SemaOpenMP.cpp revision 1.1.1.1
1//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8/// \file 9/// This file implements semantic analysis for OpenMP directives and 10/// clauses. 11/// 12//===----------------------------------------------------------------------===// 13 14#include "TreeTransform.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/ASTMutationListener.h" 17#include "clang/AST/CXXInheritance.h" 18#include "clang/AST/Decl.h" 19#include "clang/AST/DeclCXX.h" 20#include "clang/AST/DeclOpenMP.h" 21#include "clang/AST/StmtCXX.h" 22#include "clang/AST/StmtOpenMP.h" 23#include "clang/AST/StmtVisitor.h" 24#include "clang/AST/TypeOrdering.h" 25#include "clang/Basic/OpenMPKinds.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#include "llvm/ADT/PointerEmbeddedInt.h" 32using namespace clang; 33 34//===----------------------------------------------------------------------===// 35// Stack of data-sharing attributes for variables 36//===----------------------------------------------------------------------===// 37 38static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43namespace { 44/// Default data sharing attributes, which can be applied to directive. 45enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49}; 50 51/// Attributes of the defaultmap clause. 52enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55}; 56 57/// Stack for tracking declarations used in OpenMP directives and 58/// clauses and their data-sharing attributes. 59class DSAStackTy { 60public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 bool HasMutipleLoops = false; 143 const Decl *PossiblyLoopCounter = nullptr; 144 bool NowaitRegion = false; 145 bool CancelRegion = false; 146 bool LoopStart = false; 147 bool BodyComplete = false; 148 SourceLocation InnerTeamsRegionLoc; 149 /// Reference to the taskgroup task_reduction reference expression. 150 Expr *TaskgroupReductionRef = nullptr; 151 llvm::DenseSet<QualType> MappedClassesQualTypes; 152 /// List of globals marked as declare target link in this target region 153 /// (isOpenMPTargetExecutionDirective(Directive) == true). 154 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 155 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 156 Scope *CurScope, SourceLocation Loc) 157 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 158 ConstructLoc(Loc) {} 159 SharingMapTy() = default; 160 }; 161 162 using StackTy = SmallVector<SharingMapTy, 4>; 163 164 /// Stack of used declaration and their data-sharing attributes. 165 DeclSAMapTy Threadprivates; 166 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 167 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 168 /// true, if check for DSA must be from parent directive, false, if 169 /// from current directive. 170 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 171 Sema &SemaRef; 172 bool ForceCapturing = false; 173 /// true if all the variables in the target executable directives must be 174 /// captured by reference. 175 bool ForceCaptureByReferenceInTargetExecutable = false; 176 CriticalsWithHintsTy Criticals; 177 unsigned IgnoredStackElements = 0; 178 179 /// Iterators over the stack iterate in order from innermost to outermost 180 /// directive. 181 using const_iterator = StackTy::const_reverse_iterator; 182 const_iterator begin() const { 183 return Stack.empty() ? const_iterator() 184 : Stack.back().first.rbegin() + IgnoredStackElements; 185 } 186 const_iterator end() const { 187 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 188 } 189 using iterator = StackTy::reverse_iterator; 190 iterator begin() { 191 return Stack.empty() ? iterator() 192 : Stack.back().first.rbegin() + IgnoredStackElements; 193 } 194 iterator end() { 195 return Stack.empty() ? iterator() : Stack.back().first.rend(); 196 } 197 198 // Convenience operations to get at the elements of the stack. 199 200 bool isStackEmpty() const { 201 return Stack.empty() || 202 Stack.back().second != CurrentNonCapturingFunctionScope || 203 Stack.back().first.size() <= IgnoredStackElements; 204 } 205 size_t getStackSize() const { 206 return isStackEmpty() ? 0 207 : Stack.back().first.size() - IgnoredStackElements; 208 } 209 210 SharingMapTy *getTopOfStackOrNull() { 211 size_t Size = getStackSize(); 212 if (Size == 0) 213 return nullptr; 214 return &Stack.back().first[Size - 1]; 215 } 216 const SharingMapTy *getTopOfStackOrNull() const { 217 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 218 } 219 SharingMapTy &getTopOfStack() { 220 assert(!isStackEmpty() && "no current directive"); 221 return *getTopOfStackOrNull(); 222 } 223 const SharingMapTy &getTopOfStack() const { 224 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 225 } 226 227 SharingMapTy *getSecondOnStackOrNull() { 228 size_t Size = getStackSize(); 229 if (Size <= 1) 230 return nullptr; 231 return &Stack.back().first[Size - 2]; 232 } 233 const SharingMapTy *getSecondOnStackOrNull() const { 234 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 235 } 236 237 /// Get the stack element at a certain level (previously returned by 238 /// \c getNestingLevel). 239 /// 240 /// Note that nesting levels count from outermost to innermost, and this is 241 /// the reverse of our iteration order where new inner levels are pushed at 242 /// the front of the stack. 243 SharingMapTy &getStackElemAtLevel(unsigned Level) { 244 assert(Level < getStackSize() && "no such stack element"); 245 return Stack.back().first[Level]; 246 } 247 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 248 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 249 } 250 251 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 252 253 /// Checks if the variable is a local for OpenMP region. 254 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 255 256 /// Vector of previously declared requires directives 257 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 258 /// omp_allocator_handle_t type. 259 QualType OMPAllocatorHandleT; 260 /// Expression for the predefined allocators. 261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 262 nullptr}; 263 /// Vector of previously encountered target directives 264 SmallVector<SourceLocation, 2> TargetLocations; 265 266public: 267 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 268 269 /// Sets omp_allocator_handle_t type. 270 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 271 /// Gets omp_allocator_handle_t type. 272 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 273 /// Sets the given default allocator. 274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 275 Expr *Allocator) { 276 OMPPredefinedAllocators[AllocatorKind] = Allocator; 277 } 278 /// Returns the specified default allocator. 279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 280 return OMPPredefinedAllocators[AllocatorKind]; 281 } 282 283 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 284 OpenMPClauseKind getClauseParsingMode() const { 285 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 286 return ClauseKindMode; 287 } 288 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 289 290 bool isBodyComplete() const { 291 const SharingMapTy *Top = getTopOfStackOrNull(); 292 return Top && Top->BodyComplete; 293 } 294 void setBodyComplete() { 295 getTopOfStack().BodyComplete = true; 296 } 297 298 bool isForceVarCapturing() const { return ForceCapturing; } 299 void setForceVarCapturing(bool V) { ForceCapturing = V; } 300 301 void setForceCaptureByReferenceInTargetExecutable(bool V) { 302 ForceCaptureByReferenceInTargetExecutable = V; 303 } 304 bool isForceCaptureByReferenceInTargetExecutable() const { 305 return ForceCaptureByReferenceInTargetExecutable; 306 } 307 308 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 309 Scope *CurScope, SourceLocation Loc) { 310 assert(!IgnoredStackElements && 311 "cannot change stack while ignoring elements"); 312 if (Stack.empty() || 313 Stack.back().second != CurrentNonCapturingFunctionScope) 314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 316 Stack.back().first.back().DefaultAttrLoc = Loc; 317 } 318 319 void pop() { 320 assert(!IgnoredStackElements && 321 "cannot change stack while ignoring elements"); 322 assert(!Stack.back().first.empty() && 323 "Data-sharing attributes stack is empty!"); 324 Stack.back().first.pop_back(); 325 } 326 327 /// RAII object to temporarily leave the scope of a directive when we want to 328 /// logically operate in its parent. 329 class ParentDirectiveScope { 330 DSAStackTy &Self; 331 bool Active; 332 public: 333 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 334 : Self(Self), Active(false) { 335 if (Activate) 336 enable(); 337 } 338 ~ParentDirectiveScope() { disable(); } 339 void disable() { 340 if (Active) { 341 --Self.IgnoredStackElements; 342 Active = false; 343 } 344 } 345 void enable() { 346 if (!Active) { 347 ++Self.IgnoredStackElements; 348 Active = true; 349 } 350 } 351 }; 352 353 /// Marks that we're started loop parsing. 354 void loopInit() { 355 assert(isOpenMPLoopDirective(getCurrentDirective()) && 356 "Expected loop-based directive."); 357 getTopOfStack().LoopStart = true; 358 } 359 /// Start capturing of the variables in the loop context. 360 void loopStart() { 361 assert(isOpenMPLoopDirective(getCurrentDirective()) && 362 "Expected loop-based directive."); 363 getTopOfStack().LoopStart = false; 364 } 365 /// true, if variables are captured, false otherwise. 366 bool isLoopStarted() const { 367 assert(isOpenMPLoopDirective(getCurrentDirective()) && 368 "Expected loop-based directive."); 369 return !getTopOfStack().LoopStart; 370 } 371 /// Marks (or clears) declaration as possibly loop counter. 372 void resetPossibleLoopCounter(const Decl *D = nullptr) { 373 getTopOfStack().PossiblyLoopCounter = 374 D ? D->getCanonicalDecl() : D; 375 } 376 /// Gets the possible loop counter decl. 377 const Decl *getPossiblyLoopCunter() const { 378 return getTopOfStack().PossiblyLoopCounter; 379 } 380 /// Start new OpenMP region stack in new non-capturing function. 381 void pushFunction() { 382 assert(!IgnoredStackElements && 383 "cannot change stack while ignoring elements"); 384 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 385 assert(!isa<CapturingScopeInfo>(CurFnScope)); 386 CurrentNonCapturingFunctionScope = CurFnScope; 387 } 388 /// Pop region stack for non-capturing function. 389 void popFunction(const FunctionScopeInfo *OldFSI) { 390 assert(!IgnoredStackElements && 391 "cannot change stack while ignoring elements"); 392 if (!Stack.empty() && Stack.back().second == OldFSI) { 393 assert(Stack.back().first.empty()); 394 Stack.pop_back(); 395 } 396 CurrentNonCapturingFunctionScope = nullptr; 397 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 398 if (!isa<CapturingScopeInfo>(FSI)) { 399 CurrentNonCapturingFunctionScope = FSI; 400 break; 401 } 402 } 403 } 404 405 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 406 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 407 } 408 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 409 getCriticalWithHint(const DeclarationNameInfo &Name) const { 410 auto I = Criticals.find(Name.getAsString()); 411 if (I != Criticals.end()) 412 return I->second; 413 return std::make_pair(nullptr, llvm::APSInt()); 414 } 415 /// If 'aligned' declaration for given variable \a D was not seen yet, 416 /// add it and return NULL; otherwise return previous occurrence's expression 417 /// for diagnostics. 418 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 419 420 /// Register specified variable as loop control variable. 421 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 422 /// Check if the specified variable is a loop control variable for 423 /// current region. 424 /// \return The index of the loop control variable in the list of associated 425 /// for-loops (from outer to inner). 426 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 427 /// Check if the specified variable is a loop control variable for 428 /// parent region. 429 /// \return The index of the loop control variable in the list of associated 430 /// for-loops (from outer to inner). 431 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 432 /// Get the loop control variable for the I-th loop (or nullptr) in 433 /// parent directive. 434 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 435 436 /// Adds explicit data sharing attribute to the specified declaration. 437 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 438 DeclRefExpr *PrivateCopy = nullptr); 439 440 /// Adds additional information for the reduction items with the reduction id 441 /// represented as an operator. 442 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 443 BinaryOperatorKind BOK); 444 /// Adds additional information for the reduction items with the reduction id 445 /// represented as reduction identifier. 446 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 447 const Expr *ReductionRef); 448 /// Returns the location and reduction operation from the innermost parent 449 /// region for the given \p D. 450 const DSAVarData 451 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 452 BinaryOperatorKind &BOK, 453 Expr *&TaskgroupDescriptor) const; 454 /// Returns the location and reduction operation from the innermost parent 455 /// region for the given \p D. 456 const DSAVarData 457 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 458 const Expr *&ReductionRef, 459 Expr *&TaskgroupDescriptor) const; 460 /// Return reduction reference expression for the current taskgroup. 461 Expr *getTaskgroupReductionRef() const { 462 assert(getTopOfStack().Directive == OMPD_taskgroup && 463 "taskgroup reference expression requested for non taskgroup " 464 "directive."); 465 return getTopOfStack().TaskgroupReductionRef; 466 } 467 /// Checks if the given \p VD declaration is actually a taskgroup reduction 468 /// descriptor variable at the \p Level of OpenMP regions. 469 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 470 return getStackElemAtLevel(Level).TaskgroupReductionRef && 471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 472 ->getDecl() == VD; 473 } 474 475 /// Returns data sharing attributes from top of the stack for the 476 /// specified declaration. 477 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 478 /// Returns data-sharing attributes for the specified declaration. 479 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 480 /// Checks if the specified variables has data-sharing attributes which 481 /// match specified \a CPred predicate in any directive which matches \a DPred 482 /// predicate. 483 const DSAVarData 484 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 485 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 486 bool FromParent) const; 487 /// Checks if the specified variables has data-sharing attributes which 488 /// match specified \a CPred predicate in any innermost directive which 489 /// matches \a DPred predicate. 490 const DSAVarData 491 hasInnermostDSA(ValueDecl *D, 492 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 493 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 494 bool FromParent) const; 495 /// Checks if the specified variables has explicit data-sharing 496 /// attributes which match specified \a CPred predicate at the specified 497 /// OpenMP region. 498 bool hasExplicitDSA(const ValueDecl *D, 499 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 500 unsigned Level, bool NotLastprivate = false) const; 501 502 /// Returns true if the directive at level \Level matches in the 503 /// specified \a DPred predicate. 504 bool hasExplicitDirective( 505 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 506 unsigned Level) const; 507 508 /// Finds a directive which matches specified \a DPred predicate. 509 bool hasDirective( 510 const llvm::function_ref<bool( 511 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 512 DPred, 513 bool FromParent) const; 514 515 /// Returns currently analyzed directive. 516 OpenMPDirectiveKind getCurrentDirective() const { 517 const SharingMapTy *Top = getTopOfStackOrNull(); 518 return Top ? Top->Directive : OMPD_unknown; 519 } 520 /// Returns directive kind at specified level. 521 OpenMPDirectiveKind getDirective(unsigned Level) const { 522 assert(!isStackEmpty() && "No directive at specified level."); 523 return getStackElemAtLevel(Level).Directive; 524 } 525 /// Returns the capture region at the specified level. 526 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 527 unsigned OpenMPCaptureLevel) const { 528 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 529 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 530 return CaptureRegions[OpenMPCaptureLevel]; 531 } 532 /// Returns parent directive. 533 OpenMPDirectiveKind getParentDirective() const { 534 const SharingMapTy *Parent = getSecondOnStackOrNull(); 535 return Parent ? Parent->Directive : OMPD_unknown; 536 } 537 538 /// Add requires decl to internal vector 539 void addRequiresDecl(OMPRequiresDecl *RD) { 540 RequiresDecls.push_back(RD); 541 } 542 543 /// Checks if the defined 'requires' directive has specified type of clause. 544 template <typename ClauseType> 545 bool hasRequiresDeclWithClause() { 546 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 547 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 548 return isa<ClauseType>(C); 549 }); 550 }); 551 } 552 553 /// Checks for a duplicate clause amongst previously declared requires 554 /// directives 555 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 556 bool IsDuplicate = false; 557 for (OMPClause *CNew : ClauseList) { 558 for (const OMPRequiresDecl *D : RequiresDecls) { 559 for (const OMPClause *CPrev : D->clauselists()) { 560 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 561 SemaRef.Diag(CNew->getBeginLoc(), 562 diag::err_omp_requires_clause_redeclaration) 563 << getOpenMPClauseName(CNew->getClauseKind()); 564 SemaRef.Diag(CPrev->getBeginLoc(), 565 diag::note_omp_requires_previous_clause) 566 << getOpenMPClauseName(CPrev->getClauseKind()); 567 IsDuplicate = true; 568 } 569 } 570 } 571 } 572 return IsDuplicate; 573 } 574 575 /// Add location of previously encountered target to internal vector 576 void addTargetDirLocation(SourceLocation LocStart) { 577 TargetLocations.push_back(LocStart); 578 } 579 580 // Return previously encountered target region locations. 581 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 582 return TargetLocations; 583 } 584 585 /// Set default data sharing attribute to none. 586 void setDefaultDSANone(SourceLocation Loc) { 587 getTopOfStack().DefaultAttr = DSA_none; 588 getTopOfStack().DefaultAttrLoc = Loc; 589 } 590 /// Set default data sharing attribute to shared. 591 void setDefaultDSAShared(SourceLocation Loc) { 592 getTopOfStack().DefaultAttr = DSA_shared; 593 getTopOfStack().DefaultAttrLoc = Loc; 594 } 595 /// Set default data mapping attribute to 'tofrom:scalar'. 596 void setDefaultDMAToFromScalar(SourceLocation Loc) { 597 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar; 598 getTopOfStack().DefaultMapAttrLoc = Loc; 599 } 600 601 DefaultDataSharingAttributes getDefaultDSA() const { 602 return isStackEmpty() ? DSA_unspecified 603 : getTopOfStack().DefaultAttr; 604 } 605 SourceLocation getDefaultDSALocation() const { 606 return isStackEmpty() ? SourceLocation() 607 : getTopOfStack().DefaultAttrLoc; 608 } 609 DefaultMapAttributes getDefaultDMA() const { 610 return isStackEmpty() ? DMA_unspecified 611 : getTopOfStack().DefaultMapAttr; 612 } 613 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 614 return getStackElemAtLevel(Level).DefaultMapAttr; 615 } 616 SourceLocation getDefaultDMALocation() const { 617 return isStackEmpty() ? SourceLocation() 618 : getTopOfStack().DefaultMapAttrLoc; 619 } 620 621 /// Checks if the specified variable is a threadprivate. 622 bool isThreadPrivate(VarDecl *D) { 623 const DSAVarData DVar = getTopDSA(D, false); 624 return isOpenMPThreadPrivate(DVar.CKind); 625 } 626 627 /// Marks current region as ordered (it has an 'ordered' clause). 628 void setOrderedRegion(bool IsOrdered, const Expr *Param, 629 OMPOrderedClause *Clause) { 630 if (IsOrdered) 631 getTopOfStack().OrderedRegion.emplace(Param, Clause); 632 else 633 getTopOfStack().OrderedRegion.reset(); 634 } 635 /// Returns true, if region is ordered (has associated 'ordered' clause), 636 /// false - otherwise. 637 bool isOrderedRegion() const { 638 if (const SharingMapTy *Top = getTopOfStackOrNull()) 639 return Top->OrderedRegion.hasValue(); 640 return false; 641 } 642 /// Returns optional parameter for the ordered region. 643 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 644 if (const SharingMapTy *Top = getTopOfStackOrNull()) 645 if (Top->OrderedRegion.hasValue()) 646 return Top->OrderedRegion.getValue(); 647 return std::make_pair(nullptr, nullptr); 648 } 649 /// Returns true, if parent region is ordered (has associated 650 /// 'ordered' clause), false - otherwise. 651 bool isParentOrderedRegion() const { 652 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 653 return Parent->OrderedRegion.hasValue(); 654 return false; 655 } 656 /// Returns optional parameter for the ordered region. 657 std::pair<const Expr *, OMPOrderedClause *> 658 getParentOrderedRegionParam() const { 659 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 660 if (Parent->OrderedRegion.hasValue()) 661 return Parent->OrderedRegion.getValue(); 662 return std::make_pair(nullptr, nullptr); 663 } 664 /// Marks current region as nowait (it has a 'nowait' clause). 665 void setNowaitRegion(bool IsNowait = true) { 666 getTopOfStack().NowaitRegion = IsNowait; 667 } 668 /// Returns true, if parent region is nowait (has associated 669 /// 'nowait' clause), false - otherwise. 670 bool isParentNowaitRegion() const { 671 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 672 return Parent->NowaitRegion; 673 return false; 674 } 675 /// Marks parent region as cancel region. 676 void setParentCancelRegion(bool Cancel = true) { 677 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 678 Parent->CancelRegion |= Cancel; 679 } 680 /// Return true if current region has inner cancel construct. 681 bool isCancelRegion() const { 682 const SharingMapTy *Top = getTopOfStackOrNull(); 683 return Top ? Top->CancelRegion : false; 684 } 685 686 /// Set collapse value for the region. 687 void setAssociatedLoops(unsigned Val) { 688 getTopOfStack().AssociatedLoops = Val; 689 if (Val > 1) 690 getTopOfStack().HasMutipleLoops = true; 691 } 692 /// Return collapse value for region. 693 unsigned getAssociatedLoops() const { 694 const SharingMapTy *Top = getTopOfStackOrNull(); 695 return Top ? Top->AssociatedLoops : 0; 696 } 697 /// Returns true if the construct is associated with multiple loops. 698 bool hasMutipleLoops() const { 699 const SharingMapTy *Top = getTopOfStackOrNull(); 700 return Top ? Top->HasMutipleLoops : false; 701 } 702 703 /// Marks current target region as one with closely nested teams 704 /// region. 705 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 706 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 707 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 708 } 709 /// Returns true, if current region has closely nested teams region. 710 bool hasInnerTeamsRegion() const { 711 return getInnerTeamsRegionLoc().isValid(); 712 } 713 /// Returns location of the nested teams region (if any). 714 SourceLocation getInnerTeamsRegionLoc() const { 715 const SharingMapTy *Top = getTopOfStackOrNull(); 716 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 717 } 718 719 Scope *getCurScope() const { 720 const SharingMapTy *Top = getTopOfStackOrNull(); 721 return Top ? Top->CurScope : nullptr; 722 } 723 SourceLocation getConstructLoc() const { 724 const SharingMapTy *Top = getTopOfStackOrNull(); 725 return Top ? Top->ConstructLoc : SourceLocation(); 726 } 727 728 /// Do the check specified in \a Check to all component lists and return true 729 /// if any issue is found. 730 bool checkMappableExprComponentListsForDecl( 731 const ValueDecl *VD, bool CurrentRegionOnly, 732 const llvm::function_ref< 733 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 734 OpenMPClauseKind)> 735 Check) const { 736 if (isStackEmpty()) 737 return false; 738 auto SI = begin(); 739 auto SE = end(); 740 741 if (SI == SE) 742 return false; 743 744 if (CurrentRegionOnly) 745 SE = std::next(SI); 746 else 747 std::advance(SI, 1); 748 749 for (; SI != SE; ++SI) { 750 auto MI = SI->MappedExprComponents.find(VD); 751 if (MI != SI->MappedExprComponents.end()) 752 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 753 MI->second.Components) 754 if (Check(L, MI->second.Kind)) 755 return true; 756 } 757 return false; 758 } 759 760 /// Do the check specified in \a Check to all component lists at a given level 761 /// and return true if any issue is found. 762 bool checkMappableExprComponentListsForDeclAtLevel( 763 const ValueDecl *VD, unsigned Level, 764 const llvm::function_ref< 765 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 766 OpenMPClauseKind)> 767 Check) const { 768 if (getStackSize() <= Level) 769 return false; 770 771 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 772 auto MI = StackElem.MappedExprComponents.find(VD); 773 if (MI != StackElem.MappedExprComponents.end()) 774 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 775 MI->second.Components) 776 if (Check(L, MI->second.Kind)) 777 return true; 778 return false; 779 } 780 781 /// Create a new mappable expression component list associated with a given 782 /// declaration and initialize it with the provided list of components. 783 void addMappableExpressionComponents( 784 const ValueDecl *VD, 785 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 786 OpenMPClauseKind WhereFoundClauseKind) { 787 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 788 // Create new entry and append the new components there. 789 MEC.Components.resize(MEC.Components.size() + 1); 790 MEC.Components.back().append(Components.begin(), Components.end()); 791 MEC.Kind = WhereFoundClauseKind; 792 } 793 794 unsigned getNestingLevel() const { 795 assert(!isStackEmpty()); 796 return getStackSize() - 1; 797 } 798 void addDoacrossDependClause(OMPDependClause *C, 799 const OperatorOffsetTy &OpsOffs) { 800 SharingMapTy *Parent = getSecondOnStackOrNull(); 801 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 802 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 803 } 804 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 805 getDoacrossDependClauses() const { 806 const SharingMapTy &StackElem = getTopOfStack(); 807 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 808 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 809 return llvm::make_range(Ref.begin(), Ref.end()); 810 } 811 return llvm::make_range(StackElem.DoacrossDepends.end(), 812 StackElem.DoacrossDepends.end()); 813 } 814 815 // Store types of classes which have been explicitly mapped 816 void addMappedClassesQualTypes(QualType QT) { 817 SharingMapTy &StackElem = getTopOfStack(); 818 StackElem.MappedClassesQualTypes.insert(QT); 819 } 820 821 // Return set of mapped classes types 822 bool isClassPreviouslyMapped(QualType QT) const { 823 const SharingMapTy &StackElem = getTopOfStack(); 824 return StackElem.MappedClassesQualTypes.count(QT) != 0; 825 } 826 827 /// Adds global declare target to the parent target region. 828 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 829 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 830 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 831 "Expected declare target link global."); 832 for (auto &Elem : *this) { 833 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 834 Elem.DeclareTargetLinkVarDecls.push_back(E); 835 return; 836 } 837 } 838 } 839 840 /// Returns the list of globals with declare target link if current directive 841 /// is target. 842 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 843 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 844 "Expected target executable directive."); 845 return getTopOfStack().DeclareTargetLinkVarDecls; 846 } 847}; 848 849bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 850 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 851} 852 853bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 854 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 855 DKind == OMPD_unknown; 856} 857 858} // namespace 859 860static const Expr *getExprAsWritten(const Expr *E) { 861 if (const auto *FE = dyn_cast<FullExpr>(E)) 862 E = FE->getSubExpr(); 863 864 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 865 E = MTE->GetTemporaryExpr(); 866 867 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 868 E = Binder->getSubExpr(); 869 870 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 871 E = ICE->getSubExprAsWritten(); 872 return E->IgnoreParens(); 873} 874 875static Expr *getExprAsWritten(Expr *E) { 876 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 877} 878 879static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 880 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 881 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 882 D = ME->getMemberDecl(); 883 const auto *VD = dyn_cast<VarDecl>(D); 884 const auto *FD = dyn_cast<FieldDecl>(D); 885 if (VD != nullptr) { 886 VD = VD->getCanonicalDecl(); 887 D = VD; 888 } else { 889 assert(FD); 890 FD = FD->getCanonicalDecl(); 891 D = FD; 892 } 893 return D; 894} 895 896static ValueDecl *getCanonicalDecl(ValueDecl *D) { 897 return const_cast<ValueDecl *>( 898 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 899} 900 901DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 902 ValueDecl *D) const { 903 D = getCanonicalDecl(D); 904 auto *VD = dyn_cast<VarDecl>(D); 905 const auto *FD = dyn_cast<FieldDecl>(D); 906 DSAVarData DVar; 907 if (Iter == end()) { 908 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 909 // in a region but not in construct] 910 // File-scope or namespace-scope variables referenced in called routines 911 // in the region are shared unless they appear in a threadprivate 912 // directive. 913 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 914 DVar.CKind = OMPC_shared; 915 916 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 917 // in a region but not in construct] 918 // Variables with static storage duration that are declared in called 919 // routines in the region are shared. 920 if (VD && VD->hasGlobalStorage()) 921 DVar.CKind = OMPC_shared; 922 923 // Non-static data members are shared by default. 924 if (FD) 925 DVar.CKind = OMPC_shared; 926 927 return DVar; 928 } 929 930 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 931 // in a Construct, C/C++, predetermined, p.1] 932 // Variables with automatic storage duration that are declared in a scope 933 // inside the construct are private. 934 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 935 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 936 DVar.CKind = OMPC_private; 937 return DVar; 938 } 939 940 DVar.DKind = Iter->Directive; 941 // Explicitly specified attributes and local variables with predetermined 942 // attributes. 943 if (Iter->SharingMap.count(D)) { 944 const DSAInfo &Data = Iter->SharingMap.lookup(D); 945 DVar.RefExpr = Data.RefExpr.getPointer(); 946 DVar.PrivateCopy = Data.PrivateCopy; 947 DVar.CKind = Data.Attributes; 948 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 949 return DVar; 950 } 951 952 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 953 // in a Construct, C/C++, implicitly determined, p.1] 954 // In a parallel or task construct, the data-sharing attributes of these 955 // variables are determined by the default clause, if present. 956 switch (Iter->DefaultAttr) { 957 case DSA_shared: 958 DVar.CKind = OMPC_shared; 959 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 960 return DVar; 961 case DSA_none: 962 return DVar; 963 case DSA_unspecified: 964 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 965 // in a Construct, implicitly determined, p.2] 966 // In a parallel construct, if no default clause is present, these 967 // variables are shared. 968 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 969 if ((isOpenMPParallelDirective(DVar.DKind) && 970 !isOpenMPTaskLoopDirective(DVar.DKind)) || 971 isOpenMPTeamsDirective(DVar.DKind)) { 972 DVar.CKind = OMPC_shared; 973 return DVar; 974 } 975 976 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 977 // in a Construct, implicitly determined, p.4] 978 // In a task construct, if no default clause is present, a variable that in 979 // the enclosing context is determined to be shared by all implicit tasks 980 // bound to the current team is shared. 981 if (isOpenMPTaskingDirective(DVar.DKind)) { 982 DSAVarData DVarTemp; 983 const_iterator I = Iter, E = end(); 984 do { 985 ++I; 986 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 987 // Referenced in a Construct, implicitly determined, p.6] 988 // In a task construct, if no default clause is present, a variable 989 // whose data-sharing attribute is not determined by the rules above is 990 // firstprivate. 991 DVarTemp = getDSA(I, D); 992 if (DVarTemp.CKind != OMPC_shared) { 993 DVar.RefExpr = nullptr; 994 DVar.CKind = OMPC_firstprivate; 995 return DVar; 996 } 997 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 998 DVar.CKind = 999 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1000 return DVar; 1001 } 1002 } 1003 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1004 // in a Construct, implicitly determined, p.3] 1005 // For constructs other than task, if no default clause is present, these 1006 // variables inherit their data-sharing attributes from the enclosing 1007 // context. 1008 return getDSA(++Iter, D); 1009} 1010 1011const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1012 const Expr *NewDE) { 1013 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1014 D = getCanonicalDecl(D); 1015 SharingMapTy &StackElem = getTopOfStack(); 1016 auto It = StackElem.AlignedMap.find(D); 1017 if (It == StackElem.AlignedMap.end()) { 1018 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1019 StackElem.AlignedMap[D] = NewDE; 1020 return nullptr; 1021 } 1022 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1023 return It->second; 1024} 1025 1026void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1027 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1028 D = getCanonicalDecl(D); 1029 SharingMapTy &StackElem = getTopOfStack(); 1030 StackElem.LCVMap.try_emplace( 1031 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1032} 1033 1034const DSAStackTy::LCDeclInfo 1035DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 D = getCanonicalDecl(D); 1038 const SharingMapTy &StackElem = getTopOfStack(); 1039 auto It = StackElem.LCVMap.find(D); 1040 if (It != StackElem.LCVMap.end()) 1041 return It->second; 1042 return {0, nullptr}; 1043} 1044 1045const DSAStackTy::LCDeclInfo 1046DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1047 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1048 assert(Parent && "Data-sharing attributes stack is empty"); 1049 D = getCanonicalDecl(D); 1050 auto It = Parent->LCVMap.find(D); 1051 if (It != Parent->LCVMap.end()) 1052 return It->second; 1053 return {0, nullptr}; 1054} 1055 1056const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1057 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1058 assert(Parent && "Data-sharing attributes stack is empty"); 1059 if (Parent->LCVMap.size() < I) 1060 return nullptr; 1061 for (const auto &Pair : Parent->LCVMap) 1062 if (Pair.second.first == I) 1063 return Pair.first; 1064 return nullptr; 1065} 1066 1067void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1068 DeclRefExpr *PrivateCopy) { 1069 D = getCanonicalDecl(D); 1070 if (A == OMPC_threadprivate) { 1071 DSAInfo &Data = Threadprivates[D]; 1072 Data.Attributes = A; 1073 Data.RefExpr.setPointer(E); 1074 Data.PrivateCopy = nullptr; 1075 } else { 1076 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1077 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1078 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1079 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1080 (isLoopControlVariable(D).first && A == OMPC_private)); 1081 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1082 Data.RefExpr.setInt(/*IntVal=*/true); 1083 return; 1084 } 1085 const bool IsLastprivate = 1086 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1087 Data.Attributes = A; 1088 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1089 Data.PrivateCopy = PrivateCopy; 1090 if (PrivateCopy) { 1091 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1092 Data.Attributes = A; 1093 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1094 Data.PrivateCopy = nullptr; 1095 } 1096 } 1097} 1098 1099/// Build a variable declaration for OpenMP loop iteration variable. 1100static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1101 StringRef Name, const AttrVec *Attrs = nullptr, 1102 DeclRefExpr *OrigRef = nullptr) { 1103 DeclContext *DC = SemaRef.CurContext; 1104 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1105 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1106 auto *Decl = 1107 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1108 if (Attrs) { 1109 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1110 I != E; ++I) 1111 Decl->addAttr(*I); 1112 } 1113 Decl->setImplicit(); 1114 if (OrigRef) { 1115 Decl->addAttr( 1116 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1117 } 1118 return Decl; 1119} 1120 1121static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1122 SourceLocation Loc, 1123 bool RefersToCapture = false) { 1124 D->setReferenced(); 1125 D->markUsed(S.Context); 1126 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1127 SourceLocation(), D, RefersToCapture, Loc, Ty, 1128 VK_LValue); 1129} 1130 1131void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1132 BinaryOperatorKind BOK) { 1133 D = getCanonicalDecl(D); 1134 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1135 assert( 1136 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1137 "Additional reduction info may be specified only for reduction items."); 1138 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1139 assert(ReductionData.ReductionRange.isInvalid() && 1140 getTopOfStack().Directive == OMPD_taskgroup && 1141 "Additional reduction info may be specified only once for reduction " 1142 "items."); 1143 ReductionData.set(BOK, SR); 1144 Expr *&TaskgroupReductionRef = 1145 getTopOfStack().TaskgroupReductionRef; 1146 if (!TaskgroupReductionRef) { 1147 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1148 SemaRef.Context.VoidPtrTy, ".task_red."); 1149 TaskgroupReductionRef = 1150 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1151 } 1152} 1153 1154void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1155 const Expr *ReductionRef) { 1156 D = getCanonicalDecl(D); 1157 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1158 assert( 1159 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1160 "Additional reduction info may be specified only for reduction items."); 1161 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1162 assert(ReductionData.ReductionRange.isInvalid() && 1163 getTopOfStack().Directive == OMPD_taskgroup && 1164 "Additional reduction info may be specified only once for reduction " 1165 "items."); 1166 ReductionData.set(ReductionRef, SR); 1167 Expr *&TaskgroupReductionRef = 1168 getTopOfStack().TaskgroupReductionRef; 1169 if (!TaskgroupReductionRef) { 1170 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1171 SemaRef.Context.VoidPtrTy, ".task_red."); 1172 TaskgroupReductionRef = 1173 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1174 } 1175} 1176 1177const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1178 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1179 Expr *&TaskgroupDescriptor) const { 1180 D = getCanonicalDecl(D); 1181 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1182 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1183 const DSAInfo &Data = I->SharingMap.lookup(D); 1184 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1185 continue; 1186 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1187 if (!ReductionData.ReductionOp || 1188 ReductionData.ReductionOp.is<const Expr *>()) 1189 return DSAVarData(); 1190 SR = ReductionData.ReductionRange; 1191 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1192 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1193 "expression for the descriptor is not " 1194 "set."); 1195 TaskgroupDescriptor = I->TaskgroupReductionRef; 1196 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1197 Data.PrivateCopy, I->DefaultAttrLoc); 1198 } 1199 return DSAVarData(); 1200} 1201 1202const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1203 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1204 Expr *&TaskgroupDescriptor) const { 1205 D = getCanonicalDecl(D); 1206 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1207 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1208 const DSAInfo &Data = I->SharingMap.lookup(D); 1209 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1210 continue; 1211 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1212 if (!ReductionData.ReductionOp || 1213 !ReductionData.ReductionOp.is<const Expr *>()) 1214 return DSAVarData(); 1215 SR = ReductionData.ReductionRange; 1216 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1217 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1218 "expression for the descriptor is not " 1219 "set."); 1220 TaskgroupDescriptor = I->TaskgroupReductionRef; 1221 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1222 Data.PrivateCopy, I->DefaultAttrLoc); 1223 } 1224 return DSAVarData(); 1225} 1226 1227bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1228 D = D->getCanonicalDecl(); 1229 for (const_iterator E = end(); I != E; ++I) { 1230 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1231 isOpenMPTargetExecutionDirective(I->Directive)) { 1232 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1233 Scope *CurScope = getCurScope(); 1234 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1235 CurScope = CurScope->getParent(); 1236 return CurScope != TopScope; 1237 } 1238 } 1239 return false; 1240} 1241 1242static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1243 bool AcceptIfMutable = true, 1244 bool *IsClassType = nullptr) { 1245 ASTContext &Context = SemaRef.getASTContext(); 1246 Type = Type.getNonReferenceType().getCanonicalType(); 1247 bool IsConstant = Type.isConstant(Context); 1248 Type = Context.getBaseElementType(Type); 1249 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1250 ? Type->getAsCXXRecordDecl() 1251 : nullptr; 1252 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1253 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1254 RD = CTD->getTemplatedDecl(); 1255 if (IsClassType) 1256 *IsClassType = RD; 1257 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1258 RD->hasDefinition() && RD->hasMutableFields()); 1259} 1260 1261static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1262 QualType Type, OpenMPClauseKind CKind, 1263 SourceLocation ELoc, 1264 bool AcceptIfMutable = true, 1265 bool ListItemNotVar = false) { 1266 ASTContext &Context = SemaRef.getASTContext(); 1267 bool IsClassType; 1268 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1269 unsigned Diag = ListItemNotVar 1270 ? diag::err_omp_const_list_item 1271 : IsClassType ? diag::err_omp_const_not_mutable_variable 1272 : diag::err_omp_const_variable; 1273 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1274 if (!ListItemNotVar && D) { 1275 const VarDecl *VD = dyn_cast<VarDecl>(D); 1276 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1277 VarDecl::DeclarationOnly; 1278 SemaRef.Diag(D->getLocation(), 1279 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1280 << D; 1281 } 1282 return true; 1283 } 1284 return false; 1285} 1286 1287const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1288 bool FromParent) { 1289 D = getCanonicalDecl(D); 1290 DSAVarData DVar; 1291 1292 auto *VD = dyn_cast<VarDecl>(D); 1293 auto TI = Threadprivates.find(D); 1294 if (TI != Threadprivates.end()) { 1295 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1296 DVar.CKind = OMPC_threadprivate; 1297 return DVar; 1298 } 1299 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1300 DVar.RefExpr = buildDeclRefExpr( 1301 SemaRef, VD, D->getType().getNonReferenceType(), 1302 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1303 DVar.CKind = OMPC_threadprivate; 1304 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1305 return DVar; 1306 } 1307 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1308 // in a Construct, C/C++, predetermined, p.1] 1309 // Variables appearing in threadprivate directives are threadprivate. 1310 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1311 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1312 SemaRef.getLangOpts().OpenMPUseTLS && 1313 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1314 (VD && VD->getStorageClass() == SC_Register && 1315 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1316 DVar.RefExpr = buildDeclRefExpr( 1317 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1318 DVar.CKind = OMPC_threadprivate; 1319 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1320 return DVar; 1321 } 1322 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1323 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1324 !isLoopControlVariable(D).first) { 1325 const_iterator IterTarget = 1326 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1327 return isOpenMPTargetExecutionDirective(Data.Directive); 1328 }); 1329 if (IterTarget != end()) { 1330 const_iterator ParentIterTarget = IterTarget + 1; 1331 for (const_iterator Iter = begin(); 1332 Iter != ParentIterTarget; ++Iter) { 1333 if (isOpenMPLocal(VD, Iter)) { 1334 DVar.RefExpr = 1335 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1336 D->getLocation()); 1337 DVar.CKind = OMPC_threadprivate; 1338 return DVar; 1339 } 1340 } 1341 if (!isClauseParsingMode() || IterTarget != begin()) { 1342 auto DSAIter = IterTarget->SharingMap.find(D); 1343 if (DSAIter != IterTarget->SharingMap.end() && 1344 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1345 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1346 DVar.CKind = OMPC_threadprivate; 1347 return DVar; 1348 } 1349 const_iterator End = end(); 1350 if (!SemaRef.isOpenMPCapturedByRef( 1351 D, std::distance(ParentIterTarget, End), 1352 /*OpenMPCaptureLevel=*/0)) { 1353 DVar.RefExpr = 1354 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1355 IterTarget->ConstructLoc); 1356 DVar.CKind = OMPC_threadprivate; 1357 return DVar; 1358 } 1359 } 1360 } 1361 } 1362 1363 if (isStackEmpty()) 1364 // Not in OpenMP execution region and top scope was already checked. 1365 return DVar; 1366 1367 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1368 // in a Construct, C/C++, predetermined, p.4] 1369 // Static data members are shared. 1370 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1371 // in a Construct, C/C++, predetermined, p.7] 1372 // Variables with static storage duration that are declared in a scope 1373 // inside the construct are shared. 1374 if (VD && VD->isStaticDataMember()) { 1375 // Check for explicitly specified attributes. 1376 const_iterator I = begin(); 1377 const_iterator EndI = end(); 1378 if (FromParent && I != EndI) 1379 ++I; 1380 auto It = I->SharingMap.find(D); 1381 if (It != I->SharingMap.end()) { 1382 const DSAInfo &Data = It->getSecond(); 1383 DVar.RefExpr = Data.RefExpr.getPointer(); 1384 DVar.PrivateCopy = Data.PrivateCopy; 1385 DVar.CKind = Data.Attributes; 1386 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1387 DVar.DKind = I->Directive; 1388 return DVar; 1389 } 1390 1391 DVar.CKind = OMPC_shared; 1392 return DVar; 1393 } 1394 1395 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1396 // The predetermined shared attribute for const-qualified types having no 1397 // mutable members was removed after OpenMP 3.1. 1398 if (SemaRef.LangOpts.OpenMP <= 31) { 1399 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1400 // in a Construct, C/C++, predetermined, p.6] 1401 // Variables with const qualified type having no mutable member are 1402 // shared. 1403 if (isConstNotMutableType(SemaRef, D->getType())) { 1404 // Variables with const-qualified type having no mutable member may be 1405 // listed in a firstprivate clause, even if they are static data members. 1406 DSAVarData DVarTemp = hasInnermostDSA( 1407 D, 1408 [](OpenMPClauseKind C) { 1409 return C == OMPC_firstprivate || C == OMPC_shared; 1410 }, 1411 MatchesAlways, FromParent); 1412 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1413 return DVarTemp; 1414 1415 DVar.CKind = OMPC_shared; 1416 return DVar; 1417 } 1418 } 1419 1420 // Explicitly specified attributes and local variables with predetermined 1421 // attributes. 1422 const_iterator I = begin(); 1423 const_iterator EndI = end(); 1424 if (FromParent && I != EndI) 1425 ++I; 1426 auto It = I->SharingMap.find(D); 1427 if (It != I->SharingMap.end()) { 1428 const DSAInfo &Data = It->getSecond(); 1429 DVar.RefExpr = Data.RefExpr.getPointer(); 1430 DVar.PrivateCopy = Data.PrivateCopy; 1431 DVar.CKind = Data.Attributes; 1432 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1433 DVar.DKind = I->Directive; 1434 } 1435 1436 return DVar; 1437} 1438 1439const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1440 bool FromParent) const { 1441 if (isStackEmpty()) { 1442 const_iterator I; 1443 return getDSA(I, D); 1444 } 1445 D = getCanonicalDecl(D); 1446 const_iterator StartI = begin(); 1447 const_iterator EndI = end(); 1448 if (FromParent && StartI != EndI) 1449 ++StartI; 1450 return getDSA(StartI, D); 1451} 1452 1453const DSAStackTy::DSAVarData 1454DSAStackTy::hasDSA(ValueDecl *D, 1455 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1456 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1457 bool FromParent) const { 1458 if (isStackEmpty()) 1459 return {}; 1460 D = getCanonicalDecl(D); 1461 const_iterator I = begin(); 1462 const_iterator EndI = end(); 1463 if (FromParent && I != EndI) 1464 ++I; 1465 for (; I != EndI; ++I) { 1466 if (!DPred(I->Directive) && 1467 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1468 continue; 1469 const_iterator NewI = I; 1470 DSAVarData DVar = getDSA(NewI, D); 1471 if (I == NewI && CPred(DVar.CKind)) 1472 return DVar; 1473 } 1474 return {}; 1475} 1476 1477const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1478 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1479 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1480 bool FromParent) const { 1481 if (isStackEmpty()) 1482 return {}; 1483 D = getCanonicalDecl(D); 1484 const_iterator StartI = begin(); 1485 const_iterator EndI = end(); 1486 if (FromParent && StartI != EndI) 1487 ++StartI; 1488 if (StartI == EndI || !DPred(StartI->Directive)) 1489 return {}; 1490 const_iterator NewI = StartI; 1491 DSAVarData DVar = getDSA(NewI, D); 1492 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1493} 1494 1495bool DSAStackTy::hasExplicitDSA( 1496 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1497 unsigned Level, bool NotLastprivate) const { 1498 if (getStackSize() <= Level) 1499 return false; 1500 D = getCanonicalDecl(D); 1501 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1502 auto I = StackElem.SharingMap.find(D); 1503 if (I != StackElem.SharingMap.end() && 1504 I->getSecond().RefExpr.getPointer() && 1505 CPred(I->getSecond().Attributes) && 1506 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1507 return true; 1508 // Check predetermined rules for the loop control variables. 1509 auto LI = StackElem.LCVMap.find(D); 1510 if (LI != StackElem.LCVMap.end()) 1511 return CPred(OMPC_private); 1512 return false; 1513} 1514 1515bool DSAStackTy::hasExplicitDirective( 1516 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1517 unsigned Level) const { 1518 if (getStackSize() <= Level) 1519 return false; 1520 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1521 return DPred(StackElem.Directive); 1522} 1523 1524bool DSAStackTy::hasDirective( 1525 const llvm::function_ref<bool(OpenMPDirectiveKind, 1526 const DeclarationNameInfo &, SourceLocation)> 1527 DPred, 1528 bool FromParent) const { 1529 // We look only in the enclosing region. 1530 size_t Skip = FromParent ? 2 : 1; 1531 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1532 I != E; ++I) { 1533 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1534 return true; 1535 } 1536 return false; 1537} 1538 1539void Sema::InitDataSharingAttributesStack() { 1540 VarDataSharingAttributesStack = new DSAStackTy(*this); 1541} 1542 1543#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1544 1545void Sema::pushOpenMPFunctionRegion() { 1546 DSAStack->pushFunction(); 1547} 1548 1549void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1550 DSAStack->popFunction(OldFSI); 1551} 1552 1553static bool isOpenMPDeviceDelayedContext(Sema &S) { 1554 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1555 "Expected OpenMP device compilation."); 1556 return !S.isInOpenMPTargetExecutionDirective() && 1557 !S.isInOpenMPDeclareTargetContext(); 1558} 1559 1560namespace { 1561/// Status of the function emission on the host/device. 1562enum class FunctionEmissionStatus { 1563 Emitted, 1564 Discarded, 1565 Unknown, 1566}; 1567} // anonymous namespace 1568 1569Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1570 unsigned DiagID) { 1571 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1572 "Expected OpenMP device compilation."); 1573 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1574 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1575 switch (FES) { 1576 case FunctionEmissionStatus::Emitted: 1577 Kind = DeviceDiagBuilder::K_Immediate; 1578 break; 1579 case FunctionEmissionStatus::Unknown: 1580 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1581 : DeviceDiagBuilder::K_Immediate; 1582 break; 1583 case FunctionEmissionStatus::TemplateDiscarded: 1584 case FunctionEmissionStatus::OMPDiscarded: 1585 Kind = DeviceDiagBuilder::K_Nop; 1586 break; 1587 case FunctionEmissionStatus::CUDADiscarded: 1588 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1589 break; 1590 } 1591 1592 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1593} 1594 1595Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1596 unsigned DiagID) { 1597 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1598 "Expected OpenMP host compilation."); 1599 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1600 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1601 switch (FES) { 1602 case FunctionEmissionStatus::Emitted: 1603 Kind = DeviceDiagBuilder::K_Immediate; 1604 break; 1605 case FunctionEmissionStatus::Unknown: 1606 Kind = DeviceDiagBuilder::K_Deferred; 1607 break; 1608 case FunctionEmissionStatus::TemplateDiscarded: 1609 case FunctionEmissionStatus::OMPDiscarded: 1610 case FunctionEmissionStatus::CUDADiscarded: 1611 Kind = DeviceDiagBuilder::K_Nop; 1612 break; 1613 } 1614 1615 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1616} 1617 1618void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, 1619 bool CheckForDelayedContext) { 1620 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1621 "Expected OpenMP device compilation."); 1622 assert(Callee && "Callee may not be null."); 1623 Callee = Callee->getMostRecentDecl(); 1624 FunctionDecl *Caller = getCurFunctionDecl(); 1625 1626 // host only function are not available on the device. 1627 if (Caller) { 1628 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1629 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1630 assert(CallerS != FunctionEmissionStatus::CUDADiscarded && 1631 CalleeS != FunctionEmissionStatus::CUDADiscarded && 1632 "CUDADiscarded unexpected in OpenMP device function check"); 1633 if ((CallerS == FunctionEmissionStatus::Emitted || 1634 (!isOpenMPDeviceDelayedContext(*this) && 1635 CallerS == FunctionEmissionStatus::Unknown)) && 1636 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1637 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 1638 OMPC_device_type, OMPC_DEVICE_TYPE_host); 1639 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 1640 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1641 diag::note_omp_marked_device_type_here) 1642 << HostDevTy; 1643 return; 1644 } 1645 } 1646 // If the caller is known-emitted, mark the callee as known-emitted. 1647 // Otherwise, mark the call in our call graph so we can traverse it later. 1648 if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) || 1649 (!Caller && !CheckForDelayedContext) || 1650 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1651 markKnownEmitted(*this, Caller, Callee, Loc, 1652 [CheckForDelayedContext](Sema &S, FunctionDecl *FD) { 1653 return CheckForDelayedContext && 1654 S.getEmissionStatus(FD) == 1655 FunctionEmissionStatus::Emitted; 1656 }); 1657 else if (Caller) 1658 DeviceCallGraph[Caller].insert({Callee, Loc}); 1659} 1660 1661void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, 1662 bool CheckCaller) { 1663 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1664 "Expected OpenMP host compilation."); 1665 assert(Callee && "Callee may not be null."); 1666 Callee = Callee->getMostRecentDecl(); 1667 FunctionDecl *Caller = getCurFunctionDecl(); 1668 1669 // device only function are not available on the host. 1670 if (Caller) { 1671 FunctionEmissionStatus CallerS = getEmissionStatus(Caller); 1672 FunctionEmissionStatus CalleeS = getEmissionStatus(Callee); 1673 assert( 1674 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded && 1675 CalleeS != FunctionEmissionStatus::CUDADiscarded)) && 1676 "CUDADiscarded unexpected in OpenMP host function check"); 1677 if (CallerS == FunctionEmissionStatus::Emitted && 1678 CalleeS == FunctionEmissionStatus::OMPDiscarded) { 1679 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 1680 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 1681 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 1682 Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 1683 diag::note_omp_marked_device_type_here) 1684 << NoHostDevTy; 1685 return; 1686 } 1687 } 1688 // If the caller is known-emitted, mark the callee as known-emitted. 1689 // Otherwise, mark the call in our call graph so we can traverse it later. 1690 if (!shouldIgnoreInHostDeviceCheck(Callee)) { 1691 if ((!CheckCaller && !Caller) || 1692 (Caller && 1693 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted)) 1694 markKnownEmitted( 1695 *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) { 1696 return CheckCaller && 1697 S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted; 1698 }); 1699 else if (Caller) 1700 DeviceCallGraph[Caller].insert({Callee, Loc}); 1701 } 1702} 1703 1704void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1705 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1706 "OpenMP device compilation mode is expected."); 1707 QualType Ty = E->getType(); 1708 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1709 ((Ty->isFloat128Type() || 1710 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1711 !Context.getTargetInfo().hasFloat128Type()) || 1712 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1713 !Context.getTargetInfo().hasInt128Type())) 1714 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1715 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1716 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1717} 1718 1719bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1720 unsigned OpenMPCaptureLevel) const { 1721 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1722 1723 ASTContext &Ctx = getASTContext(); 1724 bool IsByRef = true; 1725 1726 // Find the directive that is associated with the provided scope. 1727 D = cast<ValueDecl>(D->getCanonicalDecl()); 1728 QualType Ty = D->getType(); 1729 1730 bool IsVariableUsedInMapClause = false; 1731 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1732 // This table summarizes how a given variable should be passed to the device 1733 // given its type and the clauses where it appears. This table is based on 1734 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1735 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1736 // 1737 // ========================================================================= 1738 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1739 // | |(tofrom:scalar)| | pvt | | | | 1740 // ========================================================================= 1741 // | scl | | | | - | | bycopy| 1742 // | scl | | - | x | - | - | bycopy| 1743 // | scl | | x | - | - | - | null | 1744 // | scl | x | | | - | | byref | 1745 // | scl | x | - | x | - | - | bycopy| 1746 // | scl | x | x | - | - | - | null | 1747 // | scl | | - | - | - | x | byref | 1748 // | scl | x | - | - | - | x | byref | 1749 // 1750 // | agg | n.a. | | | - | | byref | 1751 // | agg | n.a. | - | x | - | - | byref | 1752 // | agg | n.a. | x | - | - | - | null | 1753 // | agg | n.a. | - | - | - | x | byref | 1754 // | agg | n.a. | - | - | - | x[] | byref | 1755 // 1756 // | ptr | n.a. | | | - | | bycopy| 1757 // | ptr | n.a. | - | x | - | - | bycopy| 1758 // | ptr | n.a. | x | - | - | - | null | 1759 // | ptr | n.a. | - | - | - | x | byref | 1760 // | ptr | n.a. | - | - | - | x[] | bycopy| 1761 // | ptr | n.a. | - | - | x | | bycopy| 1762 // | ptr | n.a. | - | - | x | x | bycopy| 1763 // | ptr | n.a. | - | - | x | x[] | bycopy| 1764 // ========================================================================= 1765 // Legend: 1766 // scl - scalar 1767 // ptr - pointer 1768 // agg - aggregate 1769 // x - applies 1770 // - - invalid in this combination 1771 // [] - mapped with an array section 1772 // byref - should be mapped by reference 1773 // byval - should be mapped by value 1774 // null - initialize a local variable to null on the device 1775 // 1776 // Observations: 1777 // - All scalar declarations that show up in a map clause have to be passed 1778 // by reference, because they may have been mapped in the enclosing data 1779 // environment. 1780 // - If the scalar value does not fit the size of uintptr, it has to be 1781 // passed by reference, regardless the result in the table above. 1782 // - For pointers mapped by value that have either an implicit map or an 1783 // array section, the runtime library may pass the NULL value to the 1784 // device instead of the value passed to it by the compiler. 1785 1786 if (Ty->isReferenceType()) 1787 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1788 1789 // Locate map clauses and see if the variable being captured is referred to 1790 // in any of those clauses. Here we only care about variables, not fields, 1791 // because fields are part of aggregates. 1792 bool IsVariableAssociatedWithSection = false; 1793 1794 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1795 D, Level, 1796 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1797 OMPClauseMappableExprCommon::MappableExprComponentListRef 1798 MapExprComponents, 1799 OpenMPClauseKind WhereFoundClauseKind) { 1800 // Only the map clause information influences how a variable is 1801 // captured. E.g. is_device_ptr does not require changing the default 1802 // behavior. 1803 if (WhereFoundClauseKind != OMPC_map) 1804 return false; 1805 1806 auto EI = MapExprComponents.rbegin(); 1807 auto EE = MapExprComponents.rend(); 1808 1809 assert(EI != EE && "Invalid map expression!"); 1810 1811 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1812 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1813 1814 ++EI; 1815 if (EI == EE) 1816 return false; 1817 1818 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1819 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1820 isa<MemberExpr>(EI->getAssociatedExpression())) { 1821 IsVariableAssociatedWithSection = true; 1822 // There is nothing more we need to know about this variable. 1823 return true; 1824 } 1825 1826 // Keep looking for more map info. 1827 return false; 1828 }); 1829 1830 if (IsVariableUsedInMapClause) { 1831 // If variable is identified in a map clause it is always captured by 1832 // reference except if it is a pointer that is dereferenced somehow. 1833 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1834 } else { 1835 // By default, all the data that has a scalar type is mapped by copy 1836 // (except for reduction variables). 1837 IsByRef = 1838 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1839 !Ty->isAnyPointerType()) || 1840 !Ty->isScalarType() || 1841 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1842 DSAStack->hasExplicitDSA( 1843 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1844 } 1845 } 1846 1847 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1848 IsByRef = 1849 ((IsVariableUsedInMapClause && 1850 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 1851 OMPD_target) || 1852 !DSAStack->hasExplicitDSA( 1853 D, 1854 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1855 Level, /*NotLastprivate=*/true)) && 1856 // If the variable is artificial and must be captured by value - try to 1857 // capture by value. 1858 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1859 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1860 } 1861 1862 // When passing data by copy, we need to make sure it fits the uintptr size 1863 // and alignment, because the runtime library only deals with uintptr types. 1864 // If it does not fit the uintptr size, we need to pass the data by reference 1865 // instead. 1866 if (!IsByRef && 1867 (Ctx.getTypeSizeInChars(Ty) > 1868 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1869 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1870 IsByRef = true; 1871 } 1872 1873 return IsByRef; 1874} 1875 1876unsigned Sema::getOpenMPNestingLevel() const { 1877 assert(getLangOpts().OpenMP); 1878 return DSAStack->getNestingLevel(); 1879} 1880 1881bool Sema::isInOpenMPTargetExecutionDirective() const { 1882 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1883 !DSAStack->isClauseParsingMode()) || 1884 DSAStack->hasDirective( 1885 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1886 SourceLocation) -> bool { 1887 return isOpenMPTargetExecutionDirective(K); 1888 }, 1889 false); 1890} 1891 1892VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 1893 unsigned StopAt) { 1894 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1895 D = getCanonicalDecl(D); 1896 1897 auto *VD = dyn_cast<VarDecl>(D); 1898 // Do not capture constexpr variables. 1899 if (VD && VD->isConstexpr()) 1900 return nullptr; 1901 1902 // If we want to determine whether the variable should be captured from the 1903 // perspective of the current capturing scope, and we've already left all the 1904 // capturing scopes of the top directive on the stack, check from the 1905 // perspective of its parent directive (if any) instead. 1906 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 1907 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 1908 1909 // If we are attempting to capture a global variable in a directive with 1910 // 'target' we return true so that this global is also mapped to the device. 1911 // 1912 if (VD && !VD->hasLocalStorage() && 1913 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1914 if (isInOpenMPDeclareTargetContext()) { 1915 // Try to mark variable as declare target if it is used in capturing 1916 // regions. 1917 if (LangOpts.OpenMP <= 45 && 1918 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1919 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1920 return nullptr; 1921 } else if (isInOpenMPTargetExecutionDirective()) { 1922 // If the declaration is enclosed in a 'declare target' directive, 1923 // then it should not be captured. 1924 // 1925 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1926 return nullptr; 1927 return VD; 1928 } 1929 } 1930 1931 if (CheckScopeInfo) { 1932 bool OpenMPFound = false; 1933 for (unsigned I = StopAt + 1; I > 0; --I) { 1934 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 1935 if(!isa<CapturingScopeInfo>(FSI)) 1936 return nullptr; 1937 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 1938 if (RSI->CapRegionKind == CR_OpenMP) { 1939 OpenMPFound = true; 1940 break; 1941 } 1942 } 1943 if (!OpenMPFound) 1944 return nullptr; 1945 } 1946 1947 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1948 (!DSAStack->isClauseParsingMode() || 1949 DSAStack->getParentDirective() != OMPD_unknown)) { 1950 auto &&Info = DSAStack->isLoopControlVariable(D); 1951 if (Info.first || 1952 (VD && VD->hasLocalStorage() && 1953 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1954 (VD && DSAStack->isForceVarCapturing())) 1955 return VD ? VD : Info.second; 1956 DSAStackTy::DSAVarData DVarPrivate = 1957 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1958 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1959 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1960 // Threadprivate variables must not be captured. 1961 if (isOpenMPThreadPrivate(DVarPrivate.CKind)) 1962 return nullptr; 1963 // The variable is not private or it is the variable in the directive with 1964 // default(none) clause and not used in any clause. 1965 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1966 [](OpenMPDirectiveKind) { return true; }, 1967 DSAStack->isClauseParsingMode()); 1968 if (DVarPrivate.CKind != OMPC_unknown || 1969 (VD && DSAStack->getDefaultDSA() == DSA_none)) 1970 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1971 } 1972 return nullptr; 1973} 1974 1975void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1976 unsigned Level) const { 1977 SmallVector<OpenMPDirectiveKind, 4> Regions; 1978 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1979 FunctionScopesIndex -= Regions.size(); 1980} 1981 1982void Sema::startOpenMPLoop() { 1983 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1984 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1985 DSAStack->loopInit(); 1986} 1987 1988void Sema::startOpenMPCXXRangeFor() { 1989 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1990 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1991 DSAStack->resetPossibleLoopCounter(); 1992 DSAStack->loopStart(); 1993 } 1994} 1995 1996bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1997 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1998 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1999 if (DSAStack->getAssociatedLoops() > 0 && 2000 !DSAStack->isLoopStarted()) { 2001 DSAStack->resetPossibleLoopCounter(D); 2002 DSAStack->loopStart(); 2003 return true; 2004 } 2005 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2006 DSAStack->isLoopControlVariable(D).first) && 2007 !DSAStack->hasExplicitDSA( 2008 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2009 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2010 return true; 2011 } 2012 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2013 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2014 DSAStack->isForceVarCapturing() && 2015 !DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2017 return true; 2018 } 2019 return DSAStack->hasExplicitDSA( 2020 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2021 (DSAStack->isClauseParsingMode() && 2022 DSAStack->getClauseParsingMode() == OMPC_private) || 2023 // Consider taskgroup reduction descriptor variable a private to avoid 2024 // possible capture in the region. 2025 (DSAStack->hasExplicitDirective( 2026 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 2027 Level) && 2028 DSAStack->isTaskgroupReductionRef(D, Level)); 2029} 2030 2031void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2032 unsigned Level) { 2033 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2034 D = getCanonicalDecl(D); 2035 OpenMPClauseKind OMPC = OMPC_unknown; 2036 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2037 const unsigned NewLevel = I - 1; 2038 if (DSAStack->hasExplicitDSA(D, 2039 [&OMPC](const OpenMPClauseKind K) { 2040 if (isOpenMPPrivate(K)) { 2041 OMPC = K; 2042 return true; 2043 } 2044 return false; 2045 }, 2046 NewLevel)) 2047 break; 2048 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2049 D, NewLevel, 2050 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2051 OpenMPClauseKind) { return true; })) { 2052 OMPC = OMPC_map; 2053 break; 2054 } 2055 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2056 NewLevel)) { 2057 OMPC = OMPC_map; 2058 if (D->getType()->isScalarType() && 2059 DSAStack->getDefaultDMAAtLevel(NewLevel) != 2060 DefaultMapAttributes::DMA_tofrom_scalar) 2061 OMPC = OMPC_firstprivate; 2062 break; 2063 } 2064 } 2065 if (OMPC != OMPC_unknown) 2066 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 2067} 2068 2069bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 2070 unsigned Level) const { 2071 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2072 // Return true if the current level is no longer enclosed in a target region. 2073 2074 const auto *VD = dyn_cast<VarDecl>(D); 2075 return VD && !VD->hasLocalStorage() && 2076 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2077 Level); 2078} 2079 2080void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2081 2082void Sema::finalizeOpenMPDelayedAnalysis() { 2083 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2084 // Diagnose implicit declare target functions and their callees. 2085 for (const auto &CallerCallees : DeviceCallGraph) { 2086 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2087 OMPDeclareTargetDeclAttr::getDeviceType( 2088 CallerCallees.getFirst()->getMostRecentDecl()); 2089 // Ignore host functions during device analyzis. 2090 if (LangOpts.OpenMPIsDevice && DevTy && 2091 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2092 continue; 2093 // Ignore nohost functions during host analyzis. 2094 if (!LangOpts.OpenMPIsDevice && DevTy && 2095 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2096 continue; 2097 for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation> 2098 &Callee : CallerCallees.getSecond()) { 2099 const FunctionDecl *FD = Callee.first->getMostRecentDecl(); 2100 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2101 OMPDeclareTargetDeclAttr::getDeviceType(FD); 2102 if (LangOpts.OpenMPIsDevice && DevTy && 2103 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2104 // Diagnose host function called during device codegen. 2105 StringRef HostDevTy = getOpenMPSimpleClauseTypeName( 2106 OMPC_device_type, OMPC_DEVICE_TYPE_host); 2107 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2108 << HostDevTy << 0; 2109 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2110 diag::note_omp_marked_device_type_here) 2111 << HostDevTy; 2112 continue; 2113 } 2114 if (!LangOpts.OpenMPIsDevice && DevTy && 2115 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2116 // Diagnose nohost function called during host codegen. 2117 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2118 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2119 Diag(Callee.second, diag::err_omp_wrong_device_function_call) 2120 << NoHostDevTy << 1; 2121 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2122 diag::note_omp_marked_device_type_here) 2123 << NoHostDevTy; 2124 continue; 2125 } 2126 } 2127 } 2128} 2129 2130void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2131 const DeclarationNameInfo &DirName, 2132 Scope *CurScope, SourceLocation Loc) { 2133 DSAStack->push(DKind, DirName, CurScope, Loc); 2134 PushExpressionEvaluationContext( 2135 ExpressionEvaluationContext::PotentiallyEvaluated); 2136} 2137 2138void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2139 DSAStack->setClauseParsingMode(K); 2140} 2141 2142void Sema::EndOpenMPClause() { 2143 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2144} 2145 2146static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2147 ArrayRef<OMPClause *> Clauses); 2148 2149void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2150 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2151 // A variable of class type (or array thereof) that appears in a lastprivate 2152 // clause requires an accessible, unambiguous default constructor for the 2153 // class type, unless the list item is also specified in a firstprivate 2154 // clause. 2155 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2156 for (OMPClause *C : D->clauses()) { 2157 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2158 SmallVector<Expr *, 8> PrivateCopies; 2159 for (Expr *DE : Clause->varlists()) { 2160 if (DE->isValueDependent() || DE->isTypeDependent()) { 2161 PrivateCopies.push_back(nullptr); 2162 continue; 2163 } 2164 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2165 auto *VD = cast<VarDecl>(DRE->getDecl()); 2166 QualType Type = VD->getType().getNonReferenceType(); 2167 const DSAStackTy::DSAVarData DVar = 2168 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2169 if (DVar.CKind == OMPC_lastprivate) { 2170 // Generate helper private variable and initialize it with the 2171 // default value. The address of the original variable is replaced 2172 // by the address of the new private variable in CodeGen. This new 2173 // variable is not added to IdResolver, so the code in the OpenMP 2174 // region uses original variable for proper diagnostics. 2175 VarDecl *VDPrivate = buildVarDecl( 2176 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2177 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2178 ActOnUninitializedDecl(VDPrivate); 2179 if (VDPrivate->isInvalidDecl()) { 2180 PrivateCopies.push_back(nullptr); 2181 continue; 2182 } 2183 PrivateCopies.push_back(buildDeclRefExpr( 2184 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2185 } else { 2186 // The variable is also a firstprivate, so initialization sequence 2187 // for private copy is generated already. 2188 PrivateCopies.push_back(nullptr); 2189 } 2190 } 2191 Clause->setPrivateCopies(PrivateCopies); 2192 } 2193 } 2194 // Check allocate clauses. 2195 if (!CurContext->isDependentContext()) 2196 checkAllocateClauses(*this, DSAStack, D->clauses()); 2197 } 2198 2199 DSAStack->pop(); 2200 DiscardCleanupsInEvaluationContext(); 2201 PopExpressionEvaluationContext(); 2202} 2203 2204static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2205 Expr *NumIterations, Sema &SemaRef, 2206 Scope *S, DSAStackTy *Stack); 2207 2208namespace { 2209 2210class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2211private: 2212 Sema &SemaRef; 2213 2214public: 2215 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2216 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2217 NamedDecl *ND = Candidate.getCorrectionDecl(); 2218 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2219 return VD->hasGlobalStorage() && 2220 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2221 SemaRef.getCurScope()); 2222 } 2223 return false; 2224 } 2225 2226 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2227 return std::make_unique<VarDeclFilterCCC>(*this); 2228 } 2229 2230}; 2231 2232class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2233private: 2234 Sema &SemaRef; 2235 2236public: 2237 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2238 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2239 NamedDecl *ND = Candidate.getCorrectionDecl(); 2240 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2241 isa<FunctionDecl>(ND))) { 2242 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2243 SemaRef.getCurScope()); 2244 } 2245 return false; 2246 } 2247 2248 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2249 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2250 } 2251}; 2252 2253} // namespace 2254 2255ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2256 CXXScopeSpec &ScopeSpec, 2257 const DeclarationNameInfo &Id, 2258 OpenMPDirectiveKind Kind) { 2259 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2260 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2261 2262 if (Lookup.isAmbiguous()) 2263 return ExprError(); 2264 2265 VarDecl *VD; 2266 if (!Lookup.isSingleResult()) { 2267 VarDeclFilterCCC CCC(*this); 2268 if (TypoCorrection Corrected = 2269 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2270 CTK_ErrorRecovery)) { 2271 diagnoseTypo(Corrected, 2272 PDiag(Lookup.empty() 2273 ? diag::err_undeclared_var_use_suggest 2274 : diag::err_omp_expected_var_arg_suggest) 2275 << Id.getName()); 2276 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2277 } else { 2278 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2279 : diag::err_omp_expected_var_arg) 2280 << Id.getName(); 2281 return ExprError(); 2282 } 2283 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2284 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2285 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2286 return ExprError(); 2287 } 2288 Lookup.suppressDiagnostics(); 2289 2290 // OpenMP [2.9.2, Syntax, C/C++] 2291 // Variables must be file-scope, namespace-scope, or static block-scope. 2292 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2293 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2294 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2295 bool IsDecl = 2296 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2297 Diag(VD->getLocation(), 2298 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2299 << VD; 2300 return ExprError(); 2301 } 2302 2303 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2304 NamedDecl *ND = CanonicalVD; 2305 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2306 // A threadprivate directive for file-scope variables must appear outside 2307 // any definition or declaration. 2308 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2309 !getCurLexicalContext()->isTranslationUnit()) { 2310 Diag(Id.getLoc(), diag::err_omp_var_scope) 2311 << getOpenMPDirectiveName(Kind) << VD; 2312 bool IsDecl = 2313 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2314 Diag(VD->getLocation(), 2315 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2316 << VD; 2317 return ExprError(); 2318 } 2319 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2320 // A threadprivate directive for static class member variables must appear 2321 // in the class definition, in the same scope in which the member 2322 // variables are declared. 2323 if (CanonicalVD->isStaticDataMember() && 2324 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2325 Diag(Id.getLoc(), diag::err_omp_var_scope) 2326 << getOpenMPDirectiveName(Kind) << VD; 2327 bool IsDecl = 2328 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2329 Diag(VD->getLocation(), 2330 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2331 << VD; 2332 return ExprError(); 2333 } 2334 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2335 // A threadprivate directive for namespace-scope variables must appear 2336 // outside any definition or declaration other than the namespace 2337 // definition itself. 2338 if (CanonicalVD->getDeclContext()->isNamespace() && 2339 (!getCurLexicalContext()->isFileContext() || 2340 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2341 Diag(Id.getLoc(), diag::err_omp_var_scope) 2342 << getOpenMPDirectiveName(Kind) << VD; 2343 bool IsDecl = 2344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2345 Diag(VD->getLocation(), 2346 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2347 << VD; 2348 return ExprError(); 2349 } 2350 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2351 // A threadprivate directive for static block-scope variables must appear 2352 // in the scope of the variable and not in a nested scope. 2353 if (CanonicalVD->isLocalVarDecl() && CurScope && 2354 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2355 Diag(Id.getLoc(), diag::err_omp_var_scope) 2356 << getOpenMPDirectiveName(Kind) << VD; 2357 bool IsDecl = 2358 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2359 Diag(VD->getLocation(), 2360 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2361 << VD; 2362 return ExprError(); 2363 } 2364 2365 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2366 // A threadprivate directive must lexically precede all references to any 2367 // of the variables in its list. 2368 if (Kind == OMPD_threadprivate && VD->isUsed() && 2369 !DSAStack->isThreadPrivate(VD)) { 2370 Diag(Id.getLoc(), diag::err_omp_var_used) 2371 << getOpenMPDirectiveName(Kind) << VD; 2372 return ExprError(); 2373 } 2374 2375 QualType ExprType = VD->getType().getNonReferenceType(); 2376 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2377 SourceLocation(), VD, 2378 /*RefersToEnclosingVariableOrCapture=*/false, 2379 Id.getLoc(), ExprType, VK_LValue); 2380} 2381 2382Sema::DeclGroupPtrTy 2383Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2384 ArrayRef<Expr *> VarList) { 2385 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2386 CurContext->addDecl(D); 2387 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2388 } 2389 return nullptr; 2390} 2391 2392namespace { 2393class LocalVarRefChecker final 2394 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2395 Sema &SemaRef; 2396 2397public: 2398 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2399 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2400 if (VD->hasLocalStorage()) { 2401 SemaRef.Diag(E->getBeginLoc(), 2402 diag::err_omp_local_var_in_threadprivate_init) 2403 << E->getSourceRange(); 2404 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2405 << VD << VD->getSourceRange(); 2406 return true; 2407 } 2408 } 2409 return false; 2410 } 2411 bool VisitStmt(const Stmt *S) { 2412 for (const Stmt *Child : S->children()) { 2413 if (Child && Visit(Child)) 2414 return true; 2415 } 2416 return false; 2417 } 2418 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2419}; 2420} // namespace 2421 2422OMPThreadPrivateDecl * 2423Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2424 SmallVector<Expr *, 8> Vars; 2425 for (Expr *RefExpr : VarList) { 2426 auto *DE = cast<DeclRefExpr>(RefExpr); 2427 auto *VD = cast<VarDecl>(DE->getDecl()); 2428 SourceLocation ILoc = DE->getExprLoc(); 2429 2430 // Mark variable as used. 2431 VD->setReferenced(); 2432 VD->markUsed(Context); 2433 2434 QualType QType = VD->getType(); 2435 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2436 // It will be analyzed later. 2437 Vars.push_back(DE); 2438 continue; 2439 } 2440 2441 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2442 // A threadprivate variable must not have an incomplete type. 2443 if (RequireCompleteType(ILoc, VD->getType(), 2444 diag::err_omp_threadprivate_incomplete_type)) { 2445 continue; 2446 } 2447 2448 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2449 // A threadprivate variable must not have a reference type. 2450 if (VD->getType()->isReferenceType()) { 2451 Diag(ILoc, diag::err_omp_ref_type_arg) 2452 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2453 bool IsDecl = 2454 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2455 Diag(VD->getLocation(), 2456 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2457 << VD; 2458 continue; 2459 } 2460 2461 // Check if this is a TLS variable. If TLS is not being supported, produce 2462 // the corresponding diagnostic. 2463 if ((VD->getTLSKind() != VarDecl::TLS_None && 2464 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2465 getLangOpts().OpenMPUseTLS && 2466 getASTContext().getTargetInfo().isTLSSupported())) || 2467 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2468 !VD->isLocalVarDecl())) { 2469 Diag(ILoc, diag::err_omp_var_thread_local) 2470 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2471 bool IsDecl = 2472 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2473 Diag(VD->getLocation(), 2474 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2475 << VD; 2476 continue; 2477 } 2478 2479 // Check if initial value of threadprivate variable reference variable with 2480 // local storage (it is not supported by runtime). 2481 if (const Expr *Init = VD->getAnyInitializer()) { 2482 LocalVarRefChecker Checker(*this); 2483 if (Checker.Visit(Init)) 2484 continue; 2485 } 2486 2487 Vars.push_back(RefExpr); 2488 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2489 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2490 Context, SourceRange(Loc, Loc))); 2491 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2492 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2493 } 2494 OMPThreadPrivateDecl *D = nullptr; 2495 if (!Vars.empty()) { 2496 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2497 Vars); 2498 D->setAccess(AS_public); 2499 } 2500 return D; 2501} 2502 2503static OMPAllocateDeclAttr::AllocatorTypeTy 2504getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2505 if (!Allocator) 2506 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2507 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2508 Allocator->isInstantiationDependent() || 2509 Allocator->containsUnexpandedParameterPack()) 2510 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2511 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2512 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2513 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2514 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2515 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2516 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2517 llvm::FoldingSetNodeID AEId, DAEId; 2518 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2519 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2520 if (AEId == DAEId) { 2521 AllocatorKindRes = AllocatorKind; 2522 break; 2523 } 2524 } 2525 return AllocatorKindRes; 2526} 2527 2528static bool checkPreviousOMPAllocateAttribute( 2529 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2530 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2531 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2532 return false; 2533 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2534 Expr *PrevAllocator = A->getAllocator(); 2535 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2536 getAllocatorKind(S, Stack, PrevAllocator); 2537 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2538 if (AllocatorsMatch && 2539 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2540 Allocator && PrevAllocator) { 2541 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2542 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2543 llvm::FoldingSetNodeID AEId, PAEId; 2544 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2545 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2546 AllocatorsMatch = AEId == PAEId; 2547 } 2548 if (!AllocatorsMatch) { 2549 SmallString<256> AllocatorBuffer; 2550 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2551 if (Allocator) 2552 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2553 SmallString<256> PrevAllocatorBuffer; 2554 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2555 if (PrevAllocator) 2556 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2557 S.getPrintingPolicy()); 2558 2559 SourceLocation AllocatorLoc = 2560 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2561 SourceRange AllocatorRange = 2562 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2563 SourceLocation PrevAllocatorLoc = 2564 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2565 SourceRange PrevAllocatorRange = 2566 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2567 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2568 << (Allocator ? 1 : 0) << AllocatorStream.str() 2569 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2570 << AllocatorRange; 2571 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2572 << PrevAllocatorRange; 2573 return true; 2574 } 2575 return false; 2576} 2577 2578static void 2579applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2580 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2581 Expr *Allocator, SourceRange SR) { 2582 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2583 return; 2584 if (Allocator && 2585 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2586 Allocator->isInstantiationDependent() || 2587 Allocator->containsUnexpandedParameterPack())) 2588 return; 2589 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2590 Allocator, SR); 2591 VD->addAttr(A); 2592 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2593 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2594} 2595 2596Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2597 SourceLocation Loc, ArrayRef<Expr *> VarList, 2598 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2599 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2600 Expr *Allocator = nullptr; 2601 if (Clauses.empty()) { 2602 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2603 // allocate directives that appear in a target region must specify an 2604 // allocator clause unless a requires directive with the dynamic_allocators 2605 // clause is present in the same compilation unit. 2606 if (LangOpts.OpenMPIsDevice && 2607 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2608 targetDiag(Loc, diag::err_expected_allocator_clause); 2609 } else { 2610 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2611 } 2612 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2613 getAllocatorKind(*this, DSAStack, Allocator); 2614 SmallVector<Expr *, 8> Vars; 2615 for (Expr *RefExpr : VarList) { 2616 auto *DE = cast<DeclRefExpr>(RefExpr); 2617 auto *VD = cast<VarDecl>(DE->getDecl()); 2618 2619 // Check if this is a TLS variable or global register. 2620 if (VD->getTLSKind() != VarDecl::TLS_None || 2621 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2622 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2623 !VD->isLocalVarDecl())) 2624 continue; 2625 2626 // If the used several times in the allocate directive, the same allocator 2627 // must be used. 2628 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 2629 AllocatorKind, Allocator)) 2630 continue; 2631 2632 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2633 // If a list item has a static storage type, the allocator expression in the 2634 // allocator clause must be a constant expression that evaluates to one of 2635 // the predefined memory allocator values. 2636 if (Allocator && VD->hasGlobalStorage()) { 2637 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2638 Diag(Allocator->getExprLoc(), 2639 diag::err_omp_expected_predefined_allocator) 2640 << Allocator->getSourceRange(); 2641 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2642 VarDecl::DeclarationOnly; 2643 Diag(VD->getLocation(), 2644 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2645 << VD; 2646 continue; 2647 } 2648 } 2649 2650 Vars.push_back(RefExpr); 2651 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 2652 DE->getSourceRange()); 2653 } 2654 if (Vars.empty()) 2655 return nullptr; 2656 if (!Owner) 2657 Owner = getCurLexicalContext(); 2658 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2659 D->setAccess(AS_public); 2660 Owner->addDecl(D); 2661 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2662} 2663 2664Sema::DeclGroupPtrTy 2665Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2666 ArrayRef<OMPClause *> ClauseList) { 2667 OMPRequiresDecl *D = nullptr; 2668 if (!CurContext->isFileContext()) { 2669 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2670 } else { 2671 D = CheckOMPRequiresDecl(Loc, ClauseList); 2672 if (D) { 2673 CurContext->addDecl(D); 2674 DSAStack->addRequiresDecl(D); 2675 } 2676 } 2677 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2678} 2679 2680OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2681 ArrayRef<OMPClause *> ClauseList) { 2682 /// For target specific clauses, the requires directive cannot be 2683 /// specified after the handling of any of the target regions in the 2684 /// current compilation unit. 2685 ArrayRef<SourceLocation> TargetLocations = 2686 DSAStack->getEncounteredTargetLocs(); 2687 if (!TargetLocations.empty()) { 2688 for (const OMPClause *CNew : ClauseList) { 2689 // Check if any of the requires clauses affect target regions. 2690 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 2691 isa<OMPUnifiedAddressClause>(CNew) || 2692 isa<OMPReverseOffloadClause>(CNew) || 2693 isa<OMPDynamicAllocatorsClause>(CNew)) { 2694 Diag(Loc, diag::err_omp_target_before_requires) 2695 << getOpenMPClauseName(CNew->getClauseKind()); 2696 for (SourceLocation TargetLoc : TargetLocations) { 2697 Diag(TargetLoc, diag::note_omp_requires_encountered_target); 2698 } 2699 } 2700 } 2701 } 2702 2703 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2704 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2705 ClauseList); 2706 return nullptr; 2707} 2708 2709static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2710 const ValueDecl *D, 2711 const DSAStackTy::DSAVarData &DVar, 2712 bool IsLoopIterVar = false) { 2713 if (DVar.RefExpr) { 2714 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2715 << getOpenMPClauseName(DVar.CKind); 2716 return; 2717 } 2718 enum { 2719 PDSA_StaticMemberShared, 2720 PDSA_StaticLocalVarShared, 2721 PDSA_LoopIterVarPrivate, 2722 PDSA_LoopIterVarLinear, 2723 PDSA_LoopIterVarLastprivate, 2724 PDSA_ConstVarShared, 2725 PDSA_GlobalVarShared, 2726 PDSA_TaskVarFirstprivate, 2727 PDSA_LocalVarPrivate, 2728 PDSA_Implicit 2729 } Reason = PDSA_Implicit; 2730 bool ReportHint = false; 2731 auto ReportLoc = D->getLocation(); 2732 auto *VD = dyn_cast<VarDecl>(D); 2733 if (IsLoopIterVar) { 2734 if (DVar.CKind == OMPC_private) 2735 Reason = PDSA_LoopIterVarPrivate; 2736 else if (DVar.CKind == OMPC_lastprivate) 2737 Reason = PDSA_LoopIterVarLastprivate; 2738 else 2739 Reason = PDSA_LoopIterVarLinear; 2740 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2741 DVar.CKind == OMPC_firstprivate) { 2742 Reason = PDSA_TaskVarFirstprivate; 2743 ReportLoc = DVar.ImplicitDSALoc; 2744 } else if (VD && VD->isStaticLocal()) 2745 Reason = PDSA_StaticLocalVarShared; 2746 else if (VD && VD->isStaticDataMember()) 2747 Reason = PDSA_StaticMemberShared; 2748 else if (VD && VD->isFileVarDecl()) 2749 Reason = PDSA_GlobalVarShared; 2750 else if (D->getType().isConstant(SemaRef.getASTContext())) 2751 Reason = PDSA_ConstVarShared; 2752 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2753 ReportHint = true; 2754 Reason = PDSA_LocalVarPrivate; 2755 } 2756 if (Reason != PDSA_Implicit) { 2757 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2758 << Reason << ReportHint 2759 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2760 } else if (DVar.ImplicitDSALoc.isValid()) { 2761 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2762 << getOpenMPClauseName(DVar.CKind); 2763 } 2764} 2765 2766namespace { 2767class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2768 DSAStackTy *Stack; 2769 Sema &SemaRef; 2770 bool ErrorFound = false; 2771 CapturedStmt *CS = nullptr; 2772 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2773 llvm::SmallVector<Expr *, 4> ImplicitMap; 2774 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2775 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2776 2777 void VisitSubCaptures(OMPExecutableDirective *S) { 2778 // Check implicitly captured variables. 2779 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2780 return; 2781 visitSubCaptures(S->getInnermostCapturedStmt()); 2782 } 2783 2784public: 2785 void VisitDeclRefExpr(DeclRefExpr *E) { 2786 if (E->isTypeDependent() || E->isValueDependent() || 2787 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2788 return; 2789 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2790 // Check the datasharing rules for the expressions in the clauses. 2791 if (!CS) { 2792 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 2793 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 2794 Visit(CED->getInit()); 2795 return; 2796 } 2797 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 2798 // Do not analyze internal variables and do not enclose them into 2799 // implicit clauses. 2800 return; 2801 VD = VD->getCanonicalDecl(); 2802 // Skip internally declared variables. 2803 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD)) 2804 return; 2805 2806 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2807 // Check if the variable has explicit DSA set and stop analysis if it so. 2808 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2809 return; 2810 2811 // Skip internally declared static variables. 2812 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2813 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2814 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 2815 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 2816 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2817 return; 2818 2819 SourceLocation ELoc = E->getExprLoc(); 2820 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2821 // The default(none) clause requires that each variable that is referenced 2822 // in the construct, and does not have a predetermined data-sharing 2823 // attribute, must have its data-sharing attribute explicitly determined 2824 // by being listed in a data-sharing attribute clause. 2825 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2826 isImplicitOrExplicitTaskingRegion(DKind) && 2827 VarsWithInheritedDSA.count(VD) == 0) { 2828 VarsWithInheritedDSA[VD] = E; 2829 return; 2830 } 2831 2832 if (isOpenMPTargetExecutionDirective(DKind) && 2833 !Stack->isLoopControlVariable(VD).first) { 2834 if (!Stack->checkMappableExprComponentListsForDecl( 2835 VD, /*CurrentRegionOnly=*/true, 2836 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2837 StackComponents, 2838 OpenMPClauseKind) { 2839 // Variable is used if it has been marked as an array, array 2840 // section or the variable iself. 2841 return StackComponents.size() == 1 || 2842 std::all_of( 2843 std::next(StackComponents.rbegin()), 2844 StackComponents.rend(), 2845 [](const OMPClauseMappableExprCommon:: 2846 MappableComponent &MC) { 2847 return MC.getAssociatedDeclaration() == 2848 nullptr && 2849 (isa<OMPArraySectionExpr>( 2850 MC.getAssociatedExpression()) || 2851 isa<ArraySubscriptExpr>( 2852 MC.getAssociatedExpression())); 2853 }); 2854 })) { 2855 bool IsFirstprivate = false; 2856 // By default lambdas are captured as firstprivates. 2857 if (const auto *RD = 2858 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2859 IsFirstprivate = RD->isLambda(); 2860 IsFirstprivate = 2861 IsFirstprivate || 2862 (VD->getType().getNonReferenceType()->isScalarType() && 2863 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2864 if (IsFirstprivate) 2865 ImplicitFirstprivate.emplace_back(E); 2866 else 2867 ImplicitMap.emplace_back(E); 2868 return; 2869 } 2870 } 2871 2872 // OpenMP [2.9.3.6, Restrictions, p.2] 2873 // A list item that appears in a reduction clause of the innermost 2874 // enclosing worksharing or parallel construct may not be accessed in an 2875 // explicit task. 2876 DVar = Stack->hasInnermostDSA( 2877 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2878 [](OpenMPDirectiveKind K) { 2879 return isOpenMPParallelDirective(K) || 2880 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2881 }, 2882 /*FromParent=*/true); 2883 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2884 ErrorFound = true; 2885 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2886 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2887 return; 2888 } 2889 2890 // Define implicit data-sharing attributes for task. 2891 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2892 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2893 !Stack->isLoopControlVariable(VD).first) { 2894 ImplicitFirstprivate.push_back(E); 2895 return; 2896 } 2897 2898 // Store implicitly used globals with declare target link for parent 2899 // target. 2900 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2901 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2902 Stack->addToParentTargetRegionLinkGlobals(E); 2903 return; 2904 } 2905 } 2906 } 2907 void VisitMemberExpr(MemberExpr *E) { 2908 if (E->isTypeDependent() || E->isValueDependent() || 2909 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2910 return; 2911 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2912 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2913 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2914 if (!FD) 2915 return; 2916 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2917 // Check if the variable has explicit DSA set and stop analysis if it 2918 // so. 2919 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2920 return; 2921 2922 if (isOpenMPTargetExecutionDirective(DKind) && 2923 !Stack->isLoopControlVariable(FD).first && 2924 !Stack->checkMappableExprComponentListsForDecl( 2925 FD, /*CurrentRegionOnly=*/true, 2926 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2927 StackComponents, 2928 OpenMPClauseKind) { 2929 return isa<CXXThisExpr>( 2930 cast<MemberExpr>( 2931 StackComponents.back().getAssociatedExpression()) 2932 ->getBase() 2933 ->IgnoreParens()); 2934 })) { 2935 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2936 // A bit-field cannot appear in a map clause. 2937 // 2938 if (FD->isBitField()) 2939 return; 2940 2941 // Check to see if the member expression is referencing a class that 2942 // has already been explicitly mapped 2943 if (Stack->isClassPreviouslyMapped(TE->getType())) 2944 return; 2945 2946 ImplicitMap.emplace_back(E); 2947 return; 2948 } 2949 2950 SourceLocation ELoc = E->getExprLoc(); 2951 // OpenMP [2.9.3.6, Restrictions, p.2] 2952 // A list item that appears in a reduction clause of the innermost 2953 // enclosing worksharing or parallel construct may not be accessed in 2954 // an explicit task. 2955 DVar = Stack->hasInnermostDSA( 2956 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2957 [](OpenMPDirectiveKind K) { 2958 return isOpenMPParallelDirective(K) || 2959 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2960 }, 2961 /*FromParent=*/true); 2962 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2963 ErrorFound = true; 2964 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2965 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2966 return; 2967 } 2968 2969 // Define implicit data-sharing attributes for task. 2970 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2971 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2972 !Stack->isLoopControlVariable(FD).first) { 2973 // Check if there is a captured expression for the current field in the 2974 // region. Do not mark it as firstprivate unless there is no captured 2975 // expression. 2976 // TODO: try to make it firstprivate. 2977 if (DVar.CKind != OMPC_unknown) 2978 ImplicitFirstprivate.push_back(E); 2979 } 2980 return; 2981 } 2982 if (isOpenMPTargetExecutionDirective(DKind)) { 2983 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2984 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2985 /*NoDiagnose=*/true)) 2986 return; 2987 const auto *VD = cast<ValueDecl>( 2988 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2989 if (!Stack->checkMappableExprComponentListsForDecl( 2990 VD, /*CurrentRegionOnly=*/true, 2991 [&CurComponents]( 2992 OMPClauseMappableExprCommon::MappableExprComponentListRef 2993 StackComponents, 2994 OpenMPClauseKind) { 2995 auto CCI = CurComponents.rbegin(); 2996 auto CCE = CurComponents.rend(); 2997 for (const auto &SC : llvm::reverse(StackComponents)) { 2998 // Do both expressions have the same kind? 2999 if (CCI->getAssociatedExpression()->getStmtClass() != 3000 SC.getAssociatedExpression()->getStmtClass()) 3001 if (!(isa<OMPArraySectionExpr>( 3002 SC.getAssociatedExpression()) && 3003 isa<ArraySubscriptExpr>( 3004 CCI->getAssociatedExpression()))) 3005 return false; 3006 3007 const Decl *CCD = CCI->getAssociatedDeclaration(); 3008 const Decl *SCD = SC.getAssociatedDeclaration(); 3009 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3010 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3011 if (SCD != CCD) 3012 return false; 3013 std::advance(CCI, 1); 3014 if (CCI == CCE) 3015 break; 3016 } 3017 return true; 3018 })) { 3019 Visit(E->getBase()); 3020 } 3021 } else { 3022 Visit(E->getBase()); 3023 } 3024 } 3025 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3026 for (OMPClause *C : S->clauses()) { 3027 // Skip analysis of arguments of implicitly defined firstprivate clause 3028 // for task|target directives. 3029 // Skip analysis of arguments of implicitly defined map clause for target 3030 // directives. 3031 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3032 C->isImplicit())) { 3033 for (Stmt *CC : C->children()) { 3034 if (CC) 3035 Visit(CC); 3036 } 3037 } 3038 } 3039 // Check implicitly captured variables. 3040 VisitSubCaptures(S); 3041 } 3042 void VisitStmt(Stmt *S) { 3043 for (Stmt *C : S->children()) { 3044 if (C) { 3045 // Check implicitly captured variables in the task-based directives to 3046 // check if they must be firstprivatized. 3047 Visit(C); 3048 } 3049 } 3050 } 3051 3052 void visitSubCaptures(CapturedStmt *S) { 3053 for (const CapturedStmt::Capture &Cap : S->captures()) { 3054 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3055 continue; 3056 VarDecl *VD = Cap.getCapturedVar(); 3057 // Do not try to map the variable if it or its sub-component was mapped 3058 // already. 3059 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3060 Stack->checkMappableExprComponentListsForDecl( 3061 VD, /*CurrentRegionOnly=*/true, 3062 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3063 OpenMPClauseKind) { return true; })) 3064 continue; 3065 DeclRefExpr *DRE = buildDeclRefExpr( 3066 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3067 Cap.getLocation(), /*RefersToCapture=*/true); 3068 Visit(DRE); 3069 } 3070 } 3071 bool isErrorFound() const { return ErrorFound; } 3072 ArrayRef<Expr *> getImplicitFirstprivate() const { 3073 return ImplicitFirstprivate; 3074 } 3075 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 3076 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3077 return VarsWithInheritedDSA; 3078 } 3079 3080 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3081 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3082 // Process declare target link variables for the target directives. 3083 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3084 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3085 Visit(E); 3086 } 3087 } 3088}; 3089} // namespace 3090 3091void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3092 switch (DKind) { 3093 case OMPD_parallel: 3094 case OMPD_parallel_for: 3095 case OMPD_parallel_for_simd: 3096 case OMPD_parallel_sections: 3097 case OMPD_teams: 3098 case OMPD_teams_distribute: 3099 case OMPD_teams_distribute_simd: { 3100 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3101 QualType KmpInt32PtrTy = 3102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3103 Sema::CapturedParamNameType Params[] = { 3104 std::make_pair(".global_tid.", KmpInt32PtrTy), 3105 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3106 std::make_pair(StringRef(), QualType()) // __context with shared vars 3107 }; 3108 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3109 Params); 3110 break; 3111 } 3112 case OMPD_target_teams: 3113 case OMPD_target_parallel: 3114 case OMPD_target_parallel_for: 3115 case OMPD_target_parallel_for_simd: 3116 case OMPD_target_teams_distribute: 3117 case OMPD_target_teams_distribute_simd: { 3118 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3119 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3120 QualType KmpInt32PtrTy = 3121 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3122 QualType Args[] = {VoidPtrTy}; 3123 FunctionProtoType::ExtProtoInfo EPI; 3124 EPI.Variadic = true; 3125 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3126 Sema::CapturedParamNameType Params[] = { 3127 std::make_pair(".global_tid.", KmpInt32Ty), 3128 std::make_pair(".part_id.", KmpInt32PtrTy), 3129 std::make_pair(".privates.", VoidPtrTy), 3130 std::make_pair( 3131 ".copy_fn.", 3132 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3133 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3134 std::make_pair(StringRef(), QualType()) // __context with shared vars 3135 }; 3136 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3137 Params, /*OpenMPCaptureLevel=*/0); 3138 // Mark this captured region as inlined, because we don't use outlined 3139 // function directly. 3140 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3141 AlwaysInlineAttr::CreateImplicit( 3142 Context, {}, AttributeCommonInfo::AS_Keyword, 3143 AlwaysInlineAttr::Keyword_forceinline)); 3144 Sema::CapturedParamNameType ParamsTarget[] = { 3145 std::make_pair(StringRef(), QualType()) // __context with shared vars 3146 }; 3147 // Start a captured region for 'target' with no implicit parameters. 3148 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3149 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3150 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3151 std::make_pair(".global_tid.", KmpInt32PtrTy), 3152 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3153 std::make_pair(StringRef(), QualType()) // __context with shared vars 3154 }; 3155 // Start a captured region for 'teams' or 'parallel'. Both regions have 3156 // the same implicit parameters. 3157 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3158 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3159 break; 3160 } 3161 case OMPD_target: 3162 case OMPD_target_simd: { 3163 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3164 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3165 QualType KmpInt32PtrTy = 3166 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3167 QualType Args[] = {VoidPtrTy}; 3168 FunctionProtoType::ExtProtoInfo EPI; 3169 EPI.Variadic = true; 3170 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3171 Sema::CapturedParamNameType Params[] = { 3172 std::make_pair(".global_tid.", KmpInt32Ty), 3173 std::make_pair(".part_id.", KmpInt32PtrTy), 3174 std::make_pair(".privates.", VoidPtrTy), 3175 std::make_pair( 3176 ".copy_fn.", 3177 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3178 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3179 std::make_pair(StringRef(), QualType()) // __context with shared vars 3180 }; 3181 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3182 Params, /*OpenMPCaptureLevel=*/0); 3183 // Mark this captured region as inlined, because we don't use outlined 3184 // function directly. 3185 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3186 AlwaysInlineAttr::CreateImplicit( 3187 Context, {}, AttributeCommonInfo::AS_Keyword, 3188 AlwaysInlineAttr::Keyword_forceinline)); 3189 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3190 std::make_pair(StringRef(), QualType()), 3191 /*OpenMPCaptureLevel=*/1); 3192 break; 3193 } 3194 case OMPD_simd: 3195 case OMPD_for: 3196 case OMPD_for_simd: 3197 case OMPD_sections: 3198 case OMPD_section: 3199 case OMPD_single: 3200 case OMPD_master: 3201 case OMPD_critical: 3202 case OMPD_taskgroup: 3203 case OMPD_distribute: 3204 case OMPD_distribute_simd: 3205 case OMPD_ordered: 3206 case OMPD_atomic: 3207 case OMPD_target_data: { 3208 Sema::CapturedParamNameType Params[] = { 3209 std::make_pair(StringRef(), QualType()) // __context with shared vars 3210 }; 3211 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3212 Params); 3213 break; 3214 } 3215 case OMPD_task: { 3216 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3217 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3218 QualType KmpInt32PtrTy = 3219 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3220 QualType Args[] = {VoidPtrTy}; 3221 FunctionProtoType::ExtProtoInfo EPI; 3222 EPI.Variadic = true; 3223 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3224 Sema::CapturedParamNameType Params[] = { 3225 std::make_pair(".global_tid.", KmpInt32Ty), 3226 std::make_pair(".part_id.", KmpInt32PtrTy), 3227 std::make_pair(".privates.", VoidPtrTy), 3228 std::make_pair( 3229 ".copy_fn.", 3230 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3231 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3232 std::make_pair(StringRef(), QualType()) // __context with shared vars 3233 }; 3234 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3235 Params); 3236 // Mark this captured region as inlined, because we don't use outlined 3237 // function directly. 3238 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3239 AlwaysInlineAttr::CreateImplicit( 3240 Context, {}, AttributeCommonInfo::AS_Keyword, 3241 AlwaysInlineAttr::Keyword_forceinline)); 3242 break; 3243 } 3244 case OMPD_taskloop: 3245 case OMPD_taskloop_simd: 3246 case OMPD_master_taskloop: 3247 case OMPD_master_taskloop_simd: { 3248 QualType KmpInt32Ty = 3249 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3250 .withConst(); 3251 QualType KmpUInt64Ty = 3252 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3253 .withConst(); 3254 QualType KmpInt64Ty = 3255 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3256 .withConst(); 3257 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3258 QualType KmpInt32PtrTy = 3259 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3260 QualType Args[] = {VoidPtrTy}; 3261 FunctionProtoType::ExtProtoInfo EPI; 3262 EPI.Variadic = true; 3263 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3264 Sema::CapturedParamNameType Params[] = { 3265 std::make_pair(".global_tid.", KmpInt32Ty), 3266 std::make_pair(".part_id.", KmpInt32PtrTy), 3267 std::make_pair(".privates.", VoidPtrTy), 3268 std::make_pair( 3269 ".copy_fn.", 3270 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3271 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3272 std::make_pair(".lb.", KmpUInt64Ty), 3273 std::make_pair(".ub.", KmpUInt64Ty), 3274 std::make_pair(".st.", KmpInt64Ty), 3275 std::make_pair(".liter.", KmpInt32Ty), 3276 std::make_pair(".reductions.", VoidPtrTy), 3277 std::make_pair(StringRef(), QualType()) // __context with shared vars 3278 }; 3279 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3280 Params); 3281 // Mark this captured region as inlined, because we don't use outlined 3282 // function directly. 3283 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3284 AlwaysInlineAttr::CreateImplicit( 3285 Context, {}, AttributeCommonInfo::AS_Keyword, 3286 AlwaysInlineAttr::Keyword_forceinline)); 3287 break; 3288 } 3289 case OMPD_parallel_master_taskloop: { 3290 QualType KmpInt32Ty = 3291 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3292 .withConst(); 3293 QualType KmpUInt64Ty = 3294 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3295 .withConst(); 3296 QualType KmpInt64Ty = 3297 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3298 .withConst(); 3299 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3300 QualType KmpInt32PtrTy = 3301 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3302 Sema::CapturedParamNameType ParamsParallel[] = { 3303 std::make_pair(".global_tid.", KmpInt32PtrTy), 3304 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3305 std::make_pair(StringRef(), QualType()) // __context with shared vars 3306 }; 3307 // Start a captured region for 'parallel'. 3308 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3309 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3310 QualType Args[] = {VoidPtrTy}; 3311 FunctionProtoType::ExtProtoInfo EPI; 3312 EPI.Variadic = true; 3313 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3314 Sema::CapturedParamNameType Params[] = { 3315 std::make_pair(".global_tid.", KmpInt32Ty), 3316 std::make_pair(".part_id.", KmpInt32PtrTy), 3317 std::make_pair(".privates.", VoidPtrTy), 3318 std::make_pair( 3319 ".copy_fn.", 3320 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3321 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3322 std::make_pair(".lb.", KmpUInt64Ty), 3323 std::make_pair(".ub.", KmpUInt64Ty), 3324 std::make_pair(".st.", KmpInt64Ty), 3325 std::make_pair(".liter.", KmpInt32Ty), 3326 std::make_pair(".reductions.", VoidPtrTy), 3327 std::make_pair(StringRef(), QualType()) // __context with shared vars 3328 }; 3329 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3330 Params, /*OpenMPCaptureLevel=*/2); 3331 // Mark this captured region as inlined, because we don't use outlined 3332 // function directly. 3333 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3334 AlwaysInlineAttr::CreateImplicit( 3335 Context, {}, AttributeCommonInfo::AS_Keyword, 3336 AlwaysInlineAttr::Keyword_forceinline)); 3337 break; 3338 } 3339 case OMPD_distribute_parallel_for_simd: 3340 case OMPD_distribute_parallel_for: { 3341 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3342 QualType KmpInt32PtrTy = 3343 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3344 Sema::CapturedParamNameType Params[] = { 3345 std::make_pair(".global_tid.", KmpInt32PtrTy), 3346 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3347 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3348 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3349 std::make_pair(StringRef(), QualType()) // __context with shared vars 3350 }; 3351 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3352 Params); 3353 break; 3354 } 3355 case OMPD_target_teams_distribute_parallel_for: 3356 case OMPD_target_teams_distribute_parallel_for_simd: { 3357 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3358 QualType KmpInt32PtrTy = 3359 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3360 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3361 3362 QualType Args[] = {VoidPtrTy}; 3363 FunctionProtoType::ExtProtoInfo EPI; 3364 EPI.Variadic = true; 3365 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3366 Sema::CapturedParamNameType Params[] = { 3367 std::make_pair(".global_tid.", KmpInt32Ty), 3368 std::make_pair(".part_id.", KmpInt32PtrTy), 3369 std::make_pair(".privates.", VoidPtrTy), 3370 std::make_pair( 3371 ".copy_fn.", 3372 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3373 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3374 std::make_pair(StringRef(), QualType()) // __context with shared vars 3375 }; 3376 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3377 Params, /*OpenMPCaptureLevel=*/0); 3378 // Mark this captured region as inlined, because we don't use outlined 3379 // function directly. 3380 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3381 AlwaysInlineAttr::CreateImplicit( 3382 Context, {}, AttributeCommonInfo::AS_Keyword, 3383 AlwaysInlineAttr::Keyword_forceinline)); 3384 Sema::CapturedParamNameType ParamsTarget[] = { 3385 std::make_pair(StringRef(), QualType()) // __context with shared vars 3386 }; 3387 // Start a captured region for 'target' with no implicit parameters. 3388 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3389 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3390 3391 Sema::CapturedParamNameType ParamsTeams[] = { 3392 std::make_pair(".global_tid.", KmpInt32PtrTy), 3393 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3394 std::make_pair(StringRef(), QualType()) // __context with shared vars 3395 }; 3396 // Start a captured region for 'target' with no implicit parameters. 3397 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3398 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3399 3400 Sema::CapturedParamNameType ParamsParallel[] = { 3401 std::make_pair(".global_tid.", KmpInt32PtrTy), 3402 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3403 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3404 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3405 std::make_pair(StringRef(), QualType()) // __context with shared vars 3406 }; 3407 // Start a captured region for 'teams' or 'parallel'. Both regions have 3408 // the same implicit parameters. 3409 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3410 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3411 break; 3412 } 3413 3414 case OMPD_teams_distribute_parallel_for: 3415 case OMPD_teams_distribute_parallel_for_simd: { 3416 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3417 QualType KmpInt32PtrTy = 3418 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3419 3420 Sema::CapturedParamNameType ParamsTeams[] = { 3421 std::make_pair(".global_tid.", KmpInt32PtrTy), 3422 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3423 std::make_pair(StringRef(), QualType()) // __context with shared vars 3424 }; 3425 // Start a captured region for 'target' with no implicit parameters. 3426 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3427 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3428 3429 Sema::CapturedParamNameType ParamsParallel[] = { 3430 std::make_pair(".global_tid.", KmpInt32PtrTy), 3431 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3432 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3433 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3434 std::make_pair(StringRef(), QualType()) // __context with shared vars 3435 }; 3436 // Start a captured region for 'teams' or 'parallel'. Both regions have 3437 // the same implicit parameters. 3438 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3439 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3440 break; 3441 } 3442 case OMPD_target_update: 3443 case OMPD_target_enter_data: 3444 case OMPD_target_exit_data: { 3445 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3446 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3447 QualType KmpInt32PtrTy = 3448 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3449 QualType Args[] = {VoidPtrTy}; 3450 FunctionProtoType::ExtProtoInfo EPI; 3451 EPI.Variadic = true; 3452 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3453 Sema::CapturedParamNameType Params[] = { 3454 std::make_pair(".global_tid.", KmpInt32Ty), 3455 std::make_pair(".part_id.", KmpInt32PtrTy), 3456 std::make_pair(".privates.", VoidPtrTy), 3457 std::make_pair( 3458 ".copy_fn.", 3459 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3460 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3461 std::make_pair(StringRef(), QualType()) // __context with shared vars 3462 }; 3463 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3464 Params); 3465 // Mark this captured region as inlined, because we don't use outlined 3466 // function directly. 3467 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3468 AlwaysInlineAttr::CreateImplicit( 3469 Context, {}, AttributeCommonInfo::AS_Keyword, 3470 AlwaysInlineAttr::Keyword_forceinline)); 3471 break; 3472 } 3473 case OMPD_threadprivate: 3474 case OMPD_allocate: 3475 case OMPD_taskyield: 3476 case OMPD_barrier: 3477 case OMPD_taskwait: 3478 case OMPD_cancellation_point: 3479 case OMPD_cancel: 3480 case OMPD_flush: 3481 case OMPD_declare_reduction: 3482 case OMPD_declare_mapper: 3483 case OMPD_declare_simd: 3484 case OMPD_declare_target: 3485 case OMPD_end_declare_target: 3486 case OMPD_requires: 3487 case OMPD_declare_variant: 3488 llvm_unreachable("OpenMP Directive is not allowed"); 3489 case OMPD_unknown: 3490 llvm_unreachable("Unknown OpenMP directive"); 3491 } 3492} 3493 3494int Sema::getNumberOfConstructScopes(unsigned Level) const { 3495 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 3496} 3497 3498int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3499 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3500 getOpenMPCaptureRegions(CaptureRegions, DKind); 3501 return CaptureRegions.size(); 3502} 3503 3504static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3505 Expr *CaptureExpr, bool WithInit, 3506 bool AsExpression) { 3507 assert(CaptureExpr); 3508 ASTContext &C = S.getASTContext(); 3509 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3510 QualType Ty = Init->getType(); 3511 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3512 if (S.getLangOpts().CPlusPlus) { 3513 Ty = C.getLValueReferenceType(Ty); 3514 } else { 3515 Ty = C.getPointerType(Ty); 3516 ExprResult Res = 3517 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3518 if (!Res.isUsable()) 3519 return nullptr; 3520 Init = Res.get(); 3521 } 3522 WithInit = true; 3523 } 3524 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3525 CaptureExpr->getBeginLoc()); 3526 if (!WithInit) 3527 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3528 S.CurContext->addHiddenDecl(CED); 3529 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3530 return CED; 3531} 3532 3533static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3534 bool WithInit) { 3535 OMPCapturedExprDecl *CD; 3536 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3537 CD = cast<OMPCapturedExprDecl>(VD); 3538 else 3539 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3540 /*AsExpression=*/false); 3541 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3542 CaptureExpr->getExprLoc()); 3543} 3544 3545static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3546 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3547 if (!Ref) { 3548 OMPCapturedExprDecl *CD = buildCaptureDecl( 3549 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3550 /*WithInit=*/true, /*AsExpression=*/true); 3551 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3552 CaptureExpr->getExprLoc()); 3553 } 3554 ExprResult Res = Ref; 3555 if (!S.getLangOpts().CPlusPlus && 3556 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3557 Ref->getType()->isPointerType()) { 3558 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3559 if (!Res.isUsable()) 3560 return ExprError(); 3561 } 3562 return S.DefaultLvalueConversion(Res.get()); 3563} 3564 3565namespace { 3566// OpenMP directives parsed in this section are represented as a 3567// CapturedStatement with an associated statement. If a syntax error 3568// is detected during the parsing of the associated statement, the 3569// compiler must abort processing and close the CapturedStatement. 3570// 3571// Combined directives such as 'target parallel' have more than one 3572// nested CapturedStatements. This RAII ensures that we unwind out 3573// of all the nested CapturedStatements when an error is found. 3574class CaptureRegionUnwinderRAII { 3575private: 3576 Sema &S; 3577 bool &ErrorFound; 3578 OpenMPDirectiveKind DKind = OMPD_unknown; 3579 3580public: 3581 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3582 OpenMPDirectiveKind DKind) 3583 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3584 ~CaptureRegionUnwinderRAII() { 3585 if (ErrorFound) { 3586 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3587 while (--ThisCaptureLevel >= 0) 3588 S.ActOnCapturedRegionError(); 3589 } 3590 } 3591}; 3592} // namespace 3593 3594void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 3595 // Capture variables captured by reference in lambdas for target-based 3596 // directives. 3597 if (!CurContext->isDependentContext() && 3598 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 3599 isOpenMPTargetDataManagementDirective( 3600 DSAStack->getCurrentDirective()))) { 3601 QualType Type = V->getType(); 3602 if (const auto *RD = Type.getCanonicalType() 3603 .getNonReferenceType() 3604 ->getAsCXXRecordDecl()) { 3605 bool SavedForceCaptureByReferenceInTargetExecutable = 3606 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 3607 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3608 /*V=*/true); 3609 if (RD->isLambda()) { 3610 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 3611 FieldDecl *ThisCapture; 3612 RD->getCaptureFields(Captures, ThisCapture); 3613 for (const LambdaCapture &LC : RD->captures()) { 3614 if (LC.getCaptureKind() == LCK_ByRef) { 3615 VarDecl *VD = LC.getCapturedVar(); 3616 DeclContext *VDC = VD->getDeclContext(); 3617 if (!VDC->Encloses(CurContext)) 3618 continue; 3619 MarkVariableReferenced(LC.getLocation(), VD); 3620 } else if (LC.getCaptureKind() == LCK_This) { 3621 QualType ThisTy = getCurrentThisType(); 3622 if (!ThisTy.isNull() && 3623 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 3624 CheckCXXThisCapture(LC.getLocation()); 3625 } 3626 } 3627 } 3628 DSAStack->setForceCaptureByReferenceInTargetExecutable( 3629 SavedForceCaptureByReferenceInTargetExecutable); 3630 } 3631 } 3632} 3633 3634StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3635 ArrayRef<OMPClause *> Clauses) { 3636 bool ErrorFound = false; 3637 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3638 *this, ErrorFound, DSAStack->getCurrentDirective()); 3639 if (!S.isUsable()) { 3640 ErrorFound = true; 3641 return StmtError(); 3642 } 3643 3644 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3645 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3646 OMPOrderedClause *OC = nullptr; 3647 OMPScheduleClause *SC = nullptr; 3648 SmallVector<const OMPLinearClause *, 4> LCs; 3649 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3650 // This is required for proper codegen. 3651 for (OMPClause *Clause : Clauses) { 3652 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3653 Clause->getClauseKind() == OMPC_in_reduction) { 3654 // Capture taskgroup task_reduction descriptors inside the tasking regions 3655 // with the corresponding in_reduction items. 3656 auto *IRC = cast<OMPInReductionClause>(Clause); 3657 for (Expr *E : IRC->taskgroup_descriptors()) 3658 if (E) 3659 MarkDeclarationsReferencedInExpr(E); 3660 } 3661 if (isOpenMPPrivate(Clause->getClauseKind()) || 3662 Clause->getClauseKind() == OMPC_copyprivate || 3663 (getLangOpts().OpenMPUseTLS && 3664 getASTContext().getTargetInfo().isTLSSupported() && 3665 Clause->getClauseKind() == OMPC_copyin)) { 3666 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3667 // Mark all variables in private list clauses as used in inner region. 3668 for (Stmt *VarRef : Clause->children()) { 3669 if (auto *E = cast_or_null<Expr>(VarRef)) { 3670 MarkDeclarationsReferencedInExpr(E); 3671 } 3672 } 3673 DSAStack->setForceVarCapturing(/*V=*/false); 3674 } else if (CaptureRegions.size() > 1 || 3675 CaptureRegions.back() != OMPD_unknown) { 3676 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3677 PICs.push_back(C); 3678 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3679 if (Expr *E = C->getPostUpdateExpr()) 3680 MarkDeclarationsReferencedInExpr(E); 3681 } 3682 } 3683 if (Clause->getClauseKind() == OMPC_schedule) 3684 SC = cast<OMPScheduleClause>(Clause); 3685 else if (Clause->getClauseKind() == OMPC_ordered) 3686 OC = cast<OMPOrderedClause>(Clause); 3687 else if (Clause->getClauseKind() == OMPC_linear) 3688 LCs.push_back(cast<OMPLinearClause>(Clause)); 3689 } 3690 // OpenMP, 2.7.1 Loop Construct, Restrictions 3691 // The nonmonotonic modifier cannot be specified if an ordered clause is 3692 // specified. 3693 if (SC && 3694 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3695 SC->getSecondScheduleModifier() == 3696 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3697 OC) { 3698 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3699 ? SC->getFirstScheduleModifierLoc() 3700 : SC->getSecondScheduleModifierLoc(), 3701 diag::err_omp_schedule_nonmonotonic_ordered) 3702 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3703 ErrorFound = true; 3704 } 3705 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3706 for (const OMPLinearClause *C : LCs) { 3707 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3708 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3709 } 3710 ErrorFound = true; 3711 } 3712 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3713 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3714 OC->getNumForLoops()) { 3715 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3716 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3717 ErrorFound = true; 3718 } 3719 if (ErrorFound) { 3720 return StmtError(); 3721 } 3722 StmtResult SR = S; 3723 unsigned CompletedRegions = 0; 3724 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3725 // Mark all variables in private list clauses as used in inner region. 3726 // Required for proper codegen of combined directives. 3727 // TODO: add processing for other clauses. 3728 if (ThisCaptureRegion != OMPD_unknown) { 3729 for (const clang::OMPClauseWithPreInit *C : PICs) { 3730 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3731 // Find the particular capture region for the clause if the 3732 // directive is a combined one with multiple capture regions. 3733 // If the directive is not a combined one, the capture region 3734 // associated with the clause is OMPD_unknown and is generated 3735 // only once. 3736 if (CaptureRegion == ThisCaptureRegion || 3737 CaptureRegion == OMPD_unknown) { 3738 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3739 for (Decl *D : DS->decls()) 3740 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3741 } 3742 } 3743 } 3744 } 3745 if (++CompletedRegions == CaptureRegions.size()) 3746 DSAStack->setBodyComplete(); 3747 SR = ActOnCapturedRegionEnd(SR.get()); 3748 } 3749 return SR; 3750} 3751 3752static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3753 OpenMPDirectiveKind CancelRegion, 3754 SourceLocation StartLoc) { 3755 // CancelRegion is only needed for cancel and cancellation_point. 3756 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3757 return false; 3758 3759 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3760 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3761 return false; 3762 3763 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3764 << getOpenMPDirectiveName(CancelRegion); 3765 return true; 3766} 3767 3768static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3769 OpenMPDirectiveKind CurrentRegion, 3770 const DeclarationNameInfo &CurrentName, 3771 OpenMPDirectiveKind CancelRegion, 3772 SourceLocation StartLoc) { 3773 if (Stack->getCurScope()) { 3774 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3775 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3776 bool NestingProhibited = false; 3777 bool CloseNesting = true; 3778 bool OrphanSeen = false; 3779 enum { 3780 NoRecommend, 3781 ShouldBeInParallelRegion, 3782 ShouldBeInOrderedRegion, 3783 ShouldBeInTargetRegion, 3784 ShouldBeInTeamsRegion 3785 } Recommend = NoRecommend; 3786 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3787 // OpenMP [2.16, Nesting of Regions] 3788 // OpenMP constructs may not be nested inside a simd region. 3789 // OpenMP [2.8.1,simd Construct, Restrictions] 3790 // An ordered construct with the simd clause is the only OpenMP 3791 // construct that can appear in the simd region. 3792 // Allowing a SIMD construct nested in another SIMD construct is an 3793 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3794 // message. 3795 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3796 ? diag::err_omp_prohibited_region_simd 3797 : diag::warn_omp_nesting_simd); 3798 return CurrentRegion != OMPD_simd; 3799 } 3800 if (ParentRegion == OMPD_atomic) { 3801 // OpenMP [2.16, Nesting of Regions] 3802 // OpenMP constructs may not be nested inside an atomic region. 3803 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3804 return true; 3805 } 3806 if (CurrentRegion == OMPD_section) { 3807 // OpenMP [2.7.2, sections Construct, Restrictions] 3808 // Orphaned section directives are prohibited. That is, the section 3809 // directives must appear within the sections construct and must not be 3810 // encountered elsewhere in the sections region. 3811 if (ParentRegion != OMPD_sections && 3812 ParentRegion != OMPD_parallel_sections) { 3813 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3814 << (ParentRegion != OMPD_unknown) 3815 << getOpenMPDirectiveName(ParentRegion); 3816 return true; 3817 } 3818 return false; 3819 } 3820 // Allow some constructs (except teams and cancellation constructs) to be 3821 // orphaned (they could be used in functions, called from OpenMP regions 3822 // with the required preconditions). 3823 if (ParentRegion == OMPD_unknown && 3824 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3825 CurrentRegion != OMPD_cancellation_point && 3826 CurrentRegion != OMPD_cancel) 3827 return false; 3828 if (CurrentRegion == OMPD_cancellation_point || 3829 CurrentRegion == OMPD_cancel) { 3830 // OpenMP [2.16, Nesting of Regions] 3831 // A cancellation point construct for which construct-type-clause is 3832 // taskgroup must be nested inside a task construct. A cancellation 3833 // point construct for which construct-type-clause is not taskgroup must 3834 // be closely nested inside an OpenMP construct that matches the type 3835 // specified in construct-type-clause. 3836 // A cancel construct for which construct-type-clause is taskgroup must be 3837 // nested inside a task construct. A cancel construct for which 3838 // construct-type-clause is not taskgroup must be closely nested inside an 3839 // OpenMP construct that matches the type specified in 3840 // construct-type-clause. 3841 NestingProhibited = 3842 !((CancelRegion == OMPD_parallel && 3843 (ParentRegion == OMPD_parallel || 3844 ParentRegion == OMPD_target_parallel)) || 3845 (CancelRegion == OMPD_for && 3846 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3847 ParentRegion == OMPD_target_parallel_for || 3848 ParentRegion == OMPD_distribute_parallel_for || 3849 ParentRegion == OMPD_teams_distribute_parallel_for || 3850 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3851 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3852 (CancelRegion == OMPD_sections && 3853 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3854 ParentRegion == OMPD_parallel_sections))); 3855 OrphanSeen = ParentRegion == OMPD_unknown; 3856 } else if (CurrentRegion == OMPD_master) { 3857 // OpenMP [2.16, Nesting of Regions] 3858 // A master region may not be closely nested inside a worksharing, 3859 // atomic, or explicit task region. 3860 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3861 isOpenMPTaskingDirective(ParentRegion); 3862 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3863 // OpenMP [2.16, Nesting of Regions] 3864 // A critical region may not be nested (closely or otherwise) inside a 3865 // critical region with the same name. Note that this restriction is not 3866 // sufficient to prevent deadlock. 3867 SourceLocation PreviousCriticalLoc; 3868 bool DeadLock = Stack->hasDirective( 3869 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3870 const DeclarationNameInfo &DNI, 3871 SourceLocation Loc) { 3872 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3873 PreviousCriticalLoc = Loc; 3874 return true; 3875 } 3876 return false; 3877 }, 3878 false /* skip top directive */); 3879 if (DeadLock) { 3880 SemaRef.Diag(StartLoc, 3881 diag::err_omp_prohibited_region_critical_same_name) 3882 << CurrentName.getName(); 3883 if (PreviousCriticalLoc.isValid()) 3884 SemaRef.Diag(PreviousCriticalLoc, 3885 diag::note_omp_previous_critical_region); 3886 return true; 3887 } 3888 } else if (CurrentRegion == OMPD_barrier) { 3889 // OpenMP [2.16, Nesting of Regions] 3890 // A barrier region may not be closely nested inside a worksharing, 3891 // explicit task, critical, ordered, atomic, or master region. 3892 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3893 isOpenMPTaskingDirective(ParentRegion) || 3894 ParentRegion == OMPD_master || 3895 ParentRegion == OMPD_critical || 3896 ParentRegion == OMPD_ordered; 3897 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3898 !isOpenMPParallelDirective(CurrentRegion) && 3899 !isOpenMPTeamsDirective(CurrentRegion)) { 3900 // OpenMP [2.16, Nesting of Regions] 3901 // A worksharing region may not be closely nested inside a worksharing, 3902 // explicit task, critical, ordered, atomic, or master region. 3903 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3904 isOpenMPTaskingDirective(ParentRegion) || 3905 ParentRegion == OMPD_master || 3906 ParentRegion == OMPD_critical || 3907 ParentRegion == OMPD_ordered; 3908 Recommend = ShouldBeInParallelRegion; 3909 } else if (CurrentRegion == OMPD_ordered) { 3910 // OpenMP [2.16, Nesting of Regions] 3911 // An ordered region may not be closely nested inside a critical, 3912 // atomic, or explicit task region. 3913 // An ordered region must be closely nested inside a loop region (or 3914 // parallel loop region) with an ordered clause. 3915 // OpenMP [2.8.1,simd Construct, Restrictions] 3916 // An ordered construct with the simd clause is the only OpenMP construct 3917 // that can appear in the simd region. 3918 NestingProhibited = ParentRegion == OMPD_critical || 3919 isOpenMPTaskingDirective(ParentRegion) || 3920 !(isOpenMPSimdDirective(ParentRegion) || 3921 Stack->isParentOrderedRegion()); 3922 Recommend = ShouldBeInOrderedRegion; 3923 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3924 // OpenMP [2.16, Nesting of Regions] 3925 // If specified, a teams construct must be contained within a target 3926 // construct. 3927 NestingProhibited = 3928 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 3929 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 3930 ParentRegion != OMPD_target); 3931 OrphanSeen = ParentRegion == OMPD_unknown; 3932 Recommend = ShouldBeInTargetRegion; 3933 } 3934 if (!NestingProhibited && 3935 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3936 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3937 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3938 // OpenMP [2.16, Nesting of Regions] 3939 // distribute, parallel, parallel sections, parallel workshare, and the 3940 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3941 // constructs that can be closely nested in the teams region. 3942 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3943 !isOpenMPDistributeDirective(CurrentRegion); 3944 Recommend = ShouldBeInParallelRegion; 3945 } 3946 if (!NestingProhibited && 3947 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3948 // OpenMP 4.5 [2.17 Nesting of Regions] 3949 // The region associated with the distribute construct must be strictly 3950 // nested inside a teams region 3951 NestingProhibited = 3952 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3953 Recommend = ShouldBeInTeamsRegion; 3954 } 3955 if (!NestingProhibited && 3956 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3957 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3958 // OpenMP 4.5 [2.17 Nesting of Regions] 3959 // If a target, target update, target data, target enter data, or 3960 // target exit data construct is encountered during execution of a 3961 // target region, the behavior is unspecified. 3962 NestingProhibited = Stack->hasDirective( 3963 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3964 SourceLocation) { 3965 if (isOpenMPTargetExecutionDirective(K)) { 3966 OffendingRegion = K; 3967 return true; 3968 } 3969 return false; 3970 }, 3971 false /* don't skip top directive */); 3972 CloseNesting = false; 3973 } 3974 if (NestingProhibited) { 3975 if (OrphanSeen) { 3976 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3977 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3978 } else { 3979 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3980 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3981 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3982 } 3983 return true; 3984 } 3985 } 3986 return false; 3987} 3988 3989static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3990 ArrayRef<OMPClause *> Clauses, 3991 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3992 bool ErrorFound = false; 3993 unsigned NamedModifiersNumber = 0; 3994 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3995 OMPD_unknown + 1); 3996 SmallVector<SourceLocation, 4> NameModifierLoc; 3997 for (const OMPClause *C : Clauses) { 3998 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3999 // At most one if clause without a directive-name-modifier can appear on 4000 // the directive. 4001 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4002 if (FoundNameModifiers[CurNM]) { 4003 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4004 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4005 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4006 ErrorFound = true; 4007 } else if (CurNM != OMPD_unknown) { 4008 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4009 ++NamedModifiersNumber; 4010 } 4011 FoundNameModifiers[CurNM] = IC; 4012 if (CurNM == OMPD_unknown) 4013 continue; 4014 // Check if the specified name modifier is allowed for the current 4015 // directive. 4016 // At most one if clause with the particular directive-name-modifier can 4017 // appear on the directive. 4018 bool MatchFound = false; 4019 for (auto NM : AllowedNameModifiers) { 4020 if (CurNM == NM) { 4021 MatchFound = true; 4022 break; 4023 } 4024 } 4025 if (!MatchFound) { 4026 S.Diag(IC->getNameModifierLoc(), 4027 diag::err_omp_wrong_if_directive_name_modifier) 4028 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4029 ErrorFound = true; 4030 } 4031 } 4032 } 4033 // If any if clause on the directive includes a directive-name-modifier then 4034 // all if clauses on the directive must include a directive-name-modifier. 4035 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4036 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4037 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4038 diag::err_omp_no_more_if_clause); 4039 } else { 4040 std::string Values; 4041 std::string Sep(", "); 4042 unsigned AllowedCnt = 0; 4043 unsigned TotalAllowedNum = 4044 AllowedNameModifiers.size() - NamedModifiersNumber; 4045 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4046 ++Cnt) { 4047 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4048 if (!FoundNameModifiers[NM]) { 4049 Values += "'"; 4050 Values += getOpenMPDirectiveName(NM); 4051 Values += "'"; 4052 if (AllowedCnt + 2 == TotalAllowedNum) 4053 Values += " or "; 4054 else if (AllowedCnt + 1 != TotalAllowedNum) 4055 Values += Sep; 4056 ++AllowedCnt; 4057 } 4058 } 4059 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4060 diag::err_omp_unnamed_if_clause) 4061 << (TotalAllowedNum > 1) << Values; 4062 } 4063 for (SourceLocation Loc : NameModifierLoc) { 4064 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4065 } 4066 ErrorFound = true; 4067 } 4068 return ErrorFound; 4069} 4070 4071static std::pair<ValueDecl *, bool> 4072getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 4073 SourceRange &ERange, bool AllowArraySection = false) { 4074 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4075 RefExpr->containsUnexpandedParameterPack()) 4076 return std::make_pair(nullptr, true); 4077 4078 // OpenMP [3.1, C/C++] 4079 // A list item is a variable name. 4080 // OpenMP [2.9.3.3, Restrictions, p.1] 4081 // A variable that is part of another variable (as an array or 4082 // structure element) cannot appear in a private clause. 4083 RefExpr = RefExpr->IgnoreParens(); 4084 enum { 4085 NoArrayExpr = -1, 4086 ArraySubscript = 0, 4087 OMPArraySection = 1 4088 } IsArrayExpr = NoArrayExpr; 4089 if (AllowArraySection) { 4090 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4091 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4092 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4093 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4094 RefExpr = Base; 4095 IsArrayExpr = ArraySubscript; 4096 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4097 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4098 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4099 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4100 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4101 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4102 RefExpr = Base; 4103 IsArrayExpr = OMPArraySection; 4104 } 4105 } 4106 ELoc = RefExpr->getExprLoc(); 4107 ERange = RefExpr->getSourceRange(); 4108 RefExpr = RefExpr->IgnoreParenImpCasts(); 4109 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4110 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4111 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4112 (S.getCurrentThisType().isNull() || !ME || 4113 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4114 !isa<FieldDecl>(ME->getMemberDecl()))) { 4115 if (IsArrayExpr != NoArrayExpr) { 4116 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4117 << ERange; 4118 } else { 4119 S.Diag(ELoc, 4120 AllowArraySection 4121 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4122 : diag::err_omp_expected_var_name_member_expr) 4123 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4124 } 4125 return std::make_pair(nullptr, false); 4126 } 4127 return std::make_pair( 4128 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4129} 4130 4131static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4132 ArrayRef<OMPClause *> Clauses) { 4133 assert(!S.CurContext->isDependentContext() && 4134 "Expected non-dependent context."); 4135 auto AllocateRange = 4136 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4137 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4138 DeclToCopy; 4139 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4140 return isOpenMPPrivate(C->getClauseKind()); 4141 }); 4142 for (OMPClause *Cl : PrivateRange) { 4143 MutableArrayRef<Expr *>::iterator I, It, Et; 4144 if (Cl->getClauseKind() == OMPC_private) { 4145 auto *PC = cast<OMPPrivateClause>(Cl); 4146 I = PC->private_copies().begin(); 4147 It = PC->varlist_begin(); 4148 Et = PC->varlist_end(); 4149 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4150 auto *PC = cast<OMPFirstprivateClause>(Cl); 4151 I = PC->private_copies().begin(); 4152 It = PC->varlist_begin(); 4153 Et = PC->varlist_end(); 4154 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4155 auto *PC = cast<OMPLastprivateClause>(Cl); 4156 I = PC->private_copies().begin(); 4157 It = PC->varlist_begin(); 4158 Et = PC->varlist_end(); 4159 } else if (Cl->getClauseKind() == OMPC_linear) { 4160 auto *PC = cast<OMPLinearClause>(Cl); 4161 I = PC->privates().begin(); 4162 It = PC->varlist_begin(); 4163 Et = PC->varlist_end(); 4164 } else if (Cl->getClauseKind() == OMPC_reduction) { 4165 auto *PC = cast<OMPReductionClause>(Cl); 4166 I = PC->privates().begin(); 4167 It = PC->varlist_begin(); 4168 Et = PC->varlist_end(); 4169 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4170 auto *PC = cast<OMPTaskReductionClause>(Cl); 4171 I = PC->privates().begin(); 4172 It = PC->varlist_begin(); 4173 Et = PC->varlist_end(); 4174 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4175 auto *PC = cast<OMPInReductionClause>(Cl); 4176 I = PC->privates().begin(); 4177 It = PC->varlist_begin(); 4178 Et = PC->varlist_end(); 4179 } else { 4180 llvm_unreachable("Expected private clause."); 4181 } 4182 for (Expr *E : llvm::make_range(It, Et)) { 4183 if (!*I) { 4184 ++I; 4185 continue; 4186 } 4187 SourceLocation ELoc; 4188 SourceRange ERange; 4189 Expr *SimpleRefExpr = E; 4190 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4191 /*AllowArraySection=*/true); 4192 DeclToCopy.try_emplace(Res.first, 4193 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4194 ++I; 4195 } 4196 } 4197 for (OMPClause *C : AllocateRange) { 4198 auto *AC = cast<OMPAllocateClause>(C); 4199 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4200 getAllocatorKind(S, Stack, AC->getAllocator()); 4201 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4202 // For task, taskloop or target directives, allocation requests to memory 4203 // allocators with the trait access set to thread result in unspecified 4204 // behavior. 4205 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4206 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4207 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4208 S.Diag(AC->getAllocator()->getExprLoc(), 4209 diag::warn_omp_allocate_thread_on_task_target_directive) 4210 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4211 } 4212 for (Expr *E : AC->varlists()) { 4213 SourceLocation ELoc; 4214 SourceRange ERange; 4215 Expr *SimpleRefExpr = E; 4216 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4217 ValueDecl *VD = Res.first; 4218 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4219 if (!isOpenMPPrivate(Data.CKind)) { 4220 S.Diag(E->getExprLoc(), 4221 diag::err_omp_expected_private_copy_for_allocate); 4222 continue; 4223 } 4224 VarDecl *PrivateVD = DeclToCopy[VD]; 4225 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4226 AllocatorKind, AC->getAllocator())) 4227 continue; 4228 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4229 E->getSourceRange()); 4230 } 4231 } 4232} 4233 4234StmtResult Sema::ActOnOpenMPExecutableDirective( 4235 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4236 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4237 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4238 StmtResult Res = StmtError(); 4239 // First check CancelRegion which is then used in checkNestingOfRegions. 4240 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4241 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4242 StartLoc)) 4243 return StmtError(); 4244 4245 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4246 VarsWithInheritedDSAType VarsWithInheritedDSA; 4247 bool ErrorFound = false; 4248 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4249 if (AStmt && !CurContext->isDependentContext()) { 4250 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4251 4252 // Check default data sharing attributes for referenced variables. 4253 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4254 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4255 Stmt *S = AStmt; 4256 while (--ThisCaptureLevel >= 0) 4257 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4258 DSAChecker.Visit(S); 4259 if (!isOpenMPTargetDataManagementDirective(Kind) && 4260 !isOpenMPTaskingDirective(Kind)) { 4261 // Visit subcaptures to generate implicit clauses for captured vars. 4262 auto *CS = cast<CapturedStmt>(AStmt); 4263 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4264 getOpenMPCaptureRegions(CaptureRegions, Kind); 4265 // Ignore outer tasking regions for target directives. 4266 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4267 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4268 DSAChecker.visitSubCaptures(CS); 4269 } 4270 if (DSAChecker.isErrorFound()) 4271 return StmtError(); 4272 // Generate list of implicitly defined firstprivate variables. 4273 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4274 4275 SmallVector<Expr *, 4> ImplicitFirstprivates( 4276 DSAChecker.getImplicitFirstprivate().begin(), 4277 DSAChecker.getImplicitFirstprivate().end()); 4278 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 4279 DSAChecker.getImplicitMap().end()); 4280 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4281 for (OMPClause *C : Clauses) { 4282 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4283 for (Expr *E : IRC->taskgroup_descriptors()) 4284 if (E) 4285 ImplicitFirstprivates.emplace_back(E); 4286 } 4287 } 4288 if (!ImplicitFirstprivates.empty()) { 4289 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4290 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4291 SourceLocation())) { 4292 ClausesWithImplicit.push_back(Implicit); 4293 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4294 ImplicitFirstprivates.size(); 4295 } else { 4296 ErrorFound = true; 4297 } 4298 } 4299 if (!ImplicitMaps.empty()) { 4300 CXXScopeSpec MapperIdScopeSpec; 4301 DeclarationNameInfo MapperId; 4302 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4303 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 4304 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 4305 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 4306 ClausesWithImplicit.emplace_back(Implicit); 4307 ErrorFound |= 4308 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 4309 } else { 4310 ErrorFound = true; 4311 } 4312 } 4313 } 4314 4315 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4316 switch (Kind) { 4317 case OMPD_parallel: 4318 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4319 EndLoc); 4320 AllowedNameModifiers.push_back(OMPD_parallel); 4321 break; 4322 case OMPD_simd: 4323 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4324 VarsWithInheritedDSA); 4325 break; 4326 case OMPD_for: 4327 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4328 VarsWithInheritedDSA); 4329 break; 4330 case OMPD_for_simd: 4331 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4332 EndLoc, VarsWithInheritedDSA); 4333 break; 4334 case OMPD_sections: 4335 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4336 EndLoc); 4337 break; 4338 case OMPD_section: 4339 assert(ClausesWithImplicit.empty() && 4340 "No clauses are allowed for 'omp section' directive"); 4341 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 4342 break; 4343 case OMPD_single: 4344 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 4345 EndLoc); 4346 break; 4347 case OMPD_master: 4348 assert(ClausesWithImplicit.empty() && 4349 "No clauses are allowed for 'omp master' directive"); 4350 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 4351 break; 4352 case OMPD_critical: 4353 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 4354 StartLoc, EndLoc); 4355 break; 4356 case OMPD_parallel_for: 4357 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 4358 EndLoc, VarsWithInheritedDSA); 4359 AllowedNameModifiers.push_back(OMPD_parallel); 4360 break; 4361 case OMPD_parallel_for_simd: 4362 Res = ActOnOpenMPParallelForSimdDirective( 4363 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4364 AllowedNameModifiers.push_back(OMPD_parallel); 4365 break; 4366 case OMPD_parallel_sections: 4367 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 4368 StartLoc, EndLoc); 4369 AllowedNameModifiers.push_back(OMPD_parallel); 4370 break; 4371 case OMPD_task: 4372 Res = 4373 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4374 AllowedNameModifiers.push_back(OMPD_task); 4375 break; 4376 case OMPD_taskyield: 4377 assert(ClausesWithImplicit.empty() && 4378 "No clauses are allowed for 'omp taskyield' directive"); 4379 assert(AStmt == nullptr && 4380 "No associated statement allowed for 'omp taskyield' directive"); 4381 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 4382 break; 4383 case OMPD_barrier: 4384 assert(ClausesWithImplicit.empty() && 4385 "No clauses are allowed for 'omp barrier' directive"); 4386 assert(AStmt == nullptr && 4387 "No associated statement allowed for 'omp barrier' directive"); 4388 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 4389 break; 4390 case OMPD_taskwait: 4391 assert(ClausesWithImplicit.empty() && 4392 "No clauses are allowed for 'omp taskwait' directive"); 4393 assert(AStmt == nullptr && 4394 "No associated statement allowed for 'omp taskwait' directive"); 4395 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 4396 break; 4397 case OMPD_taskgroup: 4398 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 4399 EndLoc); 4400 break; 4401 case OMPD_flush: 4402 assert(AStmt == nullptr && 4403 "No associated statement allowed for 'omp flush' directive"); 4404 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 4405 break; 4406 case OMPD_ordered: 4407 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 4408 EndLoc); 4409 break; 4410 case OMPD_atomic: 4411 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 4412 EndLoc); 4413 break; 4414 case OMPD_teams: 4415 Res = 4416 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 4417 break; 4418 case OMPD_target: 4419 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 4420 EndLoc); 4421 AllowedNameModifiers.push_back(OMPD_target); 4422 break; 4423 case OMPD_target_parallel: 4424 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 4425 StartLoc, EndLoc); 4426 AllowedNameModifiers.push_back(OMPD_target); 4427 AllowedNameModifiers.push_back(OMPD_parallel); 4428 break; 4429 case OMPD_target_parallel_for: 4430 Res = ActOnOpenMPTargetParallelForDirective( 4431 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4432 AllowedNameModifiers.push_back(OMPD_target); 4433 AllowedNameModifiers.push_back(OMPD_parallel); 4434 break; 4435 case OMPD_cancellation_point: 4436 assert(ClausesWithImplicit.empty() && 4437 "No clauses are allowed for 'omp cancellation point' directive"); 4438 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 4439 "cancellation point' directive"); 4440 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 4441 break; 4442 case OMPD_cancel: 4443 assert(AStmt == nullptr && 4444 "No associated statement allowed for 'omp cancel' directive"); 4445 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 4446 CancelRegion); 4447 AllowedNameModifiers.push_back(OMPD_cancel); 4448 break; 4449 case OMPD_target_data: 4450 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 4451 EndLoc); 4452 AllowedNameModifiers.push_back(OMPD_target_data); 4453 break; 4454 case OMPD_target_enter_data: 4455 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 4456 EndLoc, AStmt); 4457 AllowedNameModifiers.push_back(OMPD_target_enter_data); 4458 break; 4459 case OMPD_target_exit_data: 4460 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 4461 EndLoc, AStmt); 4462 AllowedNameModifiers.push_back(OMPD_target_exit_data); 4463 break; 4464 case OMPD_taskloop: 4465 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 4466 EndLoc, VarsWithInheritedDSA); 4467 AllowedNameModifiers.push_back(OMPD_taskloop); 4468 break; 4469 case OMPD_taskloop_simd: 4470 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4471 EndLoc, VarsWithInheritedDSA); 4472 AllowedNameModifiers.push_back(OMPD_taskloop); 4473 break; 4474 case OMPD_master_taskloop: 4475 Res = ActOnOpenMPMasterTaskLoopDirective( 4476 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4477 AllowedNameModifiers.push_back(OMPD_taskloop); 4478 break; 4479 case OMPD_master_taskloop_simd: 4480 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 4481 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4482 AllowedNameModifiers.push_back(OMPD_taskloop); 4483 break; 4484 case OMPD_parallel_master_taskloop: 4485 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 4486 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4487 AllowedNameModifiers.push_back(OMPD_taskloop); 4488 AllowedNameModifiers.push_back(OMPD_parallel); 4489 break; 4490 case OMPD_distribute: 4491 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 4492 EndLoc, VarsWithInheritedDSA); 4493 break; 4494 case OMPD_target_update: 4495 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 4496 EndLoc, AStmt); 4497 AllowedNameModifiers.push_back(OMPD_target_update); 4498 break; 4499 case OMPD_distribute_parallel_for: 4500 Res = ActOnOpenMPDistributeParallelForDirective( 4501 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4502 AllowedNameModifiers.push_back(OMPD_parallel); 4503 break; 4504 case OMPD_distribute_parallel_for_simd: 4505 Res = ActOnOpenMPDistributeParallelForSimdDirective( 4506 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4507 AllowedNameModifiers.push_back(OMPD_parallel); 4508 break; 4509 case OMPD_distribute_simd: 4510 Res = ActOnOpenMPDistributeSimdDirective( 4511 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4512 break; 4513 case OMPD_target_parallel_for_simd: 4514 Res = ActOnOpenMPTargetParallelForSimdDirective( 4515 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4516 AllowedNameModifiers.push_back(OMPD_target); 4517 AllowedNameModifiers.push_back(OMPD_parallel); 4518 break; 4519 case OMPD_target_simd: 4520 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4521 EndLoc, VarsWithInheritedDSA); 4522 AllowedNameModifiers.push_back(OMPD_target); 4523 break; 4524 case OMPD_teams_distribute: 4525 Res = ActOnOpenMPTeamsDistributeDirective( 4526 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4527 break; 4528 case OMPD_teams_distribute_simd: 4529 Res = ActOnOpenMPTeamsDistributeSimdDirective( 4530 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4531 break; 4532 case OMPD_teams_distribute_parallel_for_simd: 4533 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 4534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4535 AllowedNameModifiers.push_back(OMPD_parallel); 4536 break; 4537 case OMPD_teams_distribute_parallel_for: 4538 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 4539 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4540 AllowedNameModifiers.push_back(OMPD_parallel); 4541 break; 4542 case OMPD_target_teams: 4543 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 4544 EndLoc); 4545 AllowedNameModifiers.push_back(OMPD_target); 4546 break; 4547 case OMPD_target_teams_distribute: 4548 Res = ActOnOpenMPTargetTeamsDistributeDirective( 4549 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4550 AllowedNameModifiers.push_back(OMPD_target); 4551 break; 4552 case OMPD_target_teams_distribute_parallel_for: 4553 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 4554 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4555 AllowedNameModifiers.push_back(OMPD_target); 4556 AllowedNameModifiers.push_back(OMPD_parallel); 4557 break; 4558 case OMPD_target_teams_distribute_parallel_for_simd: 4559 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 4560 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4561 AllowedNameModifiers.push_back(OMPD_target); 4562 AllowedNameModifiers.push_back(OMPD_parallel); 4563 break; 4564 case OMPD_target_teams_distribute_simd: 4565 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 4566 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 4567 AllowedNameModifiers.push_back(OMPD_target); 4568 break; 4569 case OMPD_declare_target: 4570 case OMPD_end_declare_target: 4571 case OMPD_threadprivate: 4572 case OMPD_allocate: 4573 case OMPD_declare_reduction: 4574 case OMPD_declare_mapper: 4575 case OMPD_declare_simd: 4576 case OMPD_requires: 4577 case OMPD_declare_variant: 4578 llvm_unreachable("OpenMP Directive is not allowed"); 4579 case OMPD_unknown: 4580 llvm_unreachable("Unknown OpenMP directive"); 4581 } 4582 4583 ErrorFound = Res.isInvalid() || ErrorFound; 4584 4585 // Check variables in the clauses if default(none) was specified. 4586 if (DSAStack->getDefaultDSA() == DSA_none) { 4587 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 4588 for (OMPClause *C : Clauses) { 4589 switch (C->getClauseKind()) { 4590 case OMPC_num_threads: 4591 case OMPC_dist_schedule: 4592 // Do not analyse if no parent teams directive. 4593 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective())) 4594 break; 4595 continue; 4596 case OMPC_if: 4597 if (isOpenMPTeamsDirective(DSAStack->getCurrentDirective()) && 4598 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 4599 break; 4600 continue; 4601 case OMPC_schedule: 4602 break; 4603 case OMPC_grainsize: 4604 case OMPC_num_tasks: 4605 case OMPC_final: 4606 case OMPC_priority: 4607 // Do not analyze if no parent parallel directive. 4608 if (isOpenMPParallelDirective(DSAStack->getCurrentDirective())) 4609 break; 4610 continue; 4611 case OMPC_ordered: 4612 case OMPC_device: 4613 case OMPC_num_teams: 4614 case OMPC_thread_limit: 4615 case OMPC_hint: 4616 case OMPC_collapse: 4617 case OMPC_safelen: 4618 case OMPC_simdlen: 4619 case OMPC_default: 4620 case OMPC_proc_bind: 4621 case OMPC_private: 4622 case OMPC_firstprivate: 4623 case OMPC_lastprivate: 4624 case OMPC_shared: 4625 case OMPC_reduction: 4626 case OMPC_task_reduction: 4627 case OMPC_in_reduction: 4628 case OMPC_linear: 4629 case OMPC_aligned: 4630 case OMPC_copyin: 4631 case OMPC_copyprivate: 4632 case OMPC_nowait: 4633 case OMPC_untied: 4634 case OMPC_mergeable: 4635 case OMPC_allocate: 4636 case OMPC_read: 4637 case OMPC_write: 4638 case OMPC_update: 4639 case OMPC_capture: 4640 case OMPC_seq_cst: 4641 case OMPC_depend: 4642 case OMPC_threads: 4643 case OMPC_simd: 4644 case OMPC_map: 4645 case OMPC_nogroup: 4646 case OMPC_defaultmap: 4647 case OMPC_to: 4648 case OMPC_from: 4649 case OMPC_use_device_ptr: 4650 case OMPC_is_device_ptr: 4651 continue; 4652 case OMPC_allocator: 4653 case OMPC_flush: 4654 case OMPC_threadprivate: 4655 case OMPC_uniform: 4656 case OMPC_unknown: 4657 case OMPC_unified_address: 4658 case OMPC_unified_shared_memory: 4659 case OMPC_reverse_offload: 4660 case OMPC_dynamic_allocators: 4661 case OMPC_atomic_default_mem_order: 4662 case OMPC_device_type: 4663 case OMPC_match: 4664 llvm_unreachable("Unexpected clause"); 4665 } 4666 for (Stmt *CC : C->children()) { 4667 if (CC) 4668 DSAChecker.Visit(CC); 4669 } 4670 } 4671 for (auto &P : DSAChecker.getVarsWithInheritedDSA()) 4672 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 4673 } 4674 for (const auto &P : VarsWithInheritedDSA) { 4675 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 4676 continue; 4677 ErrorFound = true; 4678 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 4679 << P.first << P.second->getSourceRange(); 4680 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 4681 } 4682 4683 if (!AllowedNameModifiers.empty()) 4684 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 4685 ErrorFound; 4686 4687 if (ErrorFound) 4688 return StmtError(); 4689 4690 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 4691 Res.getAs<OMPExecutableDirective>() 4692 ->getStructuredBlock() 4693 ->setIsOMPStructuredBlock(true); 4694 } 4695 4696 if (!CurContext->isDependentContext() && 4697 isOpenMPTargetExecutionDirective(Kind) && 4698 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 4699 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 4700 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 4701 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 4702 // Register target to DSA Stack. 4703 DSAStack->addTargetDirLocation(StartLoc); 4704 } 4705 4706 return Res; 4707} 4708 4709Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 4710 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 4711 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 4712 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 4713 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 4714 assert(Aligneds.size() == Alignments.size()); 4715 assert(Linears.size() == LinModifiers.size()); 4716 assert(Linears.size() == Steps.size()); 4717 if (!DG || DG.get().isNull()) 4718 return DeclGroupPtrTy(); 4719 4720 const int SimdId = 0; 4721 if (!DG.get().isSingleDecl()) { 4722 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4723 << SimdId; 4724 return DG; 4725 } 4726 Decl *ADecl = DG.get().getSingleDecl(); 4727 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4728 ADecl = FTD->getTemplatedDecl(); 4729 4730 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4731 if (!FD) { 4732 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 4733 return DeclGroupPtrTy(); 4734 } 4735 4736 // OpenMP [2.8.2, declare simd construct, Description] 4737 // The parameter of the simdlen clause must be a constant positive integer 4738 // expression. 4739 ExprResult SL; 4740 if (Simdlen) 4741 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4742 // OpenMP [2.8.2, declare simd construct, Description] 4743 // The special this pointer can be used as if was one of the arguments to the 4744 // function in any of the linear, aligned, or uniform clauses. 4745 // The uniform clause declares one or more arguments to have an invariant 4746 // value for all concurrent invocations of the function in the execution of a 4747 // single SIMD loop. 4748 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4749 const Expr *UniformedLinearThis = nullptr; 4750 for (const Expr *E : Uniforms) { 4751 E = E->IgnoreParenImpCasts(); 4752 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4753 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4754 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4755 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4756 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4757 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4758 continue; 4759 } 4760 if (isa<CXXThisExpr>(E)) { 4761 UniformedLinearThis = E; 4762 continue; 4763 } 4764 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4765 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4766 } 4767 // OpenMP [2.8.2, declare simd construct, Description] 4768 // The aligned clause declares that the object to which each list item points 4769 // is aligned to the number of bytes expressed in the optional parameter of 4770 // the aligned clause. 4771 // The special this pointer can be used as if was one of the arguments to the 4772 // function in any of the linear, aligned, or uniform clauses. 4773 // The type of list items appearing in the aligned clause must be array, 4774 // pointer, reference to array, or reference to pointer. 4775 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4776 const Expr *AlignedThis = nullptr; 4777 for (const Expr *E : Aligneds) { 4778 E = E->IgnoreParenImpCasts(); 4779 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4780 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4781 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4782 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4783 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4784 ->getCanonicalDecl() == CanonPVD) { 4785 // OpenMP [2.8.1, simd construct, Restrictions] 4786 // A list-item cannot appear in more than one aligned clause. 4787 if (AlignedArgs.count(CanonPVD) > 0) { 4788 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4789 << 1 << E->getSourceRange(); 4790 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4791 diag::note_omp_explicit_dsa) 4792 << getOpenMPClauseName(OMPC_aligned); 4793 continue; 4794 } 4795 AlignedArgs[CanonPVD] = E; 4796 QualType QTy = PVD->getType() 4797 .getNonReferenceType() 4798 .getUnqualifiedType() 4799 .getCanonicalType(); 4800 const Type *Ty = QTy.getTypePtrOrNull(); 4801 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4802 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4803 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4804 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4805 } 4806 continue; 4807 } 4808 } 4809 if (isa<CXXThisExpr>(E)) { 4810 if (AlignedThis) { 4811 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4812 << 2 << E->getSourceRange(); 4813 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4814 << getOpenMPClauseName(OMPC_aligned); 4815 } 4816 AlignedThis = E; 4817 continue; 4818 } 4819 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4820 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4821 } 4822 // The optional parameter of the aligned clause, alignment, must be a constant 4823 // positive integer expression. If no optional parameter is specified, 4824 // implementation-defined default alignments for SIMD instructions on the 4825 // target platforms are assumed. 4826 SmallVector<const Expr *, 4> NewAligns; 4827 for (Expr *E : Alignments) { 4828 ExprResult Align; 4829 if (E) 4830 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4831 NewAligns.push_back(Align.get()); 4832 } 4833 // OpenMP [2.8.2, declare simd construct, Description] 4834 // The linear clause declares one or more list items to be private to a SIMD 4835 // lane and to have a linear relationship with respect to the iteration space 4836 // of a loop. 4837 // The special this pointer can be used as if was one of the arguments to the 4838 // function in any of the linear, aligned, or uniform clauses. 4839 // When a linear-step expression is specified in a linear clause it must be 4840 // either a constant integer expression or an integer-typed parameter that is 4841 // specified in a uniform clause on the directive. 4842 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4843 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4844 auto MI = LinModifiers.begin(); 4845 for (const Expr *E : Linears) { 4846 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4847 ++MI; 4848 E = E->IgnoreParenImpCasts(); 4849 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4850 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4851 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4852 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4853 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4854 ->getCanonicalDecl() == CanonPVD) { 4855 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4856 // A list-item cannot appear in more than one linear clause. 4857 if (LinearArgs.count(CanonPVD) > 0) { 4858 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4859 << getOpenMPClauseName(OMPC_linear) 4860 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4861 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4862 diag::note_omp_explicit_dsa) 4863 << getOpenMPClauseName(OMPC_linear); 4864 continue; 4865 } 4866 // Each argument can appear in at most one uniform or linear clause. 4867 if (UniformedArgs.count(CanonPVD) > 0) { 4868 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4869 << getOpenMPClauseName(OMPC_linear) 4870 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4871 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4872 diag::note_omp_explicit_dsa) 4873 << getOpenMPClauseName(OMPC_uniform); 4874 continue; 4875 } 4876 LinearArgs[CanonPVD] = E; 4877 if (E->isValueDependent() || E->isTypeDependent() || 4878 E->isInstantiationDependent() || 4879 E->containsUnexpandedParameterPack()) 4880 continue; 4881 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4882 PVD->getOriginalType()); 4883 continue; 4884 } 4885 } 4886 if (isa<CXXThisExpr>(E)) { 4887 if (UniformedLinearThis) { 4888 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4889 << getOpenMPClauseName(OMPC_linear) 4890 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4891 << E->getSourceRange(); 4892 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4893 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4894 : OMPC_linear); 4895 continue; 4896 } 4897 UniformedLinearThis = E; 4898 if (E->isValueDependent() || E->isTypeDependent() || 4899 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4900 continue; 4901 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4902 E->getType()); 4903 continue; 4904 } 4905 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4906 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4907 } 4908 Expr *Step = nullptr; 4909 Expr *NewStep = nullptr; 4910 SmallVector<Expr *, 4> NewSteps; 4911 for (Expr *E : Steps) { 4912 // Skip the same step expression, it was checked already. 4913 if (Step == E || !E) { 4914 NewSteps.push_back(E ? NewStep : nullptr); 4915 continue; 4916 } 4917 Step = E; 4918 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4919 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4920 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4921 if (UniformedArgs.count(CanonPVD) == 0) { 4922 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4923 << Step->getSourceRange(); 4924 } else if (E->isValueDependent() || E->isTypeDependent() || 4925 E->isInstantiationDependent() || 4926 E->containsUnexpandedParameterPack() || 4927 CanonPVD->getType()->hasIntegerRepresentation()) { 4928 NewSteps.push_back(Step); 4929 } else { 4930 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4931 << Step->getSourceRange(); 4932 } 4933 continue; 4934 } 4935 NewStep = Step; 4936 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4937 !Step->isInstantiationDependent() && 4938 !Step->containsUnexpandedParameterPack()) { 4939 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4940 .get(); 4941 if (NewStep) 4942 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4943 } 4944 NewSteps.push_back(NewStep); 4945 } 4946 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4947 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4948 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4949 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4950 const_cast<Expr **>(Linears.data()), Linears.size(), 4951 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4952 NewSteps.data(), NewSteps.size(), SR); 4953 ADecl->addAttr(NewAttr); 4954 return DG; 4955} 4956 4957Optional<std::pair<FunctionDecl *, Expr *>> 4958Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 4959 Expr *VariantRef, SourceRange SR) { 4960 if (!DG || DG.get().isNull()) 4961 return None; 4962 4963 const int VariantId = 1; 4964 // Must be applied only to single decl. 4965 if (!DG.get().isSingleDecl()) { 4966 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 4967 << VariantId << SR; 4968 return None; 4969 } 4970 Decl *ADecl = DG.get().getSingleDecl(); 4971 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 4972 ADecl = FTD->getTemplatedDecl(); 4973 4974 // Decl must be a function. 4975 auto *FD = dyn_cast<FunctionDecl>(ADecl); 4976 if (!FD) { 4977 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 4978 << VariantId << SR; 4979 return None; 4980 } 4981 4982 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 4983 return FD->hasAttrs() && 4984 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 4985 FD->hasAttr<TargetAttr>()); 4986 }; 4987 // OpenMP is not compatible with CPU-specific attributes. 4988 if (HasMultiVersionAttributes(FD)) { 4989 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 4990 << SR; 4991 return None; 4992 } 4993 4994 // Allow #pragma omp declare variant only if the function is not used. 4995 if (FD->isUsed(false)) 4996 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 4997 << FD->getLocation(); 4998 4999 // Check if the function was emitted already. 5000 const FunctionDecl *Definition; 5001 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5002 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5003 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5004 << FD->getLocation(); 5005 5006 // The VariantRef must point to function. 5007 if (!VariantRef) { 5008 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5009 return None; 5010 } 5011 5012 // Do not check templates, wait until instantiation. 5013 if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() || 5014 VariantRef->containsUnexpandedParameterPack() || 5015 VariantRef->isInstantiationDependent() || FD->isDependentContext()) 5016 return std::make_pair(FD, VariantRef); 5017 5018 // Convert VariantRef expression to the type of the original function to 5019 // resolve possible conflicts. 5020 ExprResult VariantRefCast; 5021 if (LangOpts.CPlusPlus) { 5022 QualType FnPtrType; 5023 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5024 if (Method && !Method->isStatic()) { 5025 const Type *ClassType = 5026 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5027 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5028 ExprResult ER; 5029 { 5030 // Build adrr_of unary op to correctly handle type checks for member 5031 // functions. 5032 Sema::TentativeAnalysisScope Trap(*this); 5033 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5034 VariantRef); 5035 } 5036 if (!ER.isUsable()) { 5037 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5038 << VariantId << VariantRef->getSourceRange(); 5039 return None; 5040 } 5041 VariantRef = ER.get(); 5042 } else { 5043 FnPtrType = Context.getPointerType(FD->getType()); 5044 } 5045 ImplicitConversionSequence ICS = 5046 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5047 /*SuppressUserConversions=*/false, 5048 /*AllowExplicit=*/false, 5049 /*InOverloadResolution=*/false, 5050 /*CStyle=*/false, 5051 /*AllowObjCWritebackConversion=*/false); 5052 if (ICS.isFailure()) { 5053 Diag(VariantRef->getExprLoc(), 5054 diag::err_omp_declare_variant_incompat_types) 5055 << VariantRef->getType() << FnPtrType << VariantRef->getSourceRange(); 5056 return None; 5057 } 5058 VariantRefCast = PerformImplicitConversion( 5059 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 5060 if (!VariantRefCast.isUsable()) 5061 return None; 5062 // Drop previously built artificial addr_of unary op for member functions. 5063 if (Method && !Method->isStatic()) { 5064 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 5065 if (auto *UO = dyn_cast<UnaryOperator>( 5066 PossibleAddrOfVariantRef->IgnoreImplicit())) 5067 VariantRefCast = UO->getSubExpr(); 5068 } 5069 } else { 5070 VariantRefCast = VariantRef; 5071 } 5072 5073 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 5074 if (!ER.isUsable() || 5075 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 5076 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5077 << VariantId << VariantRef->getSourceRange(); 5078 return None; 5079 } 5080 5081 // The VariantRef must point to function. 5082 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 5083 if (!DRE) { 5084 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5085 << VariantId << VariantRef->getSourceRange(); 5086 return None; 5087 } 5088 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 5089 if (!NewFD) { 5090 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5091 << VariantId << VariantRef->getSourceRange(); 5092 return None; 5093 } 5094 5095 // Check if variant function is not marked with declare variant directive. 5096 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 5097 Diag(VariantRef->getExprLoc(), 5098 diag::warn_omp_declare_variant_marked_as_declare_variant) 5099 << VariantRef->getSourceRange(); 5100 SourceRange SR = 5101 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 5102 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 5103 return None; 5104 } 5105 5106 enum DoesntSupport { 5107 VirtFuncs = 1, 5108 Constructors = 3, 5109 Destructors = 4, 5110 DeletedFuncs = 5, 5111 DefaultedFuncs = 6, 5112 ConstexprFuncs = 7, 5113 ConstevalFuncs = 8, 5114 }; 5115 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 5116 if (CXXFD->isVirtual()) { 5117 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5118 << VirtFuncs; 5119 return None; 5120 } 5121 5122 if (isa<CXXConstructorDecl>(FD)) { 5123 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5124 << Constructors; 5125 return None; 5126 } 5127 5128 if (isa<CXXDestructorDecl>(FD)) { 5129 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5130 << Destructors; 5131 return None; 5132 } 5133 } 5134 5135 if (FD->isDeleted()) { 5136 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5137 << DeletedFuncs; 5138 return None; 5139 } 5140 5141 if (FD->isDefaulted()) { 5142 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5143 << DefaultedFuncs; 5144 return None; 5145 } 5146 5147 if (FD->isConstexpr()) { 5148 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 5149 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 5150 return None; 5151 } 5152 5153 // Check general compatibility. 5154 if (areMultiversionVariantFunctionsCompatible( 5155 FD, NewFD, PDiag(diag::err_omp_declare_variant_noproto), 5156 PartialDiagnosticAt( 5157 SR.getBegin(), 5158 PDiag(diag::note_omp_declare_variant_specified_here) << SR), 5159 PartialDiagnosticAt( 5160 VariantRef->getExprLoc(), 5161 PDiag(diag::err_omp_declare_variant_doesnt_support)), 5162 PartialDiagnosticAt(VariantRef->getExprLoc(), 5163 PDiag(diag::err_omp_declare_variant_diff) 5164 << FD->getLocation()), 5165 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 5166 /*CLinkageMayDiffer=*/true)) 5167 return None; 5168 return std::make_pair(FD, cast<Expr>(DRE)); 5169} 5170 5171void Sema::ActOnOpenMPDeclareVariantDirective( 5172 FunctionDecl *FD, Expr *VariantRef, SourceRange SR, 5173 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 5174 if (Data.CtxSet == OMPDeclareVariantAttr::CtxSetUnknown || 5175 Data.Ctx == OMPDeclareVariantAttr::CtxUnknown) 5176 return; 5177 Expr *Score = nullptr; 5178 OMPDeclareVariantAttr::ScoreType ST = OMPDeclareVariantAttr::ScoreUnknown; 5179 if (Data.CtxScore.isUsable()) { 5180 ST = OMPDeclareVariantAttr::ScoreSpecified; 5181 Score = Data.CtxScore.get(); 5182 if (!Score->isTypeDependent() && !Score->isValueDependent() && 5183 !Score->isInstantiationDependent() && 5184 !Score->containsUnexpandedParameterPack()) { 5185 llvm::APSInt Result; 5186 ExprResult ICE = VerifyIntegerConstantExpression(Score, &Result); 5187 if (ICE.isInvalid()) 5188 return; 5189 } 5190 } 5191 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 5192 Context, VariantRef, Score, Data.CtxSet, ST, Data.Ctx, 5193 Data.ImplVendors.begin(), Data.ImplVendors.size(), SR); 5194 FD->addAttr(NewAttr); 5195} 5196 5197void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, 5198 FunctionDecl *Func, 5199 bool MightBeOdrUse) { 5200 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 5201 5202 if (!Func->isDependentContext() && Func->hasAttrs()) { 5203 for (OMPDeclareVariantAttr *A : 5204 Func->specific_attrs<OMPDeclareVariantAttr>()) { 5205 // TODO: add checks for active OpenMP context where possible. 5206 Expr *VariantRef = A->getVariantFuncRef(); 5207 auto *DRE = dyn_cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts()); 5208 auto *F = cast<FunctionDecl>(DRE->getDecl()); 5209 if (!F->isDefined() && F->isTemplateInstantiation()) 5210 InstantiateFunctionDefinition(Loc, F->getFirstDecl()); 5211 MarkFunctionReferenced(Loc, F, MightBeOdrUse); 5212 } 5213 } 5214} 5215 5216StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 5217 Stmt *AStmt, 5218 SourceLocation StartLoc, 5219 SourceLocation EndLoc) { 5220 if (!AStmt) 5221 return StmtError(); 5222 5223 auto *CS = cast<CapturedStmt>(AStmt); 5224 // 1.2.2 OpenMP Language Terminology 5225 // Structured block - An executable statement with a single entry at the 5226 // top and a single exit at the bottom. 5227 // The point of exit cannot be a branch out of the structured block. 5228 // longjmp() and throw() must not violate the entry/exit criteria. 5229 CS->getCapturedDecl()->setNothrow(); 5230 5231 setFunctionHasBranchProtectedScope(); 5232 5233 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5234 DSAStack->isCancelRegion()); 5235} 5236 5237namespace { 5238/// Iteration space of a single for loop. 5239struct LoopIterationSpace final { 5240 /// True if the condition operator is the strict compare operator (<, > or 5241 /// !=). 5242 bool IsStrictCompare = false; 5243 /// Condition of the loop. 5244 Expr *PreCond = nullptr; 5245 /// This expression calculates the number of iterations in the loop. 5246 /// It is always possible to calculate it before starting the loop. 5247 Expr *NumIterations = nullptr; 5248 /// The loop counter variable. 5249 Expr *CounterVar = nullptr; 5250 /// Private loop counter variable. 5251 Expr *PrivateCounterVar = nullptr; 5252 /// This is initializer for the initial value of #CounterVar. 5253 Expr *CounterInit = nullptr; 5254 /// This is step for the #CounterVar used to generate its update: 5255 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5256 Expr *CounterStep = nullptr; 5257 /// Should step be subtracted? 5258 bool Subtract = false; 5259 /// Source range of the loop init. 5260 SourceRange InitSrcRange; 5261 /// Source range of the loop condition. 5262 SourceRange CondSrcRange; 5263 /// Source range of the loop increment. 5264 SourceRange IncSrcRange; 5265 /// Minimum value that can have the loop control variable. Used to support 5266 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 5267 /// since only such variables can be used in non-loop invariant expressions. 5268 Expr *MinValue = nullptr; 5269 /// Maximum value that can have the loop control variable. Used to support 5270 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 5271 /// since only such variables can be used in non-loop invariant expressions. 5272 Expr *MaxValue = nullptr; 5273 /// true, if the lower bound depends on the outer loop control var. 5274 bool IsNonRectangularLB = false; 5275 /// true, if the upper bound depends on the outer loop control var. 5276 bool IsNonRectangularUB = false; 5277 /// Index of the loop this loop depends on and forms non-rectangular loop 5278 /// nest. 5279 unsigned LoopDependentIdx = 0; 5280 /// Final condition for the non-rectangular loop nest support. It is used to 5281 /// check that the number of iterations for this particular counter must be 5282 /// finished. 5283 Expr *FinalCondition = nullptr; 5284}; 5285 5286/// Helper class for checking canonical form of the OpenMP loops and 5287/// extracting iteration space of each loop in the loop nest, that will be used 5288/// for IR generation. 5289class OpenMPIterationSpaceChecker { 5290 /// Reference to Sema. 5291 Sema &SemaRef; 5292 /// Data-sharing stack. 5293 DSAStackTy &Stack; 5294 /// A location for diagnostics (when there is no some better location). 5295 SourceLocation DefaultLoc; 5296 /// A location for diagnostics (when increment is not compatible). 5297 SourceLocation ConditionLoc; 5298 /// A source location for referring to loop init later. 5299 SourceRange InitSrcRange; 5300 /// A source location for referring to condition later. 5301 SourceRange ConditionSrcRange; 5302 /// A source location for referring to increment later. 5303 SourceRange IncrementSrcRange; 5304 /// Loop variable. 5305 ValueDecl *LCDecl = nullptr; 5306 /// Reference to loop variable. 5307 Expr *LCRef = nullptr; 5308 /// Lower bound (initializer for the var). 5309 Expr *LB = nullptr; 5310 /// Upper bound. 5311 Expr *UB = nullptr; 5312 /// Loop step (increment). 5313 Expr *Step = nullptr; 5314 /// This flag is true when condition is one of: 5315 /// Var < UB 5316 /// Var <= UB 5317 /// UB > Var 5318 /// UB >= Var 5319 /// This will have no value when the condition is != 5320 llvm::Optional<bool> TestIsLessOp; 5321 /// This flag is true when condition is strict ( < or > ). 5322 bool TestIsStrictOp = false; 5323 /// This flag is true when step is subtracted on each iteration. 5324 bool SubtractStep = false; 5325 /// The outer loop counter this loop depends on (if any). 5326 const ValueDecl *DepDecl = nullptr; 5327 /// Contains number of loop (starts from 1) on which loop counter init 5328 /// expression of this loop depends on. 5329 Optional<unsigned> InitDependOnLC; 5330 /// Contains number of loop (starts from 1) on which loop counter condition 5331 /// expression of this loop depends on. 5332 Optional<unsigned> CondDependOnLC; 5333 /// Checks if the provide statement depends on the loop counter. 5334 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 5335 /// Original condition required for checking of the exit condition for 5336 /// non-rectangular loop. 5337 Expr *Condition = nullptr; 5338 5339public: 5340 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 5341 SourceLocation DefaultLoc) 5342 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 5343 ConditionLoc(DefaultLoc) {} 5344 /// Check init-expr for canonical loop form and save loop counter 5345 /// variable - #Var and its initialization value - #LB. 5346 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 5347 /// Check test-expr for canonical form, save upper-bound (#UB), flags 5348 /// for less/greater and for strict/non-strict comparison. 5349 bool checkAndSetCond(Expr *S); 5350 /// Check incr-expr for canonical loop form and return true if it 5351 /// does not conform, otherwise save loop step (#Step). 5352 bool checkAndSetInc(Expr *S); 5353 /// Return the loop counter variable. 5354 ValueDecl *getLoopDecl() const { return LCDecl; } 5355 /// Return the reference expression to loop counter variable. 5356 Expr *getLoopDeclRefExpr() const { return LCRef; } 5357 /// Source range of the loop init. 5358 SourceRange getInitSrcRange() const { return InitSrcRange; } 5359 /// Source range of the loop condition. 5360 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 5361 /// Source range of the loop increment. 5362 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 5363 /// True if the step should be subtracted. 5364 bool shouldSubtractStep() const { return SubtractStep; } 5365 /// True, if the compare operator is strict (<, > or !=). 5366 bool isStrictTestOp() const { return TestIsStrictOp; } 5367 /// Build the expression to calculate the number of iterations. 5368 Expr *buildNumIterations( 5369 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5370 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5371 /// Build the precondition expression for the loops. 5372 Expr * 5373 buildPreCond(Scope *S, Expr *Cond, 5374 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5375 /// Build reference expression to the counter be used for codegen. 5376 DeclRefExpr * 5377 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5378 DSAStackTy &DSA) const; 5379 /// Build reference expression to the private counter be used for 5380 /// codegen. 5381 Expr *buildPrivateCounterVar() const; 5382 /// Build initialization of the counter be used for codegen. 5383 Expr *buildCounterInit() const; 5384 /// Build step of the counter be used for codegen. 5385 Expr *buildCounterStep() const; 5386 /// Build loop data with counter value for depend clauses in ordered 5387 /// directives. 5388 Expr * 5389 buildOrderedLoopData(Scope *S, Expr *Counter, 5390 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 5391 SourceLocation Loc, Expr *Inc = nullptr, 5392 OverloadedOperatorKind OOK = OO_Amp); 5393 /// Builds the minimum value for the loop counter. 5394 std::pair<Expr *, Expr *> buildMinMaxValues( 5395 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 5396 /// Builds final condition for the non-rectangular loops. 5397 Expr *buildFinalCondition(Scope *S) const; 5398 /// Return true if any expression is dependent. 5399 bool dependent() const; 5400 /// Returns true if the initializer forms non-rectangular loop. 5401 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 5402 /// Returns true if the condition forms non-rectangular loop. 5403 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 5404 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 5405 unsigned getLoopDependentIdx() const { 5406 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 5407 } 5408 5409private: 5410 /// Check the right-hand side of an assignment in the increment 5411 /// expression. 5412 bool checkAndSetIncRHS(Expr *RHS); 5413 /// Helper to set loop counter variable and its initializer. 5414 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 5415 bool EmitDiags); 5416 /// Helper to set upper bound. 5417 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 5418 SourceRange SR, SourceLocation SL); 5419 /// Helper to set loop increment. 5420 bool setStep(Expr *NewStep, bool Subtract); 5421}; 5422 5423bool OpenMPIterationSpaceChecker::dependent() const { 5424 if (!LCDecl) { 5425 assert(!LB && !UB && !Step); 5426 return false; 5427 } 5428 return LCDecl->getType()->isDependentType() || 5429 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 5430 (Step && Step->isValueDependent()); 5431} 5432 5433bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 5434 Expr *NewLCRefExpr, 5435 Expr *NewLB, bool EmitDiags) { 5436 // State consistency checking to ensure correct usage. 5437 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 5438 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5439 if (!NewLCDecl || !NewLB) 5440 return true; 5441 LCDecl = getCanonicalDecl(NewLCDecl); 5442 LCRef = NewLCRefExpr; 5443 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 5444 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5445 if ((Ctor->isCopyOrMoveConstructor() || 5446 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5447 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5448 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 5449 LB = NewLB; 5450 if (EmitDiags) 5451 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 5452 return false; 5453} 5454 5455bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 5456 llvm::Optional<bool> LessOp, 5457 bool StrictOp, SourceRange SR, 5458 SourceLocation SL) { 5459 // State consistency checking to ensure correct usage. 5460 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 5461 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 5462 if (!NewUB) 5463 return true; 5464 UB = NewUB; 5465 if (LessOp) 5466 TestIsLessOp = LessOp; 5467 TestIsStrictOp = StrictOp; 5468 ConditionSrcRange = SR; 5469 ConditionLoc = SL; 5470 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 5471 return false; 5472} 5473 5474bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 5475 // State consistency checking to ensure correct usage. 5476 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 5477 if (!NewStep) 5478 return true; 5479 if (!NewStep->isValueDependent()) { 5480 // Check that the step is integer expression. 5481 SourceLocation StepLoc = NewStep->getBeginLoc(); 5482 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 5483 StepLoc, getExprAsWritten(NewStep)); 5484 if (Val.isInvalid()) 5485 return true; 5486 NewStep = Val.get(); 5487 5488 // OpenMP [2.6, Canonical Loop Form, Restrictions] 5489 // If test-expr is of form var relational-op b and relational-op is < or 5490 // <= then incr-expr must cause var to increase on each iteration of the 5491 // loop. If test-expr is of form var relational-op b and relational-op is 5492 // > or >= then incr-expr must cause var to decrease on each iteration of 5493 // the loop. 5494 // If test-expr is of form b relational-op var and relational-op is < or 5495 // <= then incr-expr must cause var to decrease on each iteration of the 5496 // loop. If test-expr is of form b relational-op var and relational-op is 5497 // > or >= then incr-expr must cause var to increase on each iteration of 5498 // the loop. 5499 llvm::APSInt Result; 5500 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 5501 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 5502 bool IsConstNeg = 5503 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 5504 bool IsConstPos = 5505 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 5506 bool IsConstZero = IsConstant && !Result.getBoolValue(); 5507 5508 // != with increment is treated as <; != with decrement is treated as > 5509 if (!TestIsLessOp.hasValue()) 5510 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 5511 if (UB && (IsConstZero || 5512 (TestIsLessOp.getValue() ? 5513 (IsConstNeg || (IsUnsigned && Subtract)) : 5514 (IsConstPos || (IsUnsigned && !Subtract))))) { 5515 SemaRef.Diag(NewStep->getExprLoc(), 5516 diag::err_omp_loop_incr_not_compatible) 5517 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 5518 SemaRef.Diag(ConditionLoc, 5519 diag::note_omp_loop_cond_requres_compatible_incr) 5520 << TestIsLessOp.getValue() << ConditionSrcRange; 5521 return true; 5522 } 5523 if (TestIsLessOp.getValue() == Subtract) { 5524 NewStep = 5525 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 5526 .get(); 5527 Subtract = !Subtract; 5528 } 5529 } 5530 5531 Step = NewStep; 5532 SubtractStep = Subtract; 5533 return false; 5534} 5535 5536namespace { 5537/// Checker for the non-rectangular loops. Checks if the initializer or 5538/// condition expression references loop counter variable. 5539class LoopCounterRefChecker final 5540 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 5541 Sema &SemaRef; 5542 DSAStackTy &Stack; 5543 const ValueDecl *CurLCDecl = nullptr; 5544 const ValueDecl *DepDecl = nullptr; 5545 const ValueDecl *PrevDepDecl = nullptr; 5546 bool IsInitializer = true; 5547 unsigned BaseLoopId = 0; 5548 bool checkDecl(const Expr *E, const ValueDecl *VD) { 5549 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 5550 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 5551 << (IsInitializer ? 0 : 1); 5552 return false; 5553 } 5554 const auto &&Data = Stack.isLoopControlVariable(VD); 5555 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 5556 // The type of the loop iterator on which we depend may not have a random 5557 // access iterator type. 5558 if (Data.first && VD->getType()->isRecordType()) { 5559 SmallString<128> Name; 5560 llvm::raw_svector_ostream OS(Name); 5561 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5562 /*Qualified=*/true); 5563 SemaRef.Diag(E->getExprLoc(), 5564 diag::err_omp_wrong_dependency_iterator_type) 5565 << OS.str(); 5566 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 5567 return false; 5568 } 5569 if (Data.first && 5570 (DepDecl || (PrevDepDecl && 5571 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 5572 if (!DepDecl && PrevDepDecl) 5573 DepDecl = PrevDepDecl; 5574 SmallString<128> Name; 5575 llvm::raw_svector_ostream OS(Name); 5576 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 5577 /*Qualified=*/true); 5578 SemaRef.Diag(E->getExprLoc(), 5579 diag::err_omp_invariant_or_linear_dependency) 5580 << OS.str(); 5581 return false; 5582 } 5583 if (Data.first) { 5584 DepDecl = VD; 5585 BaseLoopId = Data.first; 5586 } 5587 return Data.first; 5588 } 5589 5590public: 5591 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5592 const ValueDecl *VD = E->getDecl(); 5593 if (isa<VarDecl>(VD)) 5594 return checkDecl(E, VD); 5595 return false; 5596 } 5597 bool VisitMemberExpr(const MemberExpr *E) { 5598 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 5599 const ValueDecl *VD = E->getMemberDecl(); 5600 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 5601 return checkDecl(E, VD); 5602 } 5603 return false; 5604 } 5605 bool VisitStmt(const Stmt *S) { 5606 bool Res = false; 5607 for (const Stmt *Child : S->children()) 5608 Res = (Child && Visit(Child)) || Res; 5609 return Res; 5610 } 5611 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 5612 const ValueDecl *CurLCDecl, bool IsInitializer, 5613 const ValueDecl *PrevDepDecl = nullptr) 5614 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 5615 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 5616 unsigned getBaseLoopId() const { 5617 assert(CurLCDecl && "Expected loop dependency."); 5618 return BaseLoopId; 5619 } 5620 const ValueDecl *getDepDecl() const { 5621 assert(CurLCDecl && "Expected loop dependency."); 5622 return DepDecl; 5623 } 5624}; 5625} // namespace 5626 5627Optional<unsigned> 5628OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 5629 bool IsInitializer) { 5630 // Check for the non-rectangular loops. 5631 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 5632 DepDecl); 5633 if (LoopStmtChecker.Visit(S)) { 5634 DepDecl = LoopStmtChecker.getDepDecl(); 5635 return LoopStmtChecker.getBaseLoopId(); 5636 } 5637 return llvm::None; 5638} 5639 5640bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 5641 // Check init-expr for canonical loop form and save loop counter 5642 // variable - #Var and its initialization value - #LB. 5643 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 5644 // var = lb 5645 // integer-type var = lb 5646 // random-access-iterator-type var = lb 5647 // pointer-type var = lb 5648 // 5649 if (!S) { 5650 if (EmitDiags) { 5651 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 5652 } 5653 return true; 5654 } 5655 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5656 if (!ExprTemp->cleanupsHaveSideEffects()) 5657 S = ExprTemp->getSubExpr(); 5658 5659 InitSrcRange = S->getSourceRange(); 5660 if (Expr *E = dyn_cast<Expr>(S)) 5661 S = E->IgnoreParens(); 5662 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5663 if (BO->getOpcode() == BO_Assign) { 5664 Expr *LHS = BO->getLHS()->IgnoreParens(); 5665 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5666 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5667 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5668 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5669 EmitDiags); 5670 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 5671 } 5672 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5673 if (ME->isArrow() && 5674 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5675 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5676 EmitDiags); 5677 } 5678 } 5679 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 5680 if (DS->isSingleDecl()) { 5681 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 5682 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 5683 // Accept non-canonical init form here but emit ext. warning. 5684 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 5685 SemaRef.Diag(S->getBeginLoc(), 5686 diag::ext_omp_loop_not_canonical_init) 5687 << S->getSourceRange(); 5688 return setLCDeclAndLB( 5689 Var, 5690 buildDeclRefExpr(SemaRef, Var, 5691 Var->getType().getNonReferenceType(), 5692 DS->getBeginLoc()), 5693 Var->getInit(), EmitDiags); 5694 } 5695 } 5696 } 5697 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5698 if (CE->getOperator() == OO_Equal) { 5699 Expr *LHS = CE->getArg(0); 5700 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 5701 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 5702 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 5703 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5704 EmitDiags); 5705 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 5706 } 5707 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 5708 if (ME->isArrow() && 5709 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5710 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 5711 EmitDiags); 5712 } 5713 } 5714 } 5715 5716 if (dependent() || SemaRef.CurContext->isDependentContext()) 5717 return false; 5718 if (EmitDiags) { 5719 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 5720 << S->getSourceRange(); 5721 } 5722 return true; 5723} 5724 5725/// Ignore parenthesizes, implicit casts, copy constructor and return the 5726/// variable (which may be the loop variable) if possible. 5727static const ValueDecl *getInitLCDecl(const Expr *E) { 5728 if (!E) 5729 return nullptr; 5730 E = getExprAsWritten(E); 5731 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 5732 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 5733 if ((Ctor->isCopyOrMoveConstructor() || 5734 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 5735 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 5736 E = CE->getArg(0)->IgnoreParenImpCasts(); 5737 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 5738 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 5739 return getCanonicalDecl(VD); 5740 } 5741 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 5742 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 5743 return getCanonicalDecl(ME->getMemberDecl()); 5744 return nullptr; 5745} 5746 5747bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 5748 // Check test-expr for canonical form, save upper-bound UB, flags for 5749 // less/greater and for strict/non-strict comparison. 5750 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 5751 // var relational-op b 5752 // b relational-op var 5753 // 5754 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 5755 if (!S) { 5756 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 5757 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 5758 return true; 5759 } 5760 Condition = S; 5761 S = getExprAsWritten(S); 5762 SourceLocation CondLoc = S->getBeginLoc(); 5763 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5764 if (BO->isRelationalOp()) { 5765 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5766 return setUB(BO->getRHS(), 5767 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 5768 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5769 BO->getSourceRange(), BO->getOperatorLoc()); 5770 if (getInitLCDecl(BO->getRHS()) == LCDecl) 5771 return setUB(BO->getLHS(), 5772 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 5773 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 5774 BO->getSourceRange(), BO->getOperatorLoc()); 5775 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 5776 return setUB( 5777 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 5778 /*LessOp=*/llvm::None, 5779 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 5780 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5781 if (CE->getNumArgs() == 2) { 5782 auto Op = CE->getOperator(); 5783 switch (Op) { 5784 case OO_Greater: 5785 case OO_GreaterEqual: 5786 case OO_Less: 5787 case OO_LessEqual: 5788 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5789 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 5790 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5791 CE->getOperatorLoc()); 5792 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 5793 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 5794 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 5795 CE->getOperatorLoc()); 5796 break; 5797 case OO_ExclaimEqual: 5798 if (IneqCondIsCanonical) 5799 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 5800 : CE->getArg(0), 5801 /*LessOp=*/llvm::None, 5802 /*StrictOp=*/true, CE->getSourceRange(), 5803 CE->getOperatorLoc()); 5804 break; 5805 default: 5806 break; 5807 } 5808 } 5809 } 5810 if (dependent() || SemaRef.CurContext->isDependentContext()) 5811 return false; 5812 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 5813 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 5814 return true; 5815} 5816 5817bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 5818 // RHS of canonical loop form increment can be: 5819 // var + incr 5820 // incr + var 5821 // var - incr 5822 // 5823 RHS = RHS->IgnoreParenImpCasts(); 5824 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 5825 if (BO->isAdditiveOp()) { 5826 bool IsAdd = BO->getOpcode() == BO_Add; 5827 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5828 return setStep(BO->getRHS(), !IsAdd); 5829 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 5830 return setStep(BO->getLHS(), /*Subtract=*/false); 5831 } 5832 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 5833 bool IsAdd = CE->getOperator() == OO_Plus; 5834 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 5835 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5836 return setStep(CE->getArg(1), !IsAdd); 5837 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 5838 return setStep(CE->getArg(0), /*Subtract=*/false); 5839 } 5840 } 5841 if (dependent() || SemaRef.CurContext->isDependentContext()) 5842 return false; 5843 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5844 << RHS->getSourceRange() << LCDecl; 5845 return true; 5846} 5847 5848bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 5849 // Check incr-expr for canonical loop form and return true if it 5850 // does not conform. 5851 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 5852 // ++var 5853 // var++ 5854 // --var 5855 // var-- 5856 // var += incr 5857 // var -= incr 5858 // var = var + incr 5859 // var = incr + var 5860 // var = var - incr 5861 // 5862 if (!S) { 5863 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 5864 return true; 5865 } 5866 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 5867 if (!ExprTemp->cleanupsHaveSideEffects()) 5868 S = ExprTemp->getSubExpr(); 5869 5870 IncrementSrcRange = S->getSourceRange(); 5871 S = S->IgnoreParens(); 5872 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 5873 if (UO->isIncrementDecrementOp() && 5874 getInitLCDecl(UO->getSubExpr()) == LCDecl) 5875 return setStep(SemaRef 5876 .ActOnIntegerConstant(UO->getBeginLoc(), 5877 (UO->isDecrementOp() ? -1 : 1)) 5878 .get(), 5879 /*Subtract=*/false); 5880 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 5881 switch (BO->getOpcode()) { 5882 case BO_AddAssign: 5883 case BO_SubAssign: 5884 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5885 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 5886 break; 5887 case BO_Assign: 5888 if (getInitLCDecl(BO->getLHS()) == LCDecl) 5889 return checkAndSetIncRHS(BO->getRHS()); 5890 break; 5891 default: 5892 break; 5893 } 5894 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 5895 switch (CE->getOperator()) { 5896 case OO_PlusPlus: 5897 case OO_MinusMinus: 5898 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5899 return setStep(SemaRef 5900 .ActOnIntegerConstant( 5901 CE->getBeginLoc(), 5902 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 5903 .get(), 5904 /*Subtract=*/false); 5905 break; 5906 case OO_PlusEqual: 5907 case OO_MinusEqual: 5908 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5909 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 5910 break; 5911 case OO_Equal: 5912 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 5913 return checkAndSetIncRHS(CE->getArg(1)); 5914 break; 5915 default: 5916 break; 5917 } 5918 } 5919 if (dependent() || SemaRef.CurContext->isDependentContext()) 5920 return false; 5921 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 5922 << S->getSourceRange() << LCDecl; 5923 return true; 5924} 5925 5926static ExprResult 5927tryBuildCapture(Sema &SemaRef, Expr *Capture, 5928 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5929 if (SemaRef.CurContext->isDependentContext()) 5930 return ExprResult(Capture); 5931 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 5932 return SemaRef.PerformImplicitConversion( 5933 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 5934 /*AllowExplicit=*/true); 5935 auto I = Captures.find(Capture); 5936 if (I != Captures.end()) 5937 return buildCapture(SemaRef, Capture, I->second); 5938 DeclRefExpr *Ref = nullptr; 5939 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 5940 Captures[Capture] = Ref; 5941 return Res; 5942} 5943 5944/// Build the expression to calculate the number of iterations. 5945Expr *OpenMPIterationSpaceChecker::buildNumIterations( 5946 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 5947 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 5948 ExprResult Diff; 5949 QualType VarType = LCDecl->getType().getNonReferenceType(); 5950 if (VarType->isIntegerType() || VarType->isPointerType() || 5951 SemaRef.getLangOpts().CPlusPlus) { 5952 Expr *LBVal = LB; 5953 Expr *UBVal = UB; 5954 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 5955 // max(LB(MinVal), LB(MaxVal)) 5956 if (InitDependOnLC) { 5957 const LoopIterationSpace &IS = 5958 ResultIterSpaces[ResultIterSpaces.size() - 1 - 5959 InitDependOnLC.getValueOr( 5960 CondDependOnLC.getValueOr(0))]; 5961 if (!IS.MinValue || !IS.MaxValue) 5962 return nullptr; 5963 // OuterVar = Min 5964 ExprResult MinValue = 5965 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 5966 if (!MinValue.isUsable()) 5967 return nullptr; 5968 5969 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5970 IS.CounterVar, MinValue.get()); 5971 if (!LBMinVal.isUsable()) 5972 return nullptr; 5973 // OuterVar = Min, LBVal 5974 LBMinVal = 5975 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 5976 if (!LBMinVal.isUsable()) 5977 return nullptr; 5978 // (OuterVar = Min, LBVal) 5979 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 5980 if (!LBMinVal.isUsable()) 5981 return nullptr; 5982 5983 // OuterVar = Max 5984 ExprResult MaxValue = 5985 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 5986 if (!MaxValue.isUsable()) 5987 return nullptr; 5988 5989 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 5990 IS.CounterVar, MaxValue.get()); 5991 if (!LBMaxVal.isUsable()) 5992 return nullptr; 5993 // OuterVar = Max, LBVal 5994 LBMaxVal = 5995 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 5996 if (!LBMaxVal.isUsable()) 5997 return nullptr; 5998 // (OuterVar = Max, LBVal) 5999 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6000 if (!LBMaxVal.isUsable()) 6001 return nullptr; 6002 6003 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6004 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6005 if (!LBMin || !LBMax) 6006 return nullptr; 6007 // LB(MinVal) < LB(MaxVal) 6008 ExprResult MinLessMaxRes = 6009 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6010 if (!MinLessMaxRes.isUsable()) 6011 return nullptr; 6012 Expr *MinLessMax = 6013 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6014 if (!MinLessMax) 6015 return nullptr; 6016 if (TestIsLessOp.getValue()) { 6017 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6018 // LB(MaxVal)) 6019 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6020 MinLessMax, LBMin, LBMax); 6021 if (!MinLB.isUsable()) 6022 return nullptr; 6023 LBVal = MinLB.get(); 6024 } else { 6025 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6026 // LB(MaxVal)) 6027 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6028 MinLessMax, LBMax, LBMin); 6029 if (!MaxLB.isUsable()) 6030 return nullptr; 6031 LBVal = MaxLB.get(); 6032 } 6033 } 6034 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6035 // min(UB(MinVal), UB(MaxVal)) 6036 if (CondDependOnLC) { 6037 const LoopIterationSpace &IS = 6038 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6039 InitDependOnLC.getValueOr( 6040 CondDependOnLC.getValueOr(0))]; 6041 if (!IS.MinValue || !IS.MaxValue) 6042 return nullptr; 6043 // OuterVar = Min 6044 ExprResult MinValue = 6045 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6046 if (!MinValue.isUsable()) 6047 return nullptr; 6048 6049 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6050 IS.CounterVar, MinValue.get()); 6051 if (!UBMinVal.isUsable()) 6052 return nullptr; 6053 // OuterVar = Min, UBVal 6054 UBMinVal = 6055 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6056 if (!UBMinVal.isUsable()) 6057 return nullptr; 6058 // (OuterVar = Min, UBVal) 6059 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6060 if (!UBMinVal.isUsable()) 6061 return nullptr; 6062 6063 // OuterVar = Max 6064 ExprResult MaxValue = 6065 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6066 if (!MaxValue.isUsable()) 6067 return nullptr; 6068 6069 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6070 IS.CounterVar, MaxValue.get()); 6071 if (!UBMaxVal.isUsable()) 6072 return nullptr; 6073 // OuterVar = Max, UBVal 6074 UBMaxVal = 6075 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 6076 if (!UBMaxVal.isUsable()) 6077 return nullptr; 6078 // (OuterVar = Max, UBVal) 6079 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 6080 if (!UBMaxVal.isUsable()) 6081 return nullptr; 6082 6083 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 6084 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 6085 if (!UBMin || !UBMax) 6086 return nullptr; 6087 // UB(MinVal) > UB(MaxVal) 6088 ExprResult MinGreaterMaxRes = 6089 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 6090 if (!MinGreaterMaxRes.isUsable()) 6091 return nullptr; 6092 Expr *MinGreaterMax = 6093 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 6094 if (!MinGreaterMax) 6095 return nullptr; 6096 if (TestIsLessOp.getValue()) { 6097 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 6098 // UB(MaxVal)) 6099 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 6100 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 6101 if (!MaxUB.isUsable()) 6102 return nullptr; 6103 UBVal = MaxUB.get(); 6104 } else { 6105 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 6106 // UB(MaxVal)) 6107 ExprResult MinUB = SemaRef.ActOnConditionalOp( 6108 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 6109 if (!MinUB.isUsable()) 6110 return nullptr; 6111 UBVal = MinUB.get(); 6112 } 6113 } 6114 // Upper - Lower 6115 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 6116 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 6117 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6118 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6119 if (!Upper || !Lower) 6120 return nullptr; 6121 6122 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6123 6124 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6125 // BuildBinOp already emitted error, this one is to point user to upper 6126 // and lower bound, and to tell what is passed to 'operator-'. 6127 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6128 << Upper->getSourceRange() << Lower->getSourceRange(); 6129 return nullptr; 6130 } 6131 } 6132 6133 if (!Diff.isUsable()) 6134 return nullptr; 6135 6136 // Upper - Lower [- 1] 6137 if (TestIsStrictOp) 6138 Diff = SemaRef.BuildBinOp( 6139 S, DefaultLoc, BO_Sub, Diff.get(), 6140 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6141 if (!Diff.isUsable()) 6142 return nullptr; 6143 6144 // Upper - Lower [- 1] + Step 6145 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6146 if (!NewStep.isUsable()) 6147 return nullptr; 6148 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 6149 if (!Diff.isUsable()) 6150 return nullptr; 6151 6152 // Parentheses (for dumping/debugging purposes only). 6153 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6154 if (!Diff.isUsable()) 6155 return nullptr; 6156 6157 // (Upper - Lower [- 1] + Step) / Step 6158 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6159 if (!Diff.isUsable()) 6160 return nullptr; 6161 6162 // OpenMP runtime requires 32-bit or 64-bit loop variables. 6163 QualType Type = Diff.get()->getType(); 6164 ASTContext &C = SemaRef.Context; 6165 bool UseVarType = VarType->hasIntegerRepresentation() && 6166 C.getTypeSize(Type) > C.getTypeSize(VarType); 6167 if (!Type->isIntegerType() || UseVarType) { 6168 unsigned NewSize = 6169 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 6170 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 6171 : Type->hasSignedIntegerRepresentation(); 6172 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 6173 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 6174 Diff = SemaRef.PerformImplicitConversion( 6175 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 6176 if (!Diff.isUsable()) 6177 return nullptr; 6178 } 6179 } 6180 if (LimitedType) { 6181 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 6182 if (NewSize != C.getTypeSize(Type)) { 6183 if (NewSize < C.getTypeSize(Type)) { 6184 assert(NewSize == 64 && "incorrect loop var size"); 6185 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 6186 << InitSrcRange << ConditionSrcRange; 6187 } 6188 QualType NewType = C.getIntTypeForBitwidth( 6189 NewSize, Type->hasSignedIntegerRepresentation() || 6190 C.getTypeSize(Type) < NewSize); 6191 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 6192 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 6193 Sema::AA_Converting, true); 6194 if (!Diff.isUsable()) 6195 return nullptr; 6196 } 6197 } 6198 } 6199 6200 return Diff.get(); 6201} 6202 6203std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 6204 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6205 // Do not build for iterators, they cannot be used in non-rectangular loop 6206 // nests. 6207 if (LCDecl->getType()->isRecordType()) 6208 return std::make_pair(nullptr, nullptr); 6209 // If we subtract, the min is in the condition, otherwise the min is in the 6210 // init value. 6211 Expr *MinExpr = nullptr; 6212 Expr *MaxExpr = nullptr; 6213 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 6214 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 6215 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 6216 : CondDependOnLC.hasValue(); 6217 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 6218 : InitDependOnLC.hasValue(); 6219 Expr *Lower = 6220 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 6221 Expr *Upper = 6222 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 6223 if (!Upper || !Lower) 6224 return std::make_pair(nullptr, nullptr); 6225 6226 if (TestIsLessOp.getValue()) 6227 MinExpr = Lower; 6228 else 6229 MaxExpr = Upper; 6230 6231 // Build minimum/maximum value based on number of iterations. 6232 ExprResult Diff; 6233 QualType VarType = LCDecl->getType().getNonReferenceType(); 6234 6235 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6236 if (!Diff.isUsable()) 6237 return std::make_pair(nullptr, nullptr); 6238 6239 // Upper - Lower [- 1] 6240 if (TestIsStrictOp) 6241 Diff = SemaRef.BuildBinOp( 6242 S, DefaultLoc, BO_Sub, Diff.get(), 6243 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 6244 if (!Diff.isUsable()) 6245 return std::make_pair(nullptr, nullptr); 6246 6247 // Upper - Lower [- 1] + Step 6248 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6249 if (!NewStep.isUsable()) 6250 return std::make_pair(nullptr, nullptr); 6251 6252 // Parentheses (for dumping/debugging purposes only). 6253 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6254 if (!Diff.isUsable()) 6255 return std::make_pair(nullptr, nullptr); 6256 6257 // (Upper - Lower [- 1]) / Step 6258 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6259 if (!Diff.isUsable()) 6260 return std::make_pair(nullptr, nullptr); 6261 6262 // ((Upper - Lower [- 1]) / Step) * Step 6263 // Parentheses (for dumping/debugging purposes only). 6264 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6265 if (!Diff.isUsable()) 6266 return std::make_pair(nullptr, nullptr); 6267 6268 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 6269 if (!Diff.isUsable()) 6270 return std::make_pair(nullptr, nullptr); 6271 6272 // Convert to the original type or ptrdiff_t, if original type is pointer. 6273 if (!VarType->isAnyPointerType() && 6274 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 6275 Diff = SemaRef.PerformImplicitConversion( 6276 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 6277 } else if (VarType->isAnyPointerType() && 6278 !SemaRef.Context.hasSameType( 6279 Diff.get()->getType(), 6280 SemaRef.Context.getUnsignedPointerDiffType())) { 6281 Diff = SemaRef.PerformImplicitConversion( 6282 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 6283 Sema::AA_Converting, /*AllowExplicit=*/true); 6284 } 6285 if (!Diff.isUsable()) 6286 return std::make_pair(nullptr, nullptr); 6287 6288 // Parentheses (for dumping/debugging purposes only). 6289 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6290 if (!Diff.isUsable()) 6291 return std::make_pair(nullptr, nullptr); 6292 6293 if (TestIsLessOp.getValue()) { 6294 // MinExpr = Lower; 6295 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 6296 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 6297 if (!Diff.isUsable()) 6298 return std::make_pair(nullptr, nullptr); 6299 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6300 if (!Diff.isUsable()) 6301 return std::make_pair(nullptr, nullptr); 6302 MaxExpr = Diff.get(); 6303 } else { 6304 // MaxExpr = Upper; 6305 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 6306 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 6307 if (!Diff.isUsable()) 6308 return std::make_pair(nullptr, nullptr); 6309 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 6310 if (!Diff.isUsable()) 6311 return std::make_pair(nullptr, nullptr); 6312 MinExpr = Diff.get(); 6313 } 6314 6315 return std::make_pair(MinExpr, MaxExpr); 6316} 6317 6318Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 6319 if (InitDependOnLC || CondDependOnLC) 6320 return Condition; 6321 return nullptr; 6322} 6323 6324Expr *OpenMPIterationSpaceChecker::buildPreCond( 6325 Scope *S, Expr *Cond, 6326 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6327 // Do not build a precondition when the condition/initialization is dependent 6328 // to prevent pessimistic early loop exit. 6329 // TODO: this can be improved by calculating min/max values but not sure that 6330 // it will be very effective. 6331 if (CondDependOnLC || InitDependOnLC) 6332 return SemaRef.PerformImplicitConversion( 6333 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 6334 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6335 /*AllowExplicit=*/true).get(); 6336 6337 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 6338 Sema::TentativeAnalysisScope Trap(SemaRef); 6339 6340 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 6341 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 6342 if (!NewLB.isUsable() || !NewUB.isUsable()) 6343 return nullptr; 6344 6345 ExprResult CondExpr = 6346 SemaRef.BuildBinOp(S, DefaultLoc, 6347 TestIsLessOp.getValue() ? 6348 (TestIsStrictOp ? BO_LT : BO_LE) : 6349 (TestIsStrictOp ? BO_GT : BO_GE), 6350 NewLB.get(), NewUB.get()); 6351 if (CondExpr.isUsable()) { 6352 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 6353 SemaRef.Context.BoolTy)) 6354 CondExpr = SemaRef.PerformImplicitConversion( 6355 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 6356 /*AllowExplicit=*/true); 6357 } 6358 6359 // Otherwise use original loop condition and evaluate it in runtime. 6360 return CondExpr.isUsable() ? CondExpr.get() : Cond; 6361} 6362 6363/// Build reference expression to the counter be used for codegen. 6364DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 6365 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6366 DSAStackTy &DSA) const { 6367 auto *VD = dyn_cast<VarDecl>(LCDecl); 6368 if (!VD) { 6369 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 6370 DeclRefExpr *Ref = buildDeclRefExpr( 6371 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 6372 const DSAStackTy::DSAVarData Data = 6373 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 6374 // If the loop control decl is explicitly marked as private, do not mark it 6375 // as captured again. 6376 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 6377 Captures.insert(std::make_pair(LCRef, Ref)); 6378 return Ref; 6379 } 6380 return cast<DeclRefExpr>(LCRef); 6381} 6382 6383Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 6384 if (LCDecl && !LCDecl->isInvalidDecl()) { 6385 QualType Type = LCDecl->getType().getNonReferenceType(); 6386 VarDecl *PrivateVar = buildVarDecl( 6387 SemaRef, DefaultLoc, Type, LCDecl->getName(), 6388 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 6389 isa<VarDecl>(LCDecl) 6390 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 6391 : nullptr); 6392 if (PrivateVar->isInvalidDecl()) 6393 return nullptr; 6394 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 6395 } 6396 return nullptr; 6397} 6398 6399/// Build initialization of the counter to be used for codegen. 6400Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 6401 6402/// Build step of the counter be used for codegen. 6403Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 6404 6405Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 6406 Scope *S, Expr *Counter, 6407 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 6408 Expr *Inc, OverloadedOperatorKind OOK) { 6409 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 6410 if (!Cnt) 6411 return nullptr; 6412 if (Inc) { 6413 assert((OOK == OO_Plus || OOK == OO_Minus) && 6414 "Expected only + or - operations for depend clauses."); 6415 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 6416 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 6417 if (!Cnt) 6418 return nullptr; 6419 } 6420 ExprResult Diff; 6421 QualType VarType = LCDecl->getType().getNonReferenceType(); 6422 if (VarType->isIntegerType() || VarType->isPointerType() || 6423 SemaRef.getLangOpts().CPlusPlus) { 6424 // Upper - Lower 6425 Expr *Upper = TestIsLessOp.getValue() 6426 ? Cnt 6427 : tryBuildCapture(SemaRef, UB, Captures).get(); 6428 Expr *Lower = TestIsLessOp.getValue() 6429 ? tryBuildCapture(SemaRef, LB, Captures).get() 6430 : Cnt; 6431 if (!Upper || !Lower) 6432 return nullptr; 6433 6434 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 6435 6436 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 6437 // BuildBinOp already emitted error, this one is to point user to upper 6438 // and lower bound, and to tell what is passed to 'operator-'. 6439 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 6440 << Upper->getSourceRange() << Lower->getSourceRange(); 6441 return nullptr; 6442 } 6443 } 6444 6445 if (!Diff.isUsable()) 6446 return nullptr; 6447 6448 // Parentheses (for dumping/debugging purposes only). 6449 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 6450 if (!Diff.isUsable()) 6451 return nullptr; 6452 6453 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 6454 if (!NewStep.isUsable()) 6455 return nullptr; 6456 // (Upper - Lower) / Step 6457 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 6458 if (!Diff.isUsable()) 6459 return nullptr; 6460 6461 return Diff.get(); 6462} 6463} // namespace 6464 6465void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 6466 assert(getLangOpts().OpenMP && "OpenMP is not active."); 6467 assert(Init && "Expected loop in canonical form."); 6468 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 6469 if (AssociatedLoops > 0 && 6470 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 6471 DSAStack->loopStart(); 6472 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 6473 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 6474 if (ValueDecl *D = ISC.getLoopDecl()) { 6475 auto *VD = dyn_cast<VarDecl>(D); 6476 DeclRefExpr *PrivateRef = nullptr; 6477 if (!VD) { 6478 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 6479 VD = Private; 6480 } else { 6481 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 6482 /*WithInit=*/false); 6483 VD = cast<VarDecl>(PrivateRef->getDecl()); 6484 } 6485 } 6486 DSAStack->addLoopControlVariable(D, VD); 6487 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 6488 if (LD != D->getCanonicalDecl()) { 6489 DSAStack->resetPossibleLoopCounter(); 6490 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 6491 MarkDeclarationsReferencedInExpr( 6492 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 6493 Var->getType().getNonLValueExprType(Context), 6494 ForLoc, /*RefersToCapture=*/true)); 6495 } 6496 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 6497 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 6498 // Referenced in a Construct, C/C++]. The loop iteration variable in the 6499 // associated for-loop of a simd construct with just one associated 6500 // for-loop may be listed in a linear clause with a constant-linear-step 6501 // that is the increment of the associated for-loop. The loop iteration 6502 // variable(s) in the associated for-loop(s) of a for or parallel for 6503 // construct may be listed in a private or lastprivate clause. 6504 DSAStackTy::DSAVarData DVar = 6505 DSAStack->getTopDSA(D, /*FromParent=*/false); 6506 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 6507 // is declared in the loop and it is predetermined as a private. 6508 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 6509 OpenMPClauseKind PredeterminedCKind = 6510 isOpenMPSimdDirective(DKind) 6511 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 6512 : OMPC_private; 6513 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6514 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 6515 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 6516 DVar.CKind != OMPC_private))) || 6517 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 6518 DKind == OMPD_master_taskloop || 6519 DKind == OMPD_parallel_master_taskloop || 6520 isOpenMPDistributeDirective(DKind)) && 6521 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 6522 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 6523 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 6524 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 6525 << getOpenMPClauseName(DVar.CKind) 6526 << getOpenMPDirectiveName(DKind) 6527 << getOpenMPClauseName(PredeterminedCKind); 6528 if (DVar.RefExpr == nullptr) 6529 DVar.CKind = PredeterminedCKind; 6530 reportOriginalDsa(*this, DSAStack, D, DVar, 6531 /*IsLoopIterVar=*/true); 6532 } else if (LoopDeclRefExpr) { 6533 // Make the loop iteration variable private (for worksharing 6534 // constructs), linear (for simd directives with the only one 6535 // associated loop) or lastprivate (for simd directives with several 6536 // collapsed or ordered loops). 6537 if (DVar.CKind == OMPC_unknown) 6538 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 6539 PrivateRef); 6540 } 6541 } 6542 } 6543 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 6544 } 6545} 6546 6547/// Called on a for stmt to check and extract its iteration space 6548/// for further processing (such as collapsing). 6549static bool checkOpenMPIterationSpace( 6550 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 6551 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 6552 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 6553 Expr *OrderedLoopCountExpr, 6554 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6555 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 6556 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6557 // OpenMP [2.9.1, Canonical Loop Form] 6558 // for (init-expr; test-expr; incr-expr) structured-block 6559 // for (range-decl: range-expr) structured-block 6560 auto *For = dyn_cast_or_null<ForStmt>(S); 6561 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 6562 // Ranged for is supported only in OpenMP 5.0. 6563 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 6564 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 6565 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 6566 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 6567 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 6568 if (TotalNestedLoopCount > 1) { 6569 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 6570 SemaRef.Diag(DSA.getConstructLoc(), 6571 diag::note_omp_collapse_ordered_expr) 6572 << 2 << CollapseLoopCountExpr->getSourceRange() 6573 << OrderedLoopCountExpr->getSourceRange(); 6574 else if (CollapseLoopCountExpr) 6575 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6576 diag::note_omp_collapse_ordered_expr) 6577 << 0 << CollapseLoopCountExpr->getSourceRange(); 6578 else 6579 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6580 diag::note_omp_collapse_ordered_expr) 6581 << 1 << OrderedLoopCountExpr->getSourceRange(); 6582 } 6583 return true; 6584 } 6585 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 6586 "No loop body."); 6587 6588 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 6589 For ? For->getForLoc() : CXXFor->getForLoc()); 6590 6591 // Check init. 6592 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 6593 if (ISC.checkAndSetInit(Init)) 6594 return true; 6595 6596 bool HasErrors = false; 6597 6598 // Check loop variable's type. 6599 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 6600 // OpenMP [2.6, Canonical Loop Form] 6601 // Var is one of the following: 6602 // A variable of signed or unsigned integer type. 6603 // For C++, a variable of a random access iterator type. 6604 // For C, a variable of a pointer type. 6605 QualType VarType = LCDecl->getType().getNonReferenceType(); 6606 if (!VarType->isDependentType() && !VarType->isIntegerType() && 6607 !VarType->isPointerType() && 6608 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 6609 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 6610 << SemaRef.getLangOpts().CPlusPlus; 6611 HasErrors = true; 6612 } 6613 6614 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 6615 // a Construct 6616 // The loop iteration variable(s) in the associated for-loop(s) of a for or 6617 // parallel for construct is (are) private. 6618 // The loop iteration variable in the associated for-loop of a simd 6619 // construct with just one associated for-loop is linear with a 6620 // constant-linear-step that is the increment of the associated for-loop. 6621 // Exclude loop var from the list of variables with implicitly defined data 6622 // sharing attributes. 6623 VarsWithImplicitDSA.erase(LCDecl); 6624 6625 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 6626 6627 // Check test-expr. 6628 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 6629 6630 // Check incr-expr. 6631 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 6632 } 6633 6634 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 6635 return HasErrors; 6636 6637 // Build the loop's iteration space representation. 6638 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 6639 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 6640 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 6641 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 6642 (isOpenMPWorksharingDirective(DKind) || 6643 isOpenMPTaskLoopDirective(DKind) || 6644 isOpenMPDistributeDirective(DKind)), 6645 Captures); 6646 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 6647 ISC.buildCounterVar(Captures, DSA); 6648 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 6649 ISC.buildPrivateCounterVar(); 6650 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 6651 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 6652 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 6653 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 6654 ISC.getConditionSrcRange(); 6655 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 6656 ISC.getIncrementSrcRange(); 6657 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 6658 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 6659 ISC.isStrictTestOp(); 6660 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 6661 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 6662 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 6663 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 6664 ISC.buildFinalCondition(DSA.getCurScope()); 6665 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 6666 ISC.doesInitDependOnLC(); 6667 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 6668 ISC.doesCondDependOnLC(); 6669 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 6670 ISC.getLoopDependentIdx(); 6671 6672 HasErrors |= 6673 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 6674 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 6675 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 6676 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 6677 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 6678 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 6679 if (!HasErrors && DSA.isOrderedRegion()) { 6680 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 6681 if (CurrentNestedLoopCount < 6682 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 6683 DSA.getOrderedRegionParam().second->setLoopNumIterations( 6684 CurrentNestedLoopCount, 6685 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 6686 DSA.getOrderedRegionParam().second->setLoopCounter( 6687 CurrentNestedLoopCount, 6688 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 6689 } 6690 } 6691 for (auto &Pair : DSA.getDoacrossDependClauses()) { 6692 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 6693 // Erroneous case - clause has some problems. 6694 continue; 6695 } 6696 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 6697 Pair.second.size() <= CurrentNestedLoopCount) { 6698 // Erroneous case - clause has some problems. 6699 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 6700 continue; 6701 } 6702 Expr *CntValue; 6703 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 6704 CntValue = ISC.buildOrderedLoopData( 6705 DSA.getCurScope(), 6706 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6707 Pair.first->getDependencyLoc()); 6708 else 6709 CntValue = ISC.buildOrderedLoopData( 6710 DSA.getCurScope(), 6711 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 6712 Pair.first->getDependencyLoc(), 6713 Pair.second[CurrentNestedLoopCount].first, 6714 Pair.second[CurrentNestedLoopCount].second); 6715 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 6716 } 6717 } 6718 6719 return HasErrors; 6720} 6721 6722/// Build 'VarRef = Start. 6723static ExprResult 6724buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6725 ExprResult Start, bool IsNonRectangularLB, 6726 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6727 // Build 'VarRef = Start. 6728 ExprResult NewStart = IsNonRectangularLB 6729 ? Start.get() 6730 : tryBuildCapture(SemaRef, Start.get(), Captures); 6731 if (!NewStart.isUsable()) 6732 return ExprError(); 6733 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 6734 VarRef.get()->getType())) { 6735 NewStart = SemaRef.PerformImplicitConversion( 6736 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 6737 /*AllowExplicit=*/true); 6738 if (!NewStart.isUsable()) 6739 return ExprError(); 6740 } 6741 6742 ExprResult Init = 6743 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6744 return Init; 6745} 6746 6747/// Build 'VarRef = Start + Iter * Step'. 6748static ExprResult buildCounterUpdate( 6749 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 6750 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 6751 bool IsNonRectangularLB, 6752 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 6753 // Add parentheses (for debugging purposes only). 6754 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 6755 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 6756 !Step.isUsable()) 6757 return ExprError(); 6758 6759 ExprResult NewStep = Step; 6760 if (Captures) 6761 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 6762 if (NewStep.isInvalid()) 6763 return ExprError(); 6764 ExprResult Update = 6765 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 6766 if (!Update.isUsable()) 6767 return ExprError(); 6768 6769 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 6770 // 'VarRef = Start (+|-) Iter * Step'. 6771 if (!Start.isUsable()) 6772 return ExprError(); 6773 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 6774 if (!NewStart.isUsable()) 6775 return ExprError(); 6776 if (Captures && !IsNonRectangularLB) 6777 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 6778 if (NewStart.isInvalid()) 6779 return ExprError(); 6780 6781 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 6782 ExprResult SavedUpdate = Update; 6783 ExprResult UpdateVal; 6784 if (VarRef.get()->getType()->isOverloadableType() || 6785 NewStart.get()->getType()->isOverloadableType() || 6786 Update.get()->getType()->isOverloadableType()) { 6787 Sema::TentativeAnalysisScope Trap(SemaRef); 6788 6789 Update = 6790 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 6791 if (Update.isUsable()) { 6792 UpdateVal = 6793 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 6794 VarRef.get(), SavedUpdate.get()); 6795 if (UpdateVal.isUsable()) { 6796 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 6797 UpdateVal.get()); 6798 } 6799 } 6800 } 6801 6802 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 6803 if (!Update.isUsable() || !UpdateVal.isUsable()) { 6804 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 6805 NewStart.get(), SavedUpdate.get()); 6806 if (!Update.isUsable()) 6807 return ExprError(); 6808 6809 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 6810 VarRef.get()->getType())) { 6811 Update = SemaRef.PerformImplicitConversion( 6812 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 6813 if (!Update.isUsable()) 6814 return ExprError(); 6815 } 6816 6817 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 6818 } 6819 return Update; 6820} 6821 6822/// Convert integer expression \a E to make it have at least \a Bits 6823/// bits. 6824static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 6825 if (E == nullptr) 6826 return ExprError(); 6827 ASTContext &C = SemaRef.Context; 6828 QualType OldType = E->getType(); 6829 unsigned HasBits = C.getTypeSize(OldType); 6830 if (HasBits >= Bits) 6831 return ExprResult(E); 6832 // OK to convert to signed, because new type has more bits than old. 6833 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 6834 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 6835 true); 6836} 6837 6838/// Check if the given expression \a E is a constant integer that fits 6839/// into \a Bits bits. 6840static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 6841 if (E == nullptr) 6842 return false; 6843 llvm::APSInt Result; 6844 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 6845 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 6846 return false; 6847} 6848 6849/// Build preinits statement for the given declarations. 6850static Stmt *buildPreInits(ASTContext &Context, 6851 MutableArrayRef<Decl *> PreInits) { 6852 if (!PreInits.empty()) { 6853 return new (Context) DeclStmt( 6854 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 6855 SourceLocation(), SourceLocation()); 6856 } 6857 return nullptr; 6858} 6859 6860/// Build preinits statement for the given declarations. 6861static Stmt * 6862buildPreInits(ASTContext &Context, 6863 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6864 if (!Captures.empty()) { 6865 SmallVector<Decl *, 16> PreInits; 6866 for (const auto &Pair : Captures) 6867 PreInits.push_back(Pair.second->getDecl()); 6868 return buildPreInits(Context, PreInits); 6869 } 6870 return nullptr; 6871} 6872 6873/// Build postupdate expression for the given list of postupdates expressions. 6874static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 6875 Expr *PostUpdate = nullptr; 6876 if (!PostUpdates.empty()) { 6877 for (Expr *E : PostUpdates) { 6878 Expr *ConvE = S.BuildCStyleCastExpr( 6879 E->getExprLoc(), 6880 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 6881 E->getExprLoc(), E) 6882 .get(); 6883 PostUpdate = PostUpdate 6884 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 6885 PostUpdate, ConvE) 6886 .get() 6887 : ConvE; 6888 } 6889 } 6890 return PostUpdate; 6891} 6892 6893/// Called on a for stmt to check itself and nested loops (if any). 6894/// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 6895/// number of collapsed loops otherwise. 6896static unsigned 6897checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 6898 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 6899 DSAStackTy &DSA, 6900 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 6901 OMPLoopDirective::HelperExprs &Built) { 6902 unsigned NestedLoopCount = 1; 6903 if (CollapseLoopCountExpr) { 6904 // Found 'collapse' clause - calculate collapse number. 6905 Expr::EvalResult Result; 6906 if (!CollapseLoopCountExpr->isValueDependent() && 6907 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 6908 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 6909 } else { 6910 Built.clear(/*Size=*/1); 6911 return 1; 6912 } 6913 } 6914 unsigned OrderedLoopCount = 1; 6915 if (OrderedLoopCountExpr) { 6916 // Found 'ordered' clause - calculate collapse number. 6917 Expr::EvalResult EVResult; 6918 if (!OrderedLoopCountExpr->isValueDependent() && 6919 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 6920 SemaRef.getASTContext())) { 6921 llvm::APSInt Result = EVResult.Val.getInt(); 6922 if (Result.getLimitedValue() < NestedLoopCount) { 6923 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 6924 diag::err_omp_wrong_ordered_loop_count) 6925 << OrderedLoopCountExpr->getSourceRange(); 6926 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 6927 diag::note_collapse_loop_count) 6928 << CollapseLoopCountExpr->getSourceRange(); 6929 } 6930 OrderedLoopCount = Result.getLimitedValue(); 6931 } else { 6932 Built.clear(/*Size=*/1); 6933 return 1; 6934 } 6935 } 6936 // This is helper routine for loop directives (e.g., 'for', 'simd', 6937 // 'for simd', etc.). 6938 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 6939 SmallVector<LoopIterationSpace, 4> IterSpaces( 6940 std::max(OrderedLoopCount, NestedLoopCount)); 6941 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 6942 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 6943 if (checkOpenMPIterationSpace( 6944 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6945 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6946 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6947 return 0; 6948 // Move on to the next nested for loop, or to the loop body. 6949 // OpenMP [2.8.1, simd construct, Restrictions] 6950 // All loops associated with the construct must be perfectly nested; that 6951 // is, there must be no intervening code nor any OpenMP directive between 6952 // any two loops. 6953 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6954 CurStmt = For->getBody(); 6955 } else { 6956 assert(isa<CXXForRangeStmt>(CurStmt) && 6957 "Expected canonical for or range-based for loops."); 6958 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6959 } 6960 CurStmt = CurStmt->IgnoreContainers(); 6961 } 6962 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 6963 if (checkOpenMPIterationSpace( 6964 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 6965 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 6966 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 6967 return 0; 6968 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 6969 // Handle initialization of captured loop iterator variables. 6970 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 6971 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 6972 Captures[DRE] = DRE; 6973 } 6974 } 6975 // Move on to the next nested for loop, or to the loop body. 6976 // OpenMP [2.8.1, simd construct, Restrictions] 6977 // All loops associated with the construct must be perfectly nested; that 6978 // is, there must be no intervening code nor any OpenMP directive between 6979 // any two loops. 6980 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 6981 CurStmt = For->getBody(); 6982 } else { 6983 assert(isa<CXXForRangeStmt>(CurStmt) && 6984 "Expected canonical for or range-based for loops."); 6985 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 6986 } 6987 CurStmt = CurStmt->IgnoreContainers(); 6988 } 6989 6990 Built.clear(/* size */ NestedLoopCount); 6991 6992 if (SemaRef.CurContext->isDependentContext()) 6993 return NestedLoopCount; 6994 6995 // An example of what is generated for the following code: 6996 // 6997 // #pragma omp simd collapse(2) ordered(2) 6998 // for (i = 0; i < NI; ++i) 6999 // for (k = 0; k < NK; ++k) 7000 // for (j = J0; j < NJ; j+=2) { 7001 // <loop body> 7002 // } 7003 // 7004 // We generate the code below. 7005 // Note: the loop body may be outlined in CodeGen. 7006 // Note: some counters may be C++ classes, operator- is used to find number of 7007 // iterations and operator+= to calculate counter value. 7008 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7009 // or i64 is currently supported). 7010 // 7011 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7012 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7013 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7014 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7015 // // similar updates for vars in clauses (e.g. 'linear') 7016 // <loop body (using local i and j)> 7017 // } 7018 // i = NI; // assign final values of counters 7019 // j = NJ; 7020 // 7021 7022 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7023 // the iteration counts of the collapsed for loops. 7024 // Precondition tests if there is at least one iteration (all conditions are 7025 // true). 7026 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7027 Expr *N0 = IterSpaces[0].NumIterations; 7028 ExprResult LastIteration32 = 7029 widenIterationCount(/*Bits=*/32, 7030 SemaRef 7031 .PerformImplicitConversion( 7032 N0->IgnoreImpCasts(), N0->getType(), 7033 Sema::AA_Converting, /*AllowExplicit=*/true) 7034 .get(), 7035 SemaRef); 7036 ExprResult LastIteration64 = widenIterationCount( 7037 /*Bits=*/64, 7038 SemaRef 7039 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7040 Sema::AA_Converting, 7041 /*AllowExplicit=*/true) 7042 .get(), 7043 SemaRef); 7044 7045 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7046 return NestedLoopCount; 7047 7048 ASTContext &C = SemaRef.Context; 7049 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7050 7051 Scope *CurScope = DSA.getCurScope(); 7052 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7053 if (PreCond.isUsable()) { 7054 PreCond = 7055 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7056 PreCond.get(), IterSpaces[Cnt].PreCond); 7057 } 7058 Expr *N = IterSpaces[Cnt].NumIterations; 7059 SourceLocation Loc = N->getExprLoc(); 7060 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7061 if (LastIteration32.isUsable()) 7062 LastIteration32 = SemaRef.BuildBinOp( 7063 CurScope, Loc, BO_Mul, LastIteration32.get(), 7064 SemaRef 7065 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7066 Sema::AA_Converting, 7067 /*AllowExplicit=*/true) 7068 .get()); 7069 if (LastIteration64.isUsable()) 7070 LastIteration64 = SemaRef.BuildBinOp( 7071 CurScope, Loc, BO_Mul, LastIteration64.get(), 7072 SemaRef 7073 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7074 Sema::AA_Converting, 7075 /*AllowExplicit=*/true) 7076 .get()); 7077 } 7078 7079 // Choose either the 32-bit or 64-bit version. 7080 ExprResult LastIteration = LastIteration64; 7081 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 7082 (LastIteration32.isUsable() && 7083 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 7084 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 7085 fitsInto( 7086 /*Bits=*/32, 7087 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 7088 LastIteration64.get(), SemaRef)))) 7089 LastIteration = LastIteration32; 7090 QualType VType = LastIteration.get()->getType(); 7091 QualType RealVType = VType; 7092 QualType StrideVType = VType; 7093 if (isOpenMPTaskLoopDirective(DKind)) { 7094 VType = 7095 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 7096 StrideVType = 7097 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 7098 } 7099 7100 if (!LastIteration.isUsable()) 7101 return 0; 7102 7103 // Save the number of iterations. 7104 ExprResult NumIterations = LastIteration; 7105 { 7106 LastIteration = SemaRef.BuildBinOp( 7107 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 7108 LastIteration.get(), 7109 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7110 if (!LastIteration.isUsable()) 7111 return 0; 7112 } 7113 7114 // Calculate the last iteration number beforehand instead of doing this on 7115 // each iteration. Do not do this if the number of iterations may be kfold-ed. 7116 llvm::APSInt Result; 7117 bool IsConstant = 7118 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 7119 ExprResult CalcLastIteration; 7120 if (!IsConstant) { 7121 ExprResult SaveRef = 7122 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 7123 LastIteration = SaveRef; 7124 7125 // Prepare SaveRef + 1. 7126 NumIterations = SemaRef.BuildBinOp( 7127 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 7128 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7129 if (!NumIterations.isUsable()) 7130 return 0; 7131 } 7132 7133 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 7134 7135 // Build variables passed into runtime, necessary for worksharing directives. 7136 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 7137 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7138 isOpenMPDistributeDirective(DKind)) { 7139 // Lower bound variable, initialized with zero. 7140 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 7141 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 7142 SemaRef.AddInitializerToDecl(LBDecl, 7143 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7144 /*DirectInit*/ false); 7145 7146 // Upper bound variable, initialized with last iteration number. 7147 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 7148 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 7149 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 7150 /*DirectInit*/ false); 7151 7152 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 7153 // This will be used to implement clause 'lastprivate'. 7154 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 7155 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 7156 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 7157 SemaRef.AddInitializerToDecl(ILDecl, 7158 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7159 /*DirectInit*/ false); 7160 7161 // Stride variable returned by runtime (we initialize it to 1 by default). 7162 VarDecl *STDecl = 7163 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 7164 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 7165 SemaRef.AddInitializerToDecl(STDecl, 7166 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 7167 /*DirectInit*/ false); 7168 7169 // Build expression: UB = min(UB, LastIteration) 7170 // It is necessary for CodeGen of directives with static scheduling. 7171 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 7172 UB.get(), LastIteration.get()); 7173 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7174 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 7175 LastIteration.get(), UB.get()); 7176 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 7177 CondOp.get()); 7178 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 7179 7180 // If we have a combined directive that combines 'distribute', 'for' or 7181 // 'simd' we need to be able to access the bounds of the schedule of the 7182 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 7183 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 7184 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7185 // Lower bound variable, initialized with zero. 7186 VarDecl *CombLBDecl = 7187 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 7188 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 7189 SemaRef.AddInitializerToDecl( 7190 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 7191 /*DirectInit*/ false); 7192 7193 // Upper bound variable, initialized with last iteration number. 7194 VarDecl *CombUBDecl = 7195 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 7196 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 7197 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 7198 /*DirectInit*/ false); 7199 7200 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 7201 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 7202 ExprResult CombCondOp = 7203 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 7204 LastIteration.get(), CombUB.get()); 7205 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 7206 CombCondOp.get()); 7207 CombEUB = 7208 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 7209 7210 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 7211 // We expect to have at least 2 more parameters than the 'parallel' 7212 // directive does - the lower and upper bounds of the previous schedule. 7213 assert(CD->getNumParams() >= 4 && 7214 "Unexpected number of parameters in loop combined directive"); 7215 7216 // Set the proper type for the bounds given what we learned from the 7217 // enclosed loops. 7218 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 7219 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 7220 7221 // Previous lower and upper bounds are obtained from the region 7222 // parameters. 7223 PrevLB = 7224 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 7225 PrevUB = 7226 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 7227 } 7228 } 7229 7230 // Build the iteration variable and its initialization before loop. 7231 ExprResult IV; 7232 ExprResult Init, CombInit; 7233 { 7234 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 7235 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 7236 Expr *RHS = 7237 (isOpenMPWorksharingDirective(DKind) || 7238 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7239 ? LB.get() 7240 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7241 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 7242 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 7243 7244 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7245 Expr *CombRHS = 7246 (isOpenMPWorksharingDirective(DKind) || 7247 isOpenMPTaskLoopDirective(DKind) || 7248 isOpenMPDistributeDirective(DKind)) 7249 ? CombLB.get() 7250 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 7251 CombInit = 7252 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 7253 CombInit = 7254 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 7255 } 7256 } 7257 7258 bool UseStrictCompare = 7259 RealVType->hasUnsignedIntegerRepresentation() && 7260 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 7261 return LIS.IsStrictCompare; 7262 }); 7263 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 7264 // unsigned IV)) for worksharing loops. 7265 SourceLocation CondLoc = AStmt->getBeginLoc(); 7266 Expr *BoundUB = UB.get(); 7267 if (UseStrictCompare) { 7268 BoundUB = 7269 SemaRef 7270 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 7271 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7272 .get(); 7273 BoundUB = 7274 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 7275 } 7276 ExprResult Cond = 7277 (isOpenMPWorksharingDirective(DKind) || 7278 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 7279 ? SemaRef.BuildBinOp(CurScope, CondLoc, 7280 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 7281 BoundUB) 7282 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7283 NumIterations.get()); 7284 ExprResult CombDistCond; 7285 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7286 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 7287 NumIterations.get()); 7288 } 7289 7290 ExprResult CombCond; 7291 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7292 Expr *BoundCombUB = CombUB.get(); 7293 if (UseStrictCompare) { 7294 BoundCombUB = 7295 SemaRef 7296 .BuildBinOp( 7297 CurScope, CondLoc, BO_Add, BoundCombUB, 7298 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7299 .get(); 7300 BoundCombUB = 7301 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 7302 .get(); 7303 } 7304 CombCond = 7305 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7306 IV.get(), BoundCombUB); 7307 } 7308 // Loop increment (IV = IV + 1) 7309 SourceLocation IncLoc = AStmt->getBeginLoc(); 7310 ExprResult Inc = 7311 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 7312 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 7313 if (!Inc.isUsable()) 7314 return 0; 7315 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 7316 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 7317 if (!Inc.isUsable()) 7318 return 0; 7319 7320 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 7321 // Used for directives with static scheduling. 7322 // In combined construct, add combined version that use CombLB and CombUB 7323 // base variables for the update 7324 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 7325 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 7326 isOpenMPDistributeDirective(DKind)) { 7327 // LB + ST 7328 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 7329 if (!NextLB.isUsable()) 7330 return 0; 7331 // LB = LB + ST 7332 NextLB = 7333 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 7334 NextLB = 7335 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 7336 if (!NextLB.isUsable()) 7337 return 0; 7338 // UB + ST 7339 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 7340 if (!NextUB.isUsable()) 7341 return 0; 7342 // UB = UB + ST 7343 NextUB = 7344 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 7345 NextUB = 7346 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 7347 if (!NextUB.isUsable()) 7348 return 0; 7349 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7350 CombNextLB = 7351 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 7352 if (!NextLB.isUsable()) 7353 return 0; 7354 // LB = LB + ST 7355 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 7356 CombNextLB.get()); 7357 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 7358 /*DiscardedValue*/ false); 7359 if (!CombNextLB.isUsable()) 7360 return 0; 7361 // UB + ST 7362 CombNextUB = 7363 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 7364 if (!CombNextUB.isUsable()) 7365 return 0; 7366 // UB = UB + ST 7367 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 7368 CombNextUB.get()); 7369 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 7370 /*DiscardedValue*/ false); 7371 if (!CombNextUB.isUsable()) 7372 return 0; 7373 } 7374 } 7375 7376 // Create increment expression for distribute loop when combined in a same 7377 // directive with for as IV = IV + ST; ensure upper bound expression based 7378 // on PrevUB instead of NumIterations - used to implement 'for' when found 7379 // in combination with 'distribute', like in 'distribute parallel for' 7380 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 7381 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 7382 if (isOpenMPLoopBoundSharingDirective(DKind)) { 7383 DistCond = SemaRef.BuildBinOp( 7384 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 7385 assert(DistCond.isUsable() && "distribute cond expr was not built"); 7386 7387 DistInc = 7388 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 7389 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7390 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 7391 DistInc.get()); 7392 DistInc = 7393 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 7394 assert(DistInc.isUsable() && "distribute inc expr was not built"); 7395 7396 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 7397 // construct 7398 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 7399 ExprResult IsUBGreater = 7400 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 7401 ExprResult CondOp = SemaRef.ActOnConditionalOp( 7402 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 7403 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 7404 CondOp.get()); 7405 PrevEUB = 7406 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 7407 7408 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 7409 // parallel for is in combination with a distribute directive with 7410 // schedule(static, 1) 7411 Expr *BoundPrevUB = PrevUB.get(); 7412 if (UseStrictCompare) { 7413 BoundPrevUB = 7414 SemaRef 7415 .BuildBinOp( 7416 CurScope, CondLoc, BO_Add, BoundPrevUB, 7417 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 7418 .get(); 7419 BoundPrevUB = 7420 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 7421 .get(); 7422 } 7423 ParForInDistCond = 7424 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 7425 IV.get(), BoundPrevUB); 7426 } 7427 7428 // Build updates and final values of the loop counters. 7429 bool HasErrors = false; 7430 Built.Counters.resize(NestedLoopCount); 7431 Built.Inits.resize(NestedLoopCount); 7432 Built.Updates.resize(NestedLoopCount); 7433 Built.Finals.resize(NestedLoopCount); 7434 Built.DependentCounters.resize(NestedLoopCount); 7435 Built.DependentInits.resize(NestedLoopCount); 7436 Built.FinalsConditions.resize(NestedLoopCount); 7437 { 7438 // We implement the following algorithm for obtaining the 7439 // original loop iteration variable values based on the 7440 // value of the collapsed loop iteration variable IV. 7441 // 7442 // Let n+1 be the number of collapsed loops in the nest. 7443 // Iteration variables (I0, I1, .... In) 7444 // Iteration counts (N0, N1, ... Nn) 7445 // 7446 // Acc = IV; 7447 // 7448 // To compute Ik for loop k, 0 <= k <= n, generate: 7449 // Prod = N(k+1) * N(k+2) * ... * Nn; 7450 // Ik = Acc / Prod; 7451 // Acc -= Ik * Prod; 7452 // 7453 ExprResult Acc = IV; 7454 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7455 LoopIterationSpace &IS = IterSpaces[Cnt]; 7456 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 7457 ExprResult Iter; 7458 7459 // Compute prod 7460 ExprResult Prod = 7461 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 7462 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 7463 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 7464 IterSpaces[K].NumIterations); 7465 7466 // Iter = Acc / Prod 7467 // If there is at least one more inner loop to avoid 7468 // multiplication by 1. 7469 if (Cnt + 1 < NestedLoopCount) 7470 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 7471 Acc.get(), Prod.get()); 7472 else 7473 Iter = Acc; 7474 if (!Iter.isUsable()) { 7475 HasErrors = true; 7476 break; 7477 } 7478 7479 // Update Acc: 7480 // Acc -= Iter * Prod 7481 // Check if there is at least one more inner loop to avoid 7482 // multiplication by 1. 7483 if (Cnt + 1 < NestedLoopCount) 7484 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 7485 Iter.get(), Prod.get()); 7486 else 7487 Prod = Iter; 7488 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 7489 Acc.get(), Prod.get()); 7490 7491 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 7492 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 7493 DeclRefExpr *CounterVar = buildDeclRefExpr( 7494 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 7495 /*RefersToCapture=*/true); 7496 ExprResult Init = 7497 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 7498 IS.CounterInit, IS.IsNonRectangularLB, Captures); 7499 if (!Init.isUsable()) { 7500 HasErrors = true; 7501 break; 7502 } 7503 ExprResult Update = buildCounterUpdate( 7504 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 7505 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 7506 if (!Update.isUsable()) { 7507 HasErrors = true; 7508 break; 7509 } 7510 7511 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 7512 ExprResult Final = 7513 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 7514 IS.CounterInit, IS.NumIterations, IS.CounterStep, 7515 IS.Subtract, IS.IsNonRectangularLB, &Captures); 7516 if (!Final.isUsable()) { 7517 HasErrors = true; 7518 break; 7519 } 7520 7521 if (!Update.isUsable() || !Final.isUsable()) { 7522 HasErrors = true; 7523 break; 7524 } 7525 // Save results 7526 Built.Counters[Cnt] = IS.CounterVar; 7527 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 7528 Built.Inits[Cnt] = Init.get(); 7529 Built.Updates[Cnt] = Update.get(); 7530 Built.Finals[Cnt] = Final.get(); 7531 Built.DependentCounters[Cnt] = nullptr; 7532 Built.DependentInits[Cnt] = nullptr; 7533 Built.FinalsConditions[Cnt] = nullptr; 7534 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 7535 Built.DependentCounters[Cnt] = 7536 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7537 Built.DependentInits[Cnt] = 7538 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 7539 Built.FinalsConditions[Cnt] = IS.FinalCondition; 7540 } 7541 } 7542 } 7543 7544 if (HasErrors) 7545 return 0; 7546 7547 // Save results 7548 Built.IterationVarRef = IV.get(); 7549 Built.LastIteration = LastIteration.get(); 7550 Built.NumIterations = NumIterations.get(); 7551 Built.CalcLastIteration = SemaRef 7552 .ActOnFinishFullExpr(CalcLastIteration.get(), 7553 /*DiscardedValue=*/false) 7554 .get(); 7555 Built.PreCond = PreCond.get(); 7556 Built.PreInits = buildPreInits(C, Captures); 7557 Built.Cond = Cond.get(); 7558 Built.Init = Init.get(); 7559 Built.Inc = Inc.get(); 7560 Built.LB = LB.get(); 7561 Built.UB = UB.get(); 7562 Built.IL = IL.get(); 7563 Built.ST = ST.get(); 7564 Built.EUB = EUB.get(); 7565 Built.NLB = NextLB.get(); 7566 Built.NUB = NextUB.get(); 7567 Built.PrevLB = PrevLB.get(); 7568 Built.PrevUB = PrevUB.get(); 7569 Built.DistInc = DistInc.get(); 7570 Built.PrevEUB = PrevEUB.get(); 7571 Built.DistCombinedFields.LB = CombLB.get(); 7572 Built.DistCombinedFields.UB = CombUB.get(); 7573 Built.DistCombinedFields.EUB = CombEUB.get(); 7574 Built.DistCombinedFields.Init = CombInit.get(); 7575 Built.DistCombinedFields.Cond = CombCond.get(); 7576 Built.DistCombinedFields.NLB = CombNextLB.get(); 7577 Built.DistCombinedFields.NUB = CombNextUB.get(); 7578 Built.DistCombinedFields.DistCond = CombDistCond.get(); 7579 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 7580 7581 return NestedLoopCount; 7582} 7583 7584static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 7585 auto CollapseClauses = 7586 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 7587 if (CollapseClauses.begin() != CollapseClauses.end()) 7588 return (*CollapseClauses.begin())->getNumForLoops(); 7589 return nullptr; 7590} 7591 7592static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 7593 auto OrderedClauses = 7594 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 7595 if (OrderedClauses.begin() != OrderedClauses.end()) 7596 return (*OrderedClauses.begin())->getNumForLoops(); 7597 return nullptr; 7598} 7599 7600static bool checkSimdlenSafelenSpecified(Sema &S, 7601 const ArrayRef<OMPClause *> Clauses) { 7602 const OMPSafelenClause *Safelen = nullptr; 7603 const OMPSimdlenClause *Simdlen = nullptr; 7604 7605 for (const OMPClause *Clause : Clauses) { 7606 if (Clause->getClauseKind() == OMPC_safelen) 7607 Safelen = cast<OMPSafelenClause>(Clause); 7608 else if (Clause->getClauseKind() == OMPC_simdlen) 7609 Simdlen = cast<OMPSimdlenClause>(Clause); 7610 if (Safelen && Simdlen) 7611 break; 7612 } 7613 7614 if (Simdlen && Safelen) { 7615 const Expr *SimdlenLength = Simdlen->getSimdlen(); 7616 const Expr *SafelenLength = Safelen->getSafelen(); 7617 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 7618 SimdlenLength->isInstantiationDependent() || 7619 SimdlenLength->containsUnexpandedParameterPack()) 7620 return false; 7621 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 7622 SafelenLength->isInstantiationDependent() || 7623 SafelenLength->containsUnexpandedParameterPack()) 7624 return false; 7625 Expr::EvalResult SimdlenResult, SafelenResult; 7626 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 7627 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 7628 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 7629 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 7630 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 7631 // If both simdlen and safelen clauses are specified, the value of the 7632 // simdlen parameter must be less than or equal to the value of the safelen 7633 // parameter. 7634 if (SimdlenRes > SafelenRes) { 7635 S.Diag(SimdlenLength->getExprLoc(), 7636 diag::err_omp_wrong_simdlen_safelen_values) 7637 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 7638 return true; 7639 } 7640 } 7641 return false; 7642} 7643 7644StmtResult 7645Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7646 SourceLocation StartLoc, SourceLocation EndLoc, 7647 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7648 if (!AStmt) 7649 return StmtError(); 7650 7651 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7652 OMPLoopDirective::HelperExprs B; 7653 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7654 // define the nested loops number. 7655 unsigned NestedLoopCount = checkOpenMPLoop( 7656 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7657 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7658 if (NestedLoopCount == 0) 7659 return StmtError(); 7660 7661 assert((CurContext->isDependentContext() || B.builtAll()) && 7662 "omp simd loop exprs were not built"); 7663 7664 if (!CurContext->isDependentContext()) { 7665 // Finalize the clauses that need pre-built expressions for CodeGen. 7666 for (OMPClause *C : Clauses) { 7667 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7668 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7669 B.NumIterations, *this, CurScope, 7670 DSAStack)) 7671 return StmtError(); 7672 } 7673 } 7674 7675 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7676 return StmtError(); 7677 7678 setFunctionHasBranchProtectedScope(); 7679 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7680 Clauses, AStmt, B); 7681} 7682 7683StmtResult 7684Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 7685 SourceLocation StartLoc, SourceLocation EndLoc, 7686 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7687 if (!AStmt) 7688 return StmtError(); 7689 7690 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7691 OMPLoopDirective::HelperExprs B; 7692 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7693 // define the nested loops number. 7694 unsigned NestedLoopCount = checkOpenMPLoop( 7695 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 7696 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 7697 if (NestedLoopCount == 0) 7698 return StmtError(); 7699 7700 assert((CurContext->isDependentContext() || B.builtAll()) && 7701 "omp for loop exprs were not built"); 7702 7703 if (!CurContext->isDependentContext()) { 7704 // Finalize the clauses that need pre-built expressions for CodeGen. 7705 for (OMPClause *C : Clauses) { 7706 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7708 B.NumIterations, *this, CurScope, 7709 DSAStack)) 7710 return StmtError(); 7711 } 7712 } 7713 7714 setFunctionHasBranchProtectedScope(); 7715 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7716 Clauses, AStmt, B, DSAStack->isCancelRegion()); 7717} 7718 7719StmtResult Sema::ActOnOpenMPForSimdDirective( 7720 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7721 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7722 if (!AStmt) 7723 return StmtError(); 7724 7725 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7726 OMPLoopDirective::HelperExprs B; 7727 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7728 // define the nested loops number. 7729 unsigned NestedLoopCount = 7730 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 7731 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7732 VarsWithImplicitDSA, B); 7733 if (NestedLoopCount == 0) 7734 return StmtError(); 7735 7736 assert((CurContext->isDependentContext() || B.builtAll()) && 7737 "omp for simd loop exprs were not built"); 7738 7739 if (!CurContext->isDependentContext()) { 7740 // Finalize the clauses that need pre-built expressions for CodeGen. 7741 for (OMPClause *C : Clauses) { 7742 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7743 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7744 B.NumIterations, *this, CurScope, 7745 DSAStack)) 7746 return StmtError(); 7747 } 7748 } 7749 7750 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7751 return StmtError(); 7752 7753 setFunctionHasBranchProtectedScope(); 7754 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 7755 Clauses, AStmt, B); 7756} 7757 7758StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 7759 Stmt *AStmt, 7760 SourceLocation StartLoc, 7761 SourceLocation EndLoc) { 7762 if (!AStmt) 7763 return StmtError(); 7764 7765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7766 auto BaseStmt = AStmt; 7767 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 7768 BaseStmt = CS->getCapturedStmt(); 7769 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 7770 auto S = C->children(); 7771 if (S.begin() == S.end()) 7772 return StmtError(); 7773 // All associated statements must be '#pragma omp section' except for 7774 // the first one. 7775 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 7776 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 7777 if (SectionStmt) 7778 Diag(SectionStmt->getBeginLoc(), 7779 diag::err_omp_sections_substmt_not_section); 7780 return StmtError(); 7781 } 7782 cast<OMPSectionDirective>(SectionStmt) 7783 ->setHasCancel(DSAStack->isCancelRegion()); 7784 } 7785 } else { 7786 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 7787 return StmtError(); 7788 } 7789 7790 setFunctionHasBranchProtectedScope(); 7791 7792 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7793 DSAStack->isCancelRegion()); 7794} 7795 7796StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 7797 SourceLocation StartLoc, 7798 SourceLocation EndLoc) { 7799 if (!AStmt) 7800 return StmtError(); 7801 7802 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7803 7804 setFunctionHasBranchProtectedScope(); 7805 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 7806 7807 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 7808 DSAStack->isCancelRegion()); 7809} 7810 7811StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 7812 Stmt *AStmt, 7813 SourceLocation StartLoc, 7814 SourceLocation EndLoc) { 7815 if (!AStmt) 7816 return StmtError(); 7817 7818 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7819 7820 setFunctionHasBranchProtectedScope(); 7821 7822 // OpenMP [2.7.3, single Construct, Restrictions] 7823 // The copyprivate clause must not be used with the nowait clause. 7824 const OMPClause *Nowait = nullptr; 7825 const OMPClause *Copyprivate = nullptr; 7826 for (const OMPClause *Clause : Clauses) { 7827 if (Clause->getClauseKind() == OMPC_nowait) 7828 Nowait = Clause; 7829 else if (Clause->getClauseKind() == OMPC_copyprivate) 7830 Copyprivate = Clause; 7831 if (Copyprivate && Nowait) { 7832 Diag(Copyprivate->getBeginLoc(), 7833 diag::err_omp_single_copyprivate_with_nowait); 7834 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 7835 return StmtError(); 7836 } 7837 } 7838 7839 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7840} 7841 7842StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 7843 SourceLocation StartLoc, 7844 SourceLocation EndLoc) { 7845 if (!AStmt) 7846 return StmtError(); 7847 7848 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7849 7850 setFunctionHasBranchProtectedScope(); 7851 7852 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 7853} 7854 7855StmtResult Sema::ActOnOpenMPCriticalDirective( 7856 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 7857 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 7858 if (!AStmt) 7859 return StmtError(); 7860 7861 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7862 7863 bool ErrorFound = false; 7864 llvm::APSInt Hint; 7865 SourceLocation HintLoc; 7866 bool DependentHint = false; 7867 for (const OMPClause *C : Clauses) { 7868 if (C->getClauseKind() == OMPC_hint) { 7869 if (!DirName.getName()) { 7870 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 7871 ErrorFound = true; 7872 } 7873 Expr *E = cast<OMPHintClause>(C)->getHint(); 7874 if (E->isTypeDependent() || E->isValueDependent() || 7875 E->isInstantiationDependent()) { 7876 DependentHint = true; 7877 } else { 7878 Hint = E->EvaluateKnownConstInt(Context); 7879 HintLoc = C->getBeginLoc(); 7880 } 7881 } 7882 } 7883 if (ErrorFound) 7884 return StmtError(); 7885 const auto Pair = DSAStack->getCriticalWithHint(DirName); 7886 if (Pair.first && DirName.getName() && !DependentHint) { 7887 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 7888 Diag(StartLoc, diag::err_omp_critical_with_hint); 7889 if (HintLoc.isValid()) 7890 Diag(HintLoc, diag::note_omp_critical_hint_here) 7891 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 7892 else 7893 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 7894 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 7895 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 7896 << 1 7897 << C->getHint()->EvaluateKnownConstInt(Context).toString( 7898 /*Radix=*/10, /*Signed=*/false); 7899 } else { 7900 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 7901 } 7902 } 7903 } 7904 7905 setFunctionHasBranchProtectedScope(); 7906 7907 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 7908 Clauses, AStmt); 7909 if (!Pair.first && DirName.getName() && !DependentHint) 7910 DSAStack->addCriticalWithHint(Dir, Hint); 7911 return Dir; 7912} 7913 7914StmtResult Sema::ActOnOpenMPParallelForDirective( 7915 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7916 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7917 if (!AStmt) 7918 return StmtError(); 7919 7920 auto *CS = cast<CapturedStmt>(AStmt); 7921 // 1.2.2 OpenMP Language Terminology 7922 // Structured block - An executable statement with a single entry at the 7923 // top and a single exit at the bottom. 7924 // The point of exit cannot be a branch out of the structured block. 7925 // longjmp() and throw() must not violate the entry/exit criteria. 7926 CS->getCapturedDecl()->setNothrow(); 7927 7928 OMPLoopDirective::HelperExprs B; 7929 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7930 // define the nested loops number. 7931 unsigned NestedLoopCount = 7932 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 7933 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7934 VarsWithImplicitDSA, B); 7935 if (NestedLoopCount == 0) 7936 return StmtError(); 7937 7938 assert((CurContext->isDependentContext() || B.builtAll()) && 7939 "omp parallel for loop exprs were not built"); 7940 7941 if (!CurContext->isDependentContext()) { 7942 // Finalize the clauses that need pre-built expressions for CodeGen. 7943 for (OMPClause *C : Clauses) { 7944 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7946 B.NumIterations, *this, CurScope, 7947 DSAStack)) 7948 return StmtError(); 7949 } 7950 } 7951 7952 setFunctionHasBranchProtectedScope(); 7953 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 7954 NestedLoopCount, Clauses, AStmt, B, 7955 DSAStack->isCancelRegion()); 7956} 7957 7958StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 7959 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7960 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7961 if (!AStmt) 7962 return StmtError(); 7963 7964 auto *CS = cast<CapturedStmt>(AStmt); 7965 // 1.2.2 OpenMP Language Terminology 7966 // Structured block - An executable statement with a single entry at the 7967 // top and a single exit at the bottom. 7968 // The point of exit cannot be a branch out of the structured block. 7969 // longjmp() and throw() must not violate the entry/exit criteria. 7970 CS->getCapturedDecl()->setNothrow(); 7971 7972 OMPLoopDirective::HelperExprs B; 7973 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7974 // define the nested loops number. 7975 unsigned NestedLoopCount = 7976 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 7977 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7978 VarsWithImplicitDSA, B); 7979 if (NestedLoopCount == 0) 7980 return StmtError(); 7981 7982 if (!CurContext->isDependentContext()) { 7983 // Finalize the clauses that need pre-built expressions for CodeGen. 7984 for (OMPClause *C : Clauses) { 7985 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7986 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7987 B.NumIterations, *this, CurScope, 7988 DSAStack)) 7989 return StmtError(); 7990 } 7991 } 7992 7993 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7994 return StmtError(); 7995 7996 setFunctionHasBranchProtectedScope(); 7997 return OMPParallelForSimdDirective::Create( 7998 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7999} 8000 8001StmtResult 8002Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8003 Stmt *AStmt, SourceLocation StartLoc, 8004 SourceLocation EndLoc) { 8005 if (!AStmt) 8006 return StmtError(); 8007 8008 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8009 auto BaseStmt = AStmt; 8010 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8011 BaseStmt = CS->getCapturedStmt(); 8012 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8013 auto S = C->children(); 8014 if (S.begin() == S.end()) 8015 return StmtError(); 8016 // All associated statements must be '#pragma omp section' except for 8017 // the first one. 8018 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8019 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8020 if (SectionStmt) 8021 Diag(SectionStmt->getBeginLoc(), 8022 diag::err_omp_parallel_sections_substmt_not_section); 8023 return StmtError(); 8024 } 8025 cast<OMPSectionDirective>(SectionStmt) 8026 ->setHasCancel(DSAStack->isCancelRegion()); 8027 } 8028 } else { 8029 Diag(AStmt->getBeginLoc(), 8030 diag::err_omp_parallel_sections_not_compound_stmt); 8031 return StmtError(); 8032 } 8033 8034 setFunctionHasBranchProtectedScope(); 8035 8036 return OMPParallelSectionsDirective::Create( 8037 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 8038} 8039 8040StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 8041 Stmt *AStmt, SourceLocation StartLoc, 8042 SourceLocation EndLoc) { 8043 if (!AStmt) 8044 return StmtError(); 8045 8046 auto *CS = cast<CapturedStmt>(AStmt); 8047 // 1.2.2 OpenMP Language Terminology 8048 // Structured block - An executable statement with a single entry at the 8049 // top and a single exit at the bottom. 8050 // The point of exit cannot be a branch out of the structured block. 8051 // longjmp() and throw() must not violate the entry/exit criteria. 8052 CS->getCapturedDecl()->setNothrow(); 8053 8054 setFunctionHasBranchProtectedScope(); 8055 8056 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8057 DSAStack->isCancelRegion()); 8058} 8059 8060StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 8061 SourceLocation EndLoc) { 8062 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 8063} 8064 8065StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 8066 SourceLocation EndLoc) { 8067 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 8068} 8069 8070StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 8071 SourceLocation EndLoc) { 8072 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 8073} 8074 8075StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 8076 Stmt *AStmt, 8077 SourceLocation StartLoc, 8078 SourceLocation EndLoc) { 8079 if (!AStmt) 8080 return StmtError(); 8081 8082 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8083 8084 setFunctionHasBranchProtectedScope(); 8085 8086 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 8087 AStmt, 8088 DSAStack->getTaskgroupReductionRef()); 8089} 8090 8091StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 8092 SourceLocation StartLoc, 8093 SourceLocation EndLoc) { 8094 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 8095 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 8096} 8097 8098StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 8099 Stmt *AStmt, 8100 SourceLocation StartLoc, 8101 SourceLocation EndLoc) { 8102 const OMPClause *DependFound = nullptr; 8103 const OMPClause *DependSourceClause = nullptr; 8104 const OMPClause *DependSinkClause = nullptr; 8105 bool ErrorFound = false; 8106 const OMPThreadsClause *TC = nullptr; 8107 const OMPSIMDClause *SC = nullptr; 8108 for (const OMPClause *C : Clauses) { 8109 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 8110 DependFound = C; 8111 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 8112 if (DependSourceClause) { 8113 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 8114 << getOpenMPDirectiveName(OMPD_ordered) 8115 << getOpenMPClauseName(OMPC_depend) << 2; 8116 ErrorFound = true; 8117 } else { 8118 DependSourceClause = C; 8119 } 8120 if (DependSinkClause) { 8121 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8122 << 0; 8123 ErrorFound = true; 8124 } 8125 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 8126 if (DependSourceClause) { 8127 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 8128 << 1; 8129 ErrorFound = true; 8130 } 8131 DependSinkClause = C; 8132 } 8133 } else if (C->getClauseKind() == OMPC_threads) { 8134 TC = cast<OMPThreadsClause>(C); 8135 } else if (C->getClauseKind() == OMPC_simd) { 8136 SC = cast<OMPSIMDClause>(C); 8137 } 8138 } 8139 if (!ErrorFound && !SC && 8140 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 8141 // OpenMP [2.8.1,simd Construct, Restrictions] 8142 // An ordered construct with the simd clause is the only OpenMP construct 8143 // that can appear in the simd region. 8144 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 8145 ErrorFound = true; 8146 } else if (DependFound && (TC || SC)) { 8147 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 8148 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 8149 ErrorFound = true; 8150 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 8151 Diag(DependFound->getBeginLoc(), 8152 diag::err_omp_ordered_directive_without_param); 8153 ErrorFound = true; 8154 } else if (TC || Clauses.empty()) { 8155 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 8156 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 8157 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 8158 << (TC != nullptr); 8159 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 8160 ErrorFound = true; 8161 } 8162 } 8163 if ((!AStmt && !DependFound) || ErrorFound) 8164 return StmtError(); 8165 8166 if (AStmt) { 8167 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8168 8169 setFunctionHasBranchProtectedScope(); 8170 } 8171 8172 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8173} 8174 8175namespace { 8176/// Helper class for checking expression in 'omp atomic [update]' 8177/// construct. 8178class OpenMPAtomicUpdateChecker { 8179 /// Error results for atomic update expressions. 8180 enum ExprAnalysisErrorCode { 8181 /// A statement is not an expression statement. 8182 NotAnExpression, 8183 /// Expression is not builtin binary or unary operation. 8184 NotABinaryOrUnaryExpression, 8185 /// Unary operation is not post-/pre- increment/decrement operation. 8186 NotAnUnaryIncDecExpression, 8187 /// An expression is not of scalar type. 8188 NotAScalarType, 8189 /// A binary operation is not an assignment operation. 8190 NotAnAssignmentOp, 8191 /// RHS part of the binary operation is not a binary expression. 8192 NotABinaryExpression, 8193 /// RHS part is not additive/multiplicative/shift/biwise binary 8194 /// expression. 8195 NotABinaryOperator, 8196 /// RHS binary operation does not have reference to the updated LHS 8197 /// part. 8198 NotAnUpdateExpression, 8199 /// No errors is found. 8200 NoError 8201 }; 8202 /// Reference to Sema. 8203 Sema &SemaRef; 8204 /// A location for note diagnostics (when error is found). 8205 SourceLocation NoteLoc; 8206 /// 'x' lvalue part of the source atomic expression. 8207 Expr *X; 8208 /// 'expr' rvalue part of the source atomic expression. 8209 Expr *E; 8210 /// Helper expression of the form 8211 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8212 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8213 Expr *UpdateExpr; 8214 /// Is 'x' a LHS in a RHS part of full update expression. It is 8215 /// important for non-associative operations. 8216 bool IsXLHSInRHSPart; 8217 BinaryOperatorKind Op; 8218 SourceLocation OpLoc; 8219 /// true if the source expression is a postfix unary operation, false 8220 /// if it is a prefix unary operation. 8221 bool IsPostfixUpdate; 8222 8223public: 8224 OpenMPAtomicUpdateChecker(Sema &SemaRef) 8225 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 8226 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 8227 /// Check specified statement that it is suitable for 'atomic update' 8228 /// constructs and extract 'x', 'expr' and Operation from the original 8229 /// expression. If DiagId and NoteId == 0, then only check is performed 8230 /// without error notification. 8231 /// \param DiagId Diagnostic which should be emitted if error is found. 8232 /// \param NoteId Diagnostic note for the main error message. 8233 /// \return true if statement is not an update expression, false otherwise. 8234 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 8235 /// Return the 'x' lvalue part of the source atomic expression. 8236 Expr *getX() const { return X; } 8237 /// Return the 'expr' rvalue part of the source atomic expression. 8238 Expr *getExpr() const { return E; } 8239 /// Return the update expression used in calculation of the updated 8240 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 8241 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 8242 Expr *getUpdateExpr() const { return UpdateExpr; } 8243 /// Return true if 'x' is LHS in RHS part of full update expression, 8244 /// false otherwise. 8245 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 8246 8247 /// true if the source expression is a postfix unary operation, false 8248 /// if it is a prefix unary operation. 8249 bool isPostfixUpdate() const { return IsPostfixUpdate; } 8250 8251private: 8252 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 8253 unsigned NoteId = 0); 8254}; 8255} // namespace 8256 8257bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 8258 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 8259 ExprAnalysisErrorCode ErrorFound = NoError; 8260 SourceLocation ErrorLoc, NoteLoc; 8261 SourceRange ErrorRange, NoteRange; 8262 // Allowed constructs are: 8263 // x = x binop expr; 8264 // x = expr binop x; 8265 if (AtomicBinOp->getOpcode() == BO_Assign) { 8266 X = AtomicBinOp->getLHS(); 8267 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 8268 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 8269 if (AtomicInnerBinOp->isMultiplicativeOp() || 8270 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 8271 AtomicInnerBinOp->isBitwiseOp()) { 8272 Op = AtomicInnerBinOp->getOpcode(); 8273 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 8274 Expr *LHS = AtomicInnerBinOp->getLHS(); 8275 Expr *RHS = AtomicInnerBinOp->getRHS(); 8276 llvm::FoldingSetNodeID XId, LHSId, RHSId; 8277 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 8278 /*Canonical=*/true); 8279 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 8280 /*Canonical=*/true); 8281 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 8282 /*Canonical=*/true); 8283 if (XId == LHSId) { 8284 E = RHS; 8285 IsXLHSInRHSPart = true; 8286 } else if (XId == RHSId) { 8287 E = LHS; 8288 IsXLHSInRHSPart = false; 8289 } else { 8290 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8291 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8292 NoteLoc = X->getExprLoc(); 8293 NoteRange = X->getSourceRange(); 8294 ErrorFound = NotAnUpdateExpression; 8295 } 8296 } else { 8297 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 8298 ErrorRange = AtomicInnerBinOp->getSourceRange(); 8299 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 8300 NoteRange = SourceRange(NoteLoc, NoteLoc); 8301 ErrorFound = NotABinaryOperator; 8302 } 8303 } else { 8304 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 8305 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 8306 ErrorFound = NotABinaryExpression; 8307 } 8308 } else { 8309 ErrorLoc = AtomicBinOp->getExprLoc(); 8310 ErrorRange = AtomicBinOp->getSourceRange(); 8311 NoteLoc = AtomicBinOp->getOperatorLoc(); 8312 NoteRange = SourceRange(NoteLoc, NoteLoc); 8313 ErrorFound = NotAnAssignmentOp; 8314 } 8315 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8316 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8317 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8318 return true; 8319 } 8320 if (SemaRef.CurContext->isDependentContext()) 8321 E = X = UpdateExpr = nullptr; 8322 return ErrorFound != NoError; 8323} 8324 8325bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 8326 unsigned NoteId) { 8327 ExprAnalysisErrorCode ErrorFound = NoError; 8328 SourceLocation ErrorLoc, NoteLoc; 8329 SourceRange ErrorRange, NoteRange; 8330 // Allowed constructs are: 8331 // x++; 8332 // x--; 8333 // ++x; 8334 // --x; 8335 // x binop= expr; 8336 // x = x binop expr; 8337 // x = expr binop x; 8338 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 8339 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 8340 if (AtomicBody->getType()->isScalarType() || 8341 AtomicBody->isInstantiationDependent()) { 8342 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 8343 AtomicBody->IgnoreParenImpCasts())) { 8344 // Check for Compound Assignment Operation 8345 Op = BinaryOperator::getOpForCompoundAssignment( 8346 AtomicCompAssignOp->getOpcode()); 8347 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 8348 E = AtomicCompAssignOp->getRHS(); 8349 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 8350 IsXLHSInRHSPart = true; 8351 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 8352 AtomicBody->IgnoreParenImpCasts())) { 8353 // Check for Binary Operation 8354 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 8355 return true; 8356 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 8357 AtomicBody->IgnoreParenImpCasts())) { 8358 // Check for Unary Operation 8359 if (AtomicUnaryOp->isIncrementDecrementOp()) { 8360 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 8361 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 8362 OpLoc = AtomicUnaryOp->getOperatorLoc(); 8363 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 8364 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 8365 IsXLHSInRHSPart = true; 8366 } else { 8367 ErrorFound = NotAnUnaryIncDecExpression; 8368 ErrorLoc = AtomicUnaryOp->getExprLoc(); 8369 ErrorRange = AtomicUnaryOp->getSourceRange(); 8370 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 8371 NoteRange = SourceRange(NoteLoc, NoteLoc); 8372 } 8373 } else if (!AtomicBody->isInstantiationDependent()) { 8374 ErrorFound = NotABinaryOrUnaryExpression; 8375 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 8376 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 8377 } 8378 } else { 8379 ErrorFound = NotAScalarType; 8380 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 8381 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8382 } 8383 } else { 8384 ErrorFound = NotAnExpression; 8385 NoteLoc = ErrorLoc = S->getBeginLoc(); 8386 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8387 } 8388 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 8389 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 8390 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 8391 return true; 8392 } 8393 if (SemaRef.CurContext->isDependentContext()) 8394 E = X = UpdateExpr = nullptr; 8395 if (ErrorFound == NoError && E && X) { 8396 // Build an update expression of form 'OpaqueValueExpr(x) binop 8397 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 8398 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 8399 auto *OVEX = new (SemaRef.getASTContext()) 8400 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 8401 auto *OVEExpr = new (SemaRef.getASTContext()) 8402 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 8403 ExprResult Update = 8404 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 8405 IsXLHSInRHSPart ? OVEExpr : OVEX); 8406 if (Update.isInvalid()) 8407 return true; 8408 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 8409 Sema::AA_Casting); 8410 if (Update.isInvalid()) 8411 return true; 8412 UpdateExpr = Update.get(); 8413 } 8414 return ErrorFound != NoError; 8415} 8416 8417StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 8418 Stmt *AStmt, 8419 SourceLocation StartLoc, 8420 SourceLocation EndLoc) { 8421 if (!AStmt) 8422 return StmtError(); 8423 8424 auto *CS = cast<CapturedStmt>(AStmt); 8425 // 1.2.2 OpenMP Language Terminology 8426 // Structured block - An executable statement with a single entry at the 8427 // top and a single exit at the bottom. 8428 // The point of exit cannot be a branch out of the structured block. 8429 // longjmp() and throw() must not violate the entry/exit criteria. 8430 OpenMPClauseKind AtomicKind = OMPC_unknown; 8431 SourceLocation AtomicKindLoc; 8432 for (const OMPClause *C : Clauses) { 8433 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 8434 C->getClauseKind() == OMPC_update || 8435 C->getClauseKind() == OMPC_capture) { 8436 if (AtomicKind != OMPC_unknown) { 8437 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 8438 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 8439 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 8440 << getOpenMPClauseName(AtomicKind); 8441 } else { 8442 AtomicKind = C->getClauseKind(); 8443 AtomicKindLoc = C->getBeginLoc(); 8444 } 8445 } 8446 } 8447 8448 Stmt *Body = CS->getCapturedStmt(); 8449 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 8450 Body = EWC->getSubExpr(); 8451 8452 Expr *X = nullptr; 8453 Expr *V = nullptr; 8454 Expr *E = nullptr; 8455 Expr *UE = nullptr; 8456 bool IsXLHSInRHSPart = false; 8457 bool IsPostfixUpdate = false; 8458 // OpenMP [2.12.6, atomic Construct] 8459 // In the next expressions: 8460 // * x and v (as applicable) are both l-value expressions with scalar type. 8461 // * During the execution of an atomic region, multiple syntactic 8462 // occurrences of x must designate the same storage location. 8463 // * Neither of v and expr (as applicable) may access the storage location 8464 // designated by x. 8465 // * Neither of x and expr (as applicable) may access the storage location 8466 // designated by v. 8467 // * expr is an expression with scalar type. 8468 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 8469 // * binop, binop=, ++, and -- are not overloaded operators. 8470 // * The expression x binop expr must be numerically equivalent to x binop 8471 // (expr). This requirement is satisfied if the operators in expr have 8472 // precedence greater than binop, or by using parentheses around expr or 8473 // subexpressions of expr. 8474 // * The expression expr binop x must be numerically equivalent to (expr) 8475 // binop x. This requirement is satisfied if the operators in expr have 8476 // precedence equal to or greater than binop, or by using parentheses around 8477 // expr or subexpressions of expr. 8478 // * For forms that allow multiple occurrences of x, the number of times 8479 // that x is evaluated is unspecified. 8480 if (AtomicKind == OMPC_read) { 8481 enum { 8482 NotAnExpression, 8483 NotAnAssignmentOp, 8484 NotAScalarType, 8485 NotAnLValue, 8486 NoError 8487 } ErrorFound = NoError; 8488 SourceLocation ErrorLoc, NoteLoc; 8489 SourceRange ErrorRange, NoteRange; 8490 // If clause is read: 8491 // v = x; 8492 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8493 const auto *AtomicBinOp = 8494 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8495 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8496 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8497 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 8498 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8499 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 8500 if (!X->isLValue() || !V->isLValue()) { 8501 const Expr *NotLValueExpr = X->isLValue() ? V : X; 8502 ErrorFound = NotAnLValue; 8503 ErrorLoc = AtomicBinOp->getExprLoc(); 8504 ErrorRange = AtomicBinOp->getSourceRange(); 8505 NoteLoc = NotLValueExpr->getExprLoc(); 8506 NoteRange = NotLValueExpr->getSourceRange(); 8507 } 8508 } else if (!X->isInstantiationDependent() || 8509 !V->isInstantiationDependent()) { 8510 const Expr *NotScalarExpr = 8511 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8512 ? V 8513 : X; 8514 ErrorFound = NotAScalarType; 8515 ErrorLoc = AtomicBinOp->getExprLoc(); 8516 ErrorRange = AtomicBinOp->getSourceRange(); 8517 NoteLoc = NotScalarExpr->getExprLoc(); 8518 NoteRange = NotScalarExpr->getSourceRange(); 8519 } 8520 } else if (!AtomicBody->isInstantiationDependent()) { 8521 ErrorFound = NotAnAssignmentOp; 8522 ErrorLoc = AtomicBody->getExprLoc(); 8523 ErrorRange = AtomicBody->getSourceRange(); 8524 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8525 : AtomicBody->getExprLoc(); 8526 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8527 : AtomicBody->getSourceRange(); 8528 } 8529 } else { 8530 ErrorFound = NotAnExpression; 8531 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8532 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8533 } 8534 if (ErrorFound != NoError) { 8535 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 8536 << ErrorRange; 8537 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8538 << NoteRange; 8539 return StmtError(); 8540 } 8541 if (CurContext->isDependentContext()) 8542 V = X = nullptr; 8543 } else if (AtomicKind == OMPC_write) { 8544 enum { 8545 NotAnExpression, 8546 NotAnAssignmentOp, 8547 NotAScalarType, 8548 NotAnLValue, 8549 NoError 8550 } ErrorFound = NoError; 8551 SourceLocation ErrorLoc, NoteLoc; 8552 SourceRange ErrorRange, NoteRange; 8553 // If clause is write: 8554 // x = expr; 8555 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8556 const auto *AtomicBinOp = 8557 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8558 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8559 X = AtomicBinOp->getLHS(); 8560 E = AtomicBinOp->getRHS(); 8561 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 8562 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 8563 if (!X->isLValue()) { 8564 ErrorFound = NotAnLValue; 8565 ErrorLoc = AtomicBinOp->getExprLoc(); 8566 ErrorRange = AtomicBinOp->getSourceRange(); 8567 NoteLoc = X->getExprLoc(); 8568 NoteRange = X->getSourceRange(); 8569 } 8570 } else if (!X->isInstantiationDependent() || 8571 !E->isInstantiationDependent()) { 8572 const Expr *NotScalarExpr = 8573 (X->isInstantiationDependent() || X->getType()->isScalarType()) 8574 ? E 8575 : X; 8576 ErrorFound = NotAScalarType; 8577 ErrorLoc = AtomicBinOp->getExprLoc(); 8578 ErrorRange = AtomicBinOp->getSourceRange(); 8579 NoteLoc = NotScalarExpr->getExprLoc(); 8580 NoteRange = NotScalarExpr->getSourceRange(); 8581 } 8582 } else if (!AtomicBody->isInstantiationDependent()) { 8583 ErrorFound = NotAnAssignmentOp; 8584 ErrorLoc = AtomicBody->getExprLoc(); 8585 ErrorRange = AtomicBody->getSourceRange(); 8586 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8587 : AtomicBody->getExprLoc(); 8588 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8589 : AtomicBody->getSourceRange(); 8590 } 8591 } else { 8592 ErrorFound = NotAnExpression; 8593 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8594 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 8595 } 8596 if (ErrorFound != NoError) { 8597 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 8598 << ErrorRange; 8599 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 8600 << NoteRange; 8601 return StmtError(); 8602 } 8603 if (CurContext->isDependentContext()) 8604 E = X = nullptr; 8605 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 8606 // If clause is update: 8607 // x++; 8608 // x--; 8609 // ++x; 8610 // --x; 8611 // x binop= expr; 8612 // x = x binop expr; 8613 // x = expr binop x; 8614 OpenMPAtomicUpdateChecker Checker(*this); 8615 if (Checker.checkStatement( 8616 Body, (AtomicKind == OMPC_update) 8617 ? diag::err_omp_atomic_update_not_expression_statement 8618 : diag::err_omp_atomic_not_expression_statement, 8619 diag::note_omp_atomic_update)) 8620 return StmtError(); 8621 if (!CurContext->isDependentContext()) { 8622 E = Checker.getExpr(); 8623 X = Checker.getX(); 8624 UE = Checker.getUpdateExpr(); 8625 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8626 } 8627 } else if (AtomicKind == OMPC_capture) { 8628 enum { 8629 NotAnAssignmentOp, 8630 NotACompoundStatement, 8631 NotTwoSubstatements, 8632 NotASpecificExpression, 8633 NoError 8634 } ErrorFound = NoError; 8635 SourceLocation ErrorLoc, NoteLoc; 8636 SourceRange ErrorRange, NoteRange; 8637 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 8638 // If clause is a capture: 8639 // v = x++; 8640 // v = x--; 8641 // v = ++x; 8642 // v = --x; 8643 // v = x binop= expr; 8644 // v = x = x binop expr; 8645 // v = x = expr binop x; 8646 const auto *AtomicBinOp = 8647 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 8648 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 8649 V = AtomicBinOp->getLHS(); 8650 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 8651 OpenMPAtomicUpdateChecker Checker(*this); 8652 if (Checker.checkStatement( 8653 Body, diag::err_omp_atomic_capture_not_expression_statement, 8654 diag::note_omp_atomic_update)) 8655 return StmtError(); 8656 E = Checker.getExpr(); 8657 X = Checker.getX(); 8658 UE = Checker.getUpdateExpr(); 8659 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8660 IsPostfixUpdate = Checker.isPostfixUpdate(); 8661 } else if (!AtomicBody->isInstantiationDependent()) { 8662 ErrorLoc = AtomicBody->getExprLoc(); 8663 ErrorRange = AtomicBody->getSourceRange(); 8664 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 8665 : AtomicBody->getExprLoc(); 8666 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 8667 : AtomicBody->getSourceRange(); 8668 ErrorFound = NotAnAssignmentOp; 8669 } 8670 if (ErrorFound != NoError) { 8671 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 8672 << ErrorRange; 8673 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8674 return StmtError(); 8675 } 8676 if (CurContext->isDependentContext()) 8677 UE = V = E = X = nullptr; 8678 } else { 8679 // If clause is a capture: 8680 // { v = x; x = expr; } 8681 // { v = x; x++; } 8682 // { v = x; x--; } 8683 // { v = x; ++x; } 8684 // { v = x; --x; } 8685 // { v = x; x binop= expr; } 8686 // { v = x; x = x binop expr; } 8687 // { v = x; x = expr binop x; } 8688 // { x++; v = x; } 8689 // { x--; v = x; } 8690 // { ++x; v = x; } 8691 // { --x; v = x; } 8692 // { x binop= expr; v = x; } 8693 // { x = x binop expr; v = x; } 8694 // { x = expr binop x; v = x; } 8695 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 8696 // Check that this is { expr1; expr2; } 8697 if (CS->size() == 2) { 8698 Stmt *First = CS->body_front(); 8699 Stmt *Second = CS->body_back(); 8700 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 8701 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 8702 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 8703 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 8704 // Need to find what subexpression is 'v' and what is 'x'. 8705 OpenMPAtomicUpdateChecker Checker(*this); 8706 bool IsUpdateExprFound = !Checker.checkStatement(Second); 8707 BinaryOperator *BinOp = nullptr; 8708 if (IsUpdateExprFound) { 8709 BinOp = dyn_cast<BinaryOperator>(First); 8710 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8711 } 8712 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8713 // { v = x; x++; } 8714 // { v = x; x--; } 8715 // { v = x; ++x; } 8716 // { v = x; --x; } 8717 // { v = x; x binop= expr; } 8718 // { v = x; x = x binop expr; } 8719 // { v = x; x = expr binop x; } 8720 // Check that the first expression has form v = x. 8721 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8722 llvm::FoldingSetNodeID XId, PossibleXId; 8723 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8724 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8725 IsUpdateExprFound = XId == PossibleXId; 8726 if (IsUpdateExprFound) { 8727 V = BinOp->getLHS(); 8728 X = Checker.getX(); 8729 E = Checker.getExpr(); 8730 UE = Checker.getUpdateExpr(); 8731 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8732 IsPostfixUpdate = true; 8733 } 8734 } 8735 if (!IsUpdateExprFound) { 8736 IsUpdateExprFound = !Checker.checkStatement(First); 8737 BinOp = nullptr; 8738 if (IsUpdateExprFound) { 8739 BinOp = dyn_cast<BinaryOperator>(Second); 8740 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 8741 } 8742 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 8743 // { x++; v = x; } 8744 // { x--; v = x; } 8745 // { ++x; v = x; } 8746 // { --x; v = x; } 8747 // { x binop= expr; v = x; } 8748 // { x = x binop expr; v = x; } 8749 // { x = expr binop x; v = x; } 8750 // Check that the second expression has form v = x. 8751 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 8752 llvm::FoldingSetNodeID XId, PossibleXId; 8753 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 8754 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 8755 IsUpdateExprFound = XId == PossibleXId; 8756 if (IsUpdateExprFound) { 8757 V = BinOp->getLHS(); 8758 X = Checker.getX(); 8759 E = Checker.getExpr(); 8760 UE = Checker.getUpdateExpr(); 8761 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 8762 IsPostfixUpdate = false; 8763 } 8764 } 8765 } 8766 if (!IsUpdateExprFound) { 8767 // { v = x; x = expr; } 8768 auto *FirstExpr = dyn_cast<Expr>(First); 8769 auto *SecondExpr = dyn_cast<Expr>(Second); 8770 if (!FirstExpr || !SecondExpr || 8771 !(FirstExpr->isInstantiationDependent() || 8772 SecondExpr->isInstantiationDependent())) { 8773 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 8774 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 8775 ErrorFound = NotAnAssignmentOp; 8776 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 8777 : First->getBeginLoc(); 8778 NoteRange = ErrorRange = FirstBinOp 8779 ? FirstBinOp->getSourceRange() 8780 : SourceRange(ErrorLoc, ErrorLoc); 8781 } else { 8782 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 8783 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 8784 ErrorFound = NotAnAssignmentOp; 8785 NoteLoc = ErrorLoc = SecondBinOp 8786 ? SecondBinOp->getOperatorLoc() 8787 : Second->getBeginLoc(); 8788 NoteRange = ErrorRange = 8789 SecondBinOp ? SecondBinOp->getSourceRange() 8790 : SourceRange(ErrorLoc, ErrorLoc); 8791 } else { 8792 Expr *PossibleXRHSInFirst = 8793 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 8794 Expr *PossibleXLHSInSecond = 8795 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 8796 llvm::FoldingSetNodeID X1Id, X2Id; 8797 PossibleXRHSInFirst->Profile(X1Id, Context, 8798 /*Canonical=*/true); 8799 PossibleXLHSInSecond->Profile(X2Id, Context, 8800 /*Canonical=*/true); 8801 IsUpdateExprFound = X1Id == X2Id; 8802 if (IsUpdateExprFound) { 8803 V = FirstBinOp->getLHS(); 8804 X = SecondBinOp->getLHS(); 8805 E = SecondBinOp->getRHS(); 8806 UE = nullptr; 8807 IsXLHSInRHSPart = false; 8808 IsPostfixUpdate = true; 8809 } else { 8810 ErrorFound = NotASpecificExpression; 8811 ErrorLoc = FirstBinOp->getExprLoc(); 8812 ErrorRange = FirstBinOp->getSourceRange(); 8813 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 8814 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 8815 } 8816 } 8817 } 8818 } 8819 } 8820 } else { 8821 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8822 NoteRange = ErrorRange = 8823 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8824 ErrorFound = NotTwoSubstatements; 8825 } 8826 } else { 8827 NoteLoc = ErrorLoc = Body->getBeginLoc(); 8828 NoteRange = ErrorRange = 8829 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 8830 ErrorFound = NotACompoundStatement; 8831 } 8832 if (ErrorFound != NoError) { 8833 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 8834 << ErrorRange; 8835 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 8836 return StmtError(); 8837 } 8838 if (CurContext->isDependentContext()) 8839 UE = V = E = X = nullptr; 8840 } 8841 } 8842 8843 setFunctionHasBranchProtectedScope(); 8844 8845 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8846 X, V, E, UE, IsXLHSInRHSPart, 8847 IsPostfixUpdate); 8848} 8849 8850StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 8851 Stmt *AStmt, 8852 SourceLocation StartLoc, 8853 SourceLocation EndLoc) { 8854 if (!AStmt) 8855 return StmtError(); 8856 8857 auto *CS = cast<CapturedStmt>(AStmt); 8858 // 1.2.2 OpenMP Language Terminology 8859 // Structured block - An executable statement with a single entry at the 8860 // top and a single exit at the bottom. 8861 // The point of exit cannot be a branch out of the structured block. 8862 // longjmp() and throw() must not violate the entry/exit criteria. 8863 CS->getCapturedDecl()->setNothrow(); 8864 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 8865 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8866 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8867 // 1.2.2 OpenMP Language Terminology 8868 // Structured block - An executable statement with a single entry at the 8869 // top and a single exit at the bottom. 8870 // The point of exit cannot be a branch out of the structured block. 8871 // longjmp() and throw() must not violate the entry/exit criteria. 8872 CS->getCapturedDecl()->setNothrow(); 8873 } 8874 8875 // OpenMP [2.16, Nesting of Regions] 8876 // If specified, a teams construct must be contained within a target 8877 // construct. That target construct must contain no statements or directives 8878 // outside of the teams construct. 8879 if (DSAStack->hasInnerTeamsRegion()) { 8880 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 8881 bool OMPTeamsFound = true; 8882 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 8883 auto I = CS->body_begin(); 8884 while (I != CS->body_end()) { 8885 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 8886 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 8887 OMPTeamsFound) { 8888 8889 OMPTeamsFound = false; 8890 break; 8891 } 8892 ++I; 8893 } 8894 assert(I != CS->body_end() && "Not found statement"); 8895 S = *I; 8896 } else { 8897 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 8898 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 8899 } 8900 if (!OMPTeamsFound) { 8901 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 8902 Diag(DSAStack->getInnerTeamsRegionLoc(), 8903 diag::note_omp_nested_teams_construct_here); 8904 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 8905 << isa<OMPExecutableDirective>(S); 8906 return StmtError(); 8907 } 8908 } 8909 8910 setFunctionHasBranchProtectedScope(); 8911 8912 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8913} 8914 8915StmtResult 8916Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 8917 Stmt *AStmt, SourceLocation StartLoc, 8918 SourceLocation EndLoc) { 8919 if (!AStmt) 8920 return StmtError(); 8921 8922 auto *CS = cast<CapturedStmt>(AStmt); 8923 // 1.2.2 OpenMP Language Terminology 8924 // Structured block - An executable statement with a single entry at the 8925 // top and a single exit at the bottom. 8926 // The point of exit cannot be a branch out of the structured block. 8927 // longjmp() and throw() must not violate the entry/exit criteria. 8928 CS->getCapturedDecl()->setNothrow(); 8929 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 8930 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8931 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8932 // 1.2.2 OpenMP Language Terminology 8933 // Structured block - An executable statement with a single entry at the 8934 // top and a single exit at the bottom. 8935 // The point of exit cannot be a branch out of the structured block. 8936 // longjmp() and throw() must not violate the entry/exit criteria. 8937 CS->getCapturedDecl()->setNothrow(); 8938 } 8939 8940 setFunctionHasBranchProtectedScope(); 8941 8942 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 8943 AStmt); 8944} 8945 8946StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 8947 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8948 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8949 if (!AStmt) 8950 return StmtError(); 8951 8952 auto *CS = cast<CapturedStmt>(AStmt); 8953 // 1.2.2 OpenMP Language Terminology 8954 // Structured block - An executable statement with a single entry at the 8955 // top and a single exit at the bottom. 8956 // The point of exit cannot be a branch out of the structured block. 8957 // longjmp() and throw() must not violate the entry/exit criteria. 8958 CS->getCapturedDecl()->setNothrow(); 8959 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8960 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8961 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8962 // 1.2.2 OpenMP Language Terminology 8963 // Structured block - An executable statement with a single entry at the 8964 // top and a single exit at the bottom. 8965 // The point of exit cannot be a branch out of the structured block. 8966 // longjmp() and throw() must not violate the entry/exit criteria. 8967 CS->getCapturedDecl()->setNothrow(); 8968 } 8969 8970 OMPLoopDirective::HelperExprs B; 8971 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8972 // define the nested loops number. 8973 unsigned NestedLoopCount = 8974 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 8975 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8976 VarsWithImplicitDSA, B); 8977 if (NestedLoopCount == 0) 8978 return StmtError(); 8979 8980 assert((CurContext->isDependentContext() || B.builtAll()) && 8981 "omp target parallel for loop exprs were not built"); 8982 8983 if (!CurContext->isDependentContext()) { 8984 // Finalize the clauses that need pre-built expressions for CodeGen. 8985 for (OMPClause *C : Clauses) { 8986 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8987 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8988 B.NumIterations, *this, CurScope, 8989 DSAStack)) 8990 return StmtError(); 8991 } 8992 } 8993 8994 setFunctionHasBranchProtectedScope(); 8995 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 8996 NestedLoopCount, Clauses, AStmt, 8997 B, DSAStack->isCancelRegion()); 8998} 8999 9000/// Check for existence of a map clause in the list of clauses. 9001static bool hasClauses(ArrayRef<OMPClause *> Clauses, 9002 const OpenMPClauseKind K) { 9003 return llvm::any_of( 9004 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 9005} 9006 9007template <typename... Params> 9008static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 9009 const Params... ClauseTypes) { 9010 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 9011} 9012 9013StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 9014 Stmt *AStmt, 9015 SourceLocation StartLoc, 9016 SourceLocation EndLoc) { 9017 if (!AStmt) 9018 return StmtError(); 9019 9020 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9021 9022 // OpenMP [2.10.1, Restrictions, p. 97] 9023 // At least one map clause must appear on the directive. 9024 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 9025 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9026 << "'map' or 'use_device_ptr'" 9027 << getOpenMPDirectiveName(OMPD_target_data); 9028 return StmtError(); 9029 } 9030 9031 setFunctionHasBranchProtectedScope(); 9032 9033 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9034 AStmt); 9035} 9036 9037StmtResult 9038Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 9039 SourceLocation StartLoc, 9040 SourceLocation EndLoc, Stmt *AStmt) { 9041 if (!AStmt) 9042 return StmtError(); 9043 9044 auto *CS = cast<CapturedStmt>(AStmt); 9045 // 1.2.2 OpenMP Language Terminology 9046 // Structured block - An executable statement with a single entry at the 9047 // top and a single exit at the bottom. 9048 // The point of exit cannot be a branch out of the structured block. 9049 // longjmp() and throw() must not violate the entry/exit criteria. 9050 CS->getCapturedDecl()->setNothrow(); 9051 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 9052 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9053 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9054 // 1.2.2 OpenMP Language Terminology 9055 // Structured block - An executable statement with a single entry at the 9056 // top and a single exit at the bottom. 9057 // The point of exit cannot be a branch out of the structured block. 9058 // longjmp() and throw() must not violate the entry/exit criteria. 9059 CS->getCapturedDecl()->setNothrow(); 9060 } 9061 9062 // OpenMP [2.10.2, Restrictions, p. 99] 9063 // At least one map clause must appear on the directive. 9064 if (!hasClauses(Clauses, OMPC_map)) { 9065 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9066 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 9067 return StmtError(); 9068 } 9069 9070 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9071 AStmt); 9072} 9073 9074StmtResult 9075Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 9076 SourceLocation StartLoc, 9077 SourceLocation EndLoc, Stmt *AStmt) { 9078 if (!AStmt) 9079 return StmtError(); 9080 9081 auto *CS = cast<CapturedStmt>(AStmt); 9082 // 1.2.2 OpenMP Language Terminology 9083 // Structured block - An executable statement with a single entry at the 9084 // top and a single exit at the bottom. 9085 // The point of exit cannot be a branch out of the structured block. 9086 // longjmp() and throw() must not violate the entry/exit criteria. 9087 CS->getCapturedDecl()->setNothrow(); 9088 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 9089 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9090 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9091 // 1.2.2 OpenMP Language Terminology 9092 // Structured block - An executable statement with a single entry at the 9093 // top and a single exit at the bottom. 9094 // The point of exit cannot be a branch out of the structured block. 9095 // longjmp() and throw() must not violate the entry/exit criteria. 9096 CS->getCapturedDecl()->setNothrow(); 9097 } 9098 9099 // OpenMP [2.10.3, Restrictions, p. 102] 9100 // At least one map clause must appear on the directive. 9101 if (!hasClauses(Clauses, OMPC_map)) { 9102 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 9103 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 9104 return StmtError(); 9105 } 9106 9107 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 9108 AStmt); 9109} 9110 9111StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 9112 SourceLocation StartLoc, 9113 SourceLocation EndLoc, 9114 Stmt *AStmt) { 9115 if (!AStmt) 9116 return StmtError(); 9117 9118 auto *CS = cast<CapturedStmt>(AStmt); 9119 // 1.2.2 OpenMP Language Terminology 9120 // Structured block - An executable statement with a single entry at the 9121 // top and a single exit at the bottom. 9122 // The point of exit cannot be a branch out of the structured block. 9123 // longjmp() and throw() must not violate the entry/exit criteria. 9124 CS->getCapturedDecl()->setNothrow(); 9125 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 9126 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9127 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9128 // 1.2.2 OpenMP Language Terminology 9129 // Structured block - An executable statement with a single entry at the 9130 // top and a single exit at the bottom. 9131 // The point of exit cannot be a branch out of the structured block. 9132 // longjmp() and throw() must not violate the entry/exit criteria. 9133 CS->getCapturedDecl()->setNothrow(); 9134 } 9135 9136 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 9137 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 9138 return StmtError(); 9139 } 9140 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 9141 AStmt); 9142} 9143 9144StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 9145 Stmt *AStmt, SourceLocation StartLoc, 9146 SourceLocation EndLoc) { 9147 if (!AStmt) 9148 return StmtError(); 9149 9150 auto *CS = cast<CapturedStmt>(AStmt); 9151 // 1.2.2 OpenMP Language Terminology 9152 // Structured block - An executable statement with a single entry at the 9153 // top and a single exit at the bottom. 9154 // The point of exit cannot be a branch out of the structured block. 9155 // longjmp() and throw() must not violate the entry/exit criteria. 9156 CS->getCapturedDecl()->setNothrow(); 9157 9158 setFunctionHasBranchProtectedScope(); 9159 9160 DSAStack->setParentTeamsRegionLoc(StartLoc); 9161 9162 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9163} 9164 9165StmtResult 9166Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 9167 SourceLocation EndLoc, 9168 OpenMPDirectiveKind CancelRegion) { 9169 if (DSAStack->isParentNowaitRegion()) { 9170 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 9171 return StmtError(); 9172 } 9173 if (DSAStack->isParentOrderedRegion()) { 9174 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 9175 return StmtError(); 9176 } 9177 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 9178 CancelRegion); 9179} 9180 9181StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 9182 SourceLocation StartLoc, 9183 SourceLocation EndLoc, 9184 OpenMPDirectiveKind CancelRegion) { 9185 if (DSAStack->isParentNowaitRegion()) { 9186 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 9187 return StmtError(); 9188 } 9189 if (DSAStack->isParentOrderedRegion()) { 9190 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 9191 return StmtError(); 9192 } 9193 DSAStack->setParentCancelRegion(/*Cancel=*/true); 9194 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 9195 CancelRegion); 9196} 9197 9198static bool checkGrainsizeNumTasksClauses(Sema &S, 9199 ArrayRef<OMPClause *> Clauses) { 9200 const OMPClause *PrevClause = nullptr; 9201 bool ErrorFound = false; 9202 for (const OMPClause *C : Clauses) { 9203 if (C->getClauseKind() == OMPC_grainsize || 9204 C->getClauseKind() == OMPC_num_tasks) { 9205 if (!PrevClause) 9206 PrevClause = C; 9207 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9208 S.Diag(C->getBeginLoc(), 9209 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 9210 << getOpenMPClauseName(C->getClauseKind()) 9211 << getOpenMPClauseName(PrevClause->getClauseKind()); 9212 S.Diag(PrevClause->getBeginLoc(), 9213 diag::note_omp_previous_grainsize_num_tasks) 9214 << getOpenMPClauseName(PrevClause->getClauseKind()); 9215 ErrorFound = true; 9216 } 9217 } 9218 } 9219 return ErrorFound; 9220} 9221 9222static bool checkReductionClauseWithNogroup(Sema &S, 9223 ArrayRef<OMPClause *> Clauses) { 9224 const OMPClause *ReductionClause = nullptr; 9225 const OMPClause *NogroupClause = nullptr; 9226 for (const OMPClause *C : Clauses) { 9227 if (C->getClauseKind() == OMPC_reduction) { 9228 ReductionClause = C; 9229 if (NogroupClause) 9230 break; 9231 continue; 9232 } 9233 if (C->getClauseKind() == OMPC_nogroup) { 9234 NogroupClause = C; 9235 if (ReductionClause) 9236 break; 9237 continue; 9238 } 9239 } 9240 if (ReductionClause && NogroupClause) { 9241 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 9242 << SourceRange(NogroupClause->getBeginLoc(), 9243 NogroupClause->getEndLoc()); 9244 return true; 9245 } 9246 return false; 9247} 9248 9249StmtResult Sema::ActOnOpenMPTaskLoopDirective( 9250 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9251 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9252 if (!AStmt) 9253 return StmtError(); 9254 9255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9256 OMPLoopDirective::HelperExprs B; 9257 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9258 // define the nested loops number. 9259 unsigned NestedLoopCount = 9260 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 9261 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9262 VarsWithImplicitDSA, B); 9263 if (NestedLoopCount == 0) 9264 return StmtError(); 9265 9266 assert((CurContext->isDependentContext() || B.builtAll()) && 9267 "omp for loop exprs were not built"); 9268 9269 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9270 // The grainsize clause and num_tasks clause are mutually exclusive and may 9271 // not appear on the same taskloop directive. 9272 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9273 return StmtError(); 9274 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9275 // If a reduction clause is present on the taskloop directive, the nogroup 9276 // clause must not be specified. 9277 if (checkReductionClauseWithNogroup(*this, Clauses)) 9278 return StmtError(); 9279 9280 setFunctionHasBranchProtectedScope(); 9281 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9282 NestedLoopCount, Clauses, AStmt, B); 9283} 9284 9285StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 9286 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9287 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9288 if (!AStmt) 9289 return StmtError(); 9290 9291 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9292 OMPLoopDirective::HelperExprs B; 9293 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9294 // define the nested loops number. 9295 unsigned NestedLoopCount = 9296 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 9297 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9298 VarsWithImplicitDSA, B); 9299 if (NestedLoopCount == 0) 9300 return StmtError(); 9301 9302 assert((CurContext->isDependentContext() || B.builtAll()) && 9303 "omp for loop exprs were not built"); 9304 9305 if (!CurContext->isDependentContext()) { 9306 // Finalize the clauses that need pre-built expressions for CodeGen. 9307 for (OMPClause *C : Clauses) { 9308 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9309 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9310 B.NumIterations, *this, CurScope, 9311 DSAStack)) 9312 return StmtError(); 9313 } 9314 } 9315 9316 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9317 // The grainsize clause and num_tasks clause are mutually exclusive and may 9318 // not appear on the same taskloop directive. 9319 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9320 return StmtError(); 9321 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9322 // If a reduction clause is present on the taskloop directive, the nogroup 9323 // clause must not be specified. 9324 if (checkReductionClauseWithNogroup(*this, Clauses)) 9325 return StmtError(); 9326 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9327 return StmtError(); 9328 9329 setFunctionHasBranchProtectedScope(); 9330 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 9331 NestedLoopCount, Clauses, AStmt, B); 9332} 9333 9334StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 9335 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9336 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9337 if (!AStmt) 9338 return StmtError(); 9339 9340 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9341 OMPLoopDirective::HelperExprs B; 9342 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9343 // define the nested loops number. 9344 unsigned NestedLoopCount = 9345 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 9346 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9347 VarsWithImplicitDSA, B); 9348 if (NestedLoopCount == 0) 9349 return StmtError(); 9350 9351 assert((CurContext->isDependentContext() || B.builtAll()) && 9352 "omp for loop exprs were not built"); 9353 9354 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9355 // The grainsize clause and num_tasks clause are mutually exclusive and may 9356 // not appear on the same taskloop directive. 9357 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9358 return StmtError(); 9359 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9360 // If a reduction clause is present on the taskloop directive, the nogroup 9361 // clause must not be specified. 9362 if (checkReductionClauseWithNogroup(*this, Clauses)) 9363 return StmtError(); 9364 9365 setFunctionHasBranchProtectedScope(); 9366 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 9367 NestedLoopCount, Clauses, AStmt, B); 9368} 9369 9370StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 9371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9372 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9373 if (!AStmt) 9374 return StmtError(); 9375 9376 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9377 OMPLoopDirective::HelperExprs B; 9378 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9379 // define the nested loops number. 9380 unsigned NestedLoopCount = 9381 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 9382 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 9383 VarsWithImplicitDSA, B); 9384 if (NestedLoopCount == 0) 9385 return StmtError(); 9386 9387 assert((CurContext->isDependentContext() || B.builtAll()) && 9388 "omp for loop exprs were not built"); 9389 9390 if (!CurContext->isDependentContext()) { 9391 // Finalize the clauses that need pre-built expressions for CodeGen. 9392 for (OMPClause *C : Clauses) { 9393 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9394 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9395 B.NumIterations, *this, CurScope, 9396 DSAStack)) 9397 return StmtError(); 9398 } 9399 } 9400 9401 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9402 // The grainsize clause and num_tasks clause are mutually exclusive and may 9403 // not appear on the same taskloop directive. 9404 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9405 return StmtError(); 9406 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9407 // If a reduction clause is present on the taskloop directive, the nogroup 9408 // clause must not be specified. 9409 if (checkReductionClauseWithNogroup(*this, Clauses)) 9410 return StmtError(); 9411 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9412 return StmtError(); 9413 9414 setFunctionHasBranchProtectedScope(); 9415 return OMPMasterTaskLoopSimdDirective::Create( 9416 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9417} 9418 9419StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 9420 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9421 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9422 if (!AStmt) 9423 return StmtError(); 9424 9425 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9426 auto *CS = cast<CapturedStmt>(AStmt); 9427 // 1.2.2 OpenMP Language Terminology 9428 // Structured block - An executable statement with a single entry at the 9429 // top and a single exit at the bottom. 9430 // The point of exit cannot be a branch out of the structured block. 9431 // longjmp() and throw() must not violate the entry/exit criteria. 9432 CS->getCapturedDecl()->setNothrow(); 9433 for (int ThisCaptureLevel = 9434 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 9435 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9436 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9437 // 1.2.2 OpenMP Language Terminology 9438 // Structured block - An executable statement with a single entry at the 9439 // top and a single exit at the bottom. 9440 // The point of exit cannot be a branch out of the structured block. 9441 // longjmp() and throw() must not violate the entry/exit criteria. 9442 CS->getCapturedDecl()->setNothrow(); 9443 } 9444 9445 OMPLoopDirective::HelperExprs B; 9446 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9447 // define the nested loops number. 9448 unsigned NestedLoopCount = checkOpenMPLoop( 9449 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 9450 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 9451 VarsWithImplicitDSA, B); 9452 if (NestedLoopCount == 0) 9453 return StmtError(); 9454 9455 assert((CurContext->isDependentContext() || B.builtAll()) && 9456 "omp for loop exprs were not built"); 9457 9458 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9459 // The grainsize clause and num_tasks clause are mutually exclusive and may 9460 // not appear on the same taskloop directive. 9461 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 9462 return StmtError(); 9463 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 9464 // If a reduction clause is present on the taskloop directive, the nogroup 9465 // clause must not be specified. 9466 if (checkReductionClauseWithNogroup(*this, Clauses)) 9467 return StmtError(); 9468 9469 setFunctionHasBranchProtectedScope(); 9470 return OMPParallelMasterTaskLoopDirective::Create( 9471 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9472} 9473 9474StmtResult Sema::ActOnOpenMPDistributeDirective( 9475 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9476 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9477 if (!AStmt) 9478 return StmtError(); 9479 9480 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9481 OMPLoopDirective::HelperExprs B; 9482 // In presence of clause 'collapse' with number of loops, it will 9483 // define the nested loops number. 9484 unsigned NestedLoopCount = 9485 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 9486 nullptr /*ordered not a clause on distribute*/, AStmt, 9487 *this, *DSAStack, VarsWithImplicitDSA, B); 9488 if (NestedLoopCount == 0) 9489 return StmtError(); 9490 9491 assert((CurContext->isDependentContext() || B.builtAll()) && 9492 "omp for loop exprs were not built"); 9493 9494 setFunctionHasBranchProtectedScope(); 9495 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 9496 NestedLoopCount, Clauses, AStmt, B); 9497} 9498 9499StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 9500 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9501 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9502 if (!AStmt) 9503 return StmtError(); 9504 9505 auto *CS = cast<CapturedStmt>(AStmt); 9506 // 1.2.2 OpenMP Language Terminology 9507 // Structured block - An executable statement with a single entry at the 9508 // top and a single exit at the bottom. 9509 // The point of exit cannot be a branch out of the structured block. 9510 // longjmp() and throw() must not violate the entry/exit criteria. 9511 CS->getCapturedDecl()->setNothrow(); 9512 for (int ThisCaptureLevel = 9513 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 9514 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9515 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9516 // 1.2.2 OpenMP Language Terminology 9517 // Structured block - An executable statement with a single entry at the 9518 // top and a single exit at the bottom. 9519 // The point of exit cannot be a branch out of the structured block. 9520 // longjmp() and throw() must not violate the entry/exit criteria. 9521 CS->getCapturedDecl()->setNothrow(); 9522 } 9523 9524 OMPLoopDirective::HelperExprs B; 9525 // In presence of clause 'collapse' with number of loops, it will 9526 // define the nested loops number. 9527 unsigned NestedLoopCount = checkOpenMPLoop( 9528 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9529 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9530 VarsWithImplicitDSA, B); 9531 if (NestedLoopCount == 0) 9532 return StmtError(); 9533 9534 assert((CurContext->isDependentContext() || B.builtAll()) && 9535 "omp for loop exprs were not built"); 9536 9537 setFunctionHasBranchProtectedScope(); 9538 return OMPDistributeParallelForDirective::Create( 9539 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9540 DSAStack->isCancelRegion()); 9541} 9542 9543StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 9544 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9545 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9546 if (!AStmt) 9547 return StmtError(); 9548 9549 auto *CS = cast<CapturedStmt>(AStmt); 9550 // 1.2.2 OpenMP Language Terminology 9551 // Structured block - An executable statement with a single entry at the 9552 // top and a single exit at the bottom. 9553 // The point of exit cannot be a branch out of the structured block. 9554 // longjmp() and throw() must not violate the entry/exit criteria. 9555 CS->getCapturedDecl()->setNothrow(); 9556 for (int ThisCaptureLevel = 9557 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 9558 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9559 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9560 // 1.2.2 OpenMP Language Terminology 9561 // Structured block - An executable statement with a single entry at the 9562 // top and a single exit at the bottom. 9563 // The point of exit cannot be a branch out of the structured block. 9564 // longjmp() and throw() must not violate the entry/exit criteria. 9565 CS->getCapturedDecl()->setNothrow(); 9566 } 9567 9568 OMPLoopDirective::HelperExprs B; 9569 // In presence of clause 'collapse' with number of loops, it will 9570 // define the nested loops number. 9571 unsigned NestedLoopCount = checkOpenMPLoop( 9572 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9573 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9574 VarsWithImplicitDSA, B); 9575 if (NestedLoopCount == 0) 9576 return StmtError(); 9577 9578 assert((CurContext->isDependentContext() || B.builtAll()) && 9579 "omp for loop exprs were not built"); 9580 9581 if (!CurContext->isDependentContext()) { 9582 // Finalize the clauses that need pre-built expressions for CodeGen. 9583 for (OMPClause *C : Clauses) { 9584 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9585 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9586 B.NumIterations, *this, CurScope, 9587 DSAStack)) 9588 return StmtError(); 9589 } 9590 } 9591 9592 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9593 return StmtError(); 9594 9595 setFunctionHasBranchProtectedScope(); 9596 return OMPDistributeParallelForSimdDirective::Create( 9597 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9598} 9599 9600StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 9601 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9602 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9603 if (!AStmt) 9604 return StmtError(); 9605 9606 auto *CS = cast<CapturedStmt>(AStmt); 9607 // 1.2.2 OpenMP Language Terminology 9608 // Structured block - An executable statement with a single entry at the 9609 // top and a single exit at the bottom. 9610 // The point of exit cannot be a branch out of the structured block. 9611 // longjmp() and throw() must not violate the entry/exit criteria. 9612 CS->getCapturedDecl()->setNothrow(); 9613 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 9614 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9615 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9616 // 1.2.2 OpenMP Language Terminology 9617 // Structured block - An executable statement with a single entry at the 9618 // top and a single exit at the bottom. 9619 // The point of exit cannot be a branch out of the structured block. 9620 // longjmp() and throw() must not violate the entry/exit criteria. 9621 CS->getCapturedDecl()->setNothrow(); 9622 } 9623 9624 OMPLoopDirective::HelperExprs B; 9625 // In presence of clause 'collapse' with number of loops, it will 9626 // define the nested loops number. 9627 unsigned NestedLoopCount = 9628 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 9629 nullptr /*ordered not a clause on distribute*/, CS, *this, 9630 *DSAStack, VarsWithImplicitDSA, B); 9631 if (NestedLoopCount == 0) 9632 return StmtError(); 9633 9634 assert((CurContext->isDependentContext() || B.builtAll()) && 9635 "omp for loop exprs were not built"); 9636 9637 if (!CurContext->isDependentContext()) { 9638 // Finalize the clauses that need pre-built expressions for CodeGen. 9639 for (OMPClause *C : Clauses) { 9640 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9641 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9642 B.NumIterations, *this, CurScope, 9643 DSAStack)) 9644 return StmtError(); 9645 } 9646 } 9647 9648 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9649 return StmtError(); 9650 9651 setFunctionHasBranchProtectedScope(); 9652 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 9653 NestedLoopCount, Clauses, AStmt, B); 9654} 9655 9656StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 9657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9659 if (!AStmt) 9660 return StmtError(); 9661 9662 auto *CS = cast<CapturedStmt>(AStmt); 9663 // 1.2.2 OpenMP Language Terminology 9664 // Structured block - An executable statement with a single entry at the 9665 // top and a single exit at the bottom. 9666 // The point of exit cannot be a branch out of the structured block. 9667 // longjmp() and throw() must not violate the entry/exit criteria. 9668 CS->getCapturedDecl()->setNothrow(); 9669 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 9670 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9671 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9672 // 1.2.2 OpenMP Language Terminology 9673 // Structured block - An executable statement with a single entry at the 9674 // top and a single exit at the bottom. 9675 // The point of exit cannot be a branch out of the structured block. 9676 // longjmp() and throw() must not violate the entry/exit criteria. 9677 CS->getCapturedDecl()->setNothrow(); 9678 } 9679 9680 OMPLoopDirective::HelperExprs B; 9681 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 9682 // define the nested loops number. 9683 unsigned NestedLoopCount = checkOpenMPLoop( 9684 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 9685 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9686 VarsWithImplicitDSA, B); 9687 if (NestedLoopCount == 0) 9688 return StmtError(); 9689 9690 assert((CurContext->isDependentContext() || B.builtAll()) && 9691 "omp target parallel for simd loop exprs were not built"); 9692 9693 if (!CurContext->isDependentContext()) { 9694 // Finalize the clauses that need pre-built expressions for CodeGen. 9695 for (OMPClause *C : Clauses) { 9696 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9697 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9698 B.NumIterations, *this, CurScope, 9699 DSAStack)) 9700 return StmtError(); 9701 } 9702 } 9703 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9704 return StmtError(); 9705 9706 setFunctionHasBranchProtectedScope(); 9707 return OMPTargetParallelForSimdDirective::Create( 9708 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9709} 9710 9711StmtResult Sema::ActOnOpenMPTargetSimdDirective( 9712 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9713 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9714 if (!AStmt) 9715 return StmtError(); 9716 9717 auto *CS = cast<CapturedStmt>(AStmt); 9718 // 1.2.2 OpenMP Language Terminology 9719 // Structured block - An executable statement with a single entry at the 9720 // top and a single exit at the bottom. 9721 // The point of exit cannot be a branch out of the structured block. 9722 // longjmp() and throw() must not violate the entry/exit criteria. 9723 CS->getCapturedDecl()->setNothrow(); 9724 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 9725 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9726 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9727 // 1.2.2 OpenMP Language Terminology 9728 // Structured block - An executable statement with a single entry at the 9729 // top and a single exit at the bottom. 9730 // The point of exit cannot be a branch out of the structured block. 9731 // longjmp() and throw() must not violate the entry/exit criteria. 9732 CS->getCapturedDecl()->setNothrow(); 9733 } 9734 9735 OMPLoopDirective::HelperExprs B; 9736 // In presence of clause 'collapse' with number of loops, it will define the 9737 // nested loops number. 9738 unsigned NestedLoopCount = 9739 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 9740 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 9741 VarsWithImplicitDSA, B); 9742 if (NestedLoopCount == 0) 9743 return StmtError(); 9744 9745 assert((CurContext->isDependentContext() || B.builtAll()) && 9746 "omp target simd loop exprs were not built"); 9747 9748 if (!CurContext->isDependentContext()) { 9749 // Finalize the clauses that need pre-built expressions for CodeGen. 9750 for (OMPClause *C : Clauses) { 9751 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9752 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9753 B.NumIterations, *this, CurScope, 9754 DSAStack)) 9755 return StmtError(); 9756 } 9757 } 9758 9759 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9760 return StmtError(); 9761 9762 setFunctionHasBranchProtectedScope(); 9763 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 9764 NestedLoopCount, Clauses, AStmt, B); 9765} 9766 9767StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 9768 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9769 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9770 if (!AStmt) 9771 return StmtError(); 9772 9773 auto *CS = cast<CapturedStmt>(AStmt); 9774 // 1.2.2 OpenMP Language Terminology 9775 // Structured block - An executable statement with a single entry at the 9776 // top and a single exit at the bottom. 9777 // The point of exit cannot be a branch out of the structured block. 9778 // longjmp() and throw() must not violate the entry/exit criteria. 9779 CS->getCapturedDecl()->setNothrow(); 9780 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 9781 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9782 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9783 // 1.2.2 OpenMP Language Terminology 9784 // Structured block - An executable statement with a single entry at the 9785 // top and a single exit at the bottom. 9786 // The point of exit cannot be a branch out of the structured block. 9787 // longjmp() and throw() must not violate the entry/exit criteria. 9788 CS->getCapturedDecl()->setNothrow(); 9789 } 9790 9791 OMPLoopDirective::HelperExprs B; 9792 // In presence of clause 'collapse' with number of loops, it will 9793 // define the nested loops number. 9794 unsigned NestedLoopCount = 9795 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 9796 nullptr /*ordered not a clause on distribute*/, CS, *this, 9797 *DSAStack, VarsWithImplicitDSA, B); 9798 if (NestedLoopCount == 0) 9799 return StmtError(); 9800 9801 assert((CurContext->isDependentContext() || B.builtAll()) && 9802 "omp teams distribute loop exprs were not built"); 9803 9804 setFunctionHasBranchProtectedScope(); 9805 9806 DSAStack->setParentTeamsRegionLoc(StartLoc); 9807 9808 return OMPTeamsDistributeDirective::Create( 9809 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9810} 9811 9812StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 9813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9815 if (!AStmt) 9816 return StmtError(); 9817 9818 auto *CS = cast<CapturedStmt>(AStmt); 9819 // 1.2.2 OpenMP Language Terminology 9820 // Structured block - An executable statement with a single entry at the 9821 // top and a single exit at the bottom. 9822 // The point of exit cannot be a branch out of the structured block. 9823 // longjmp() and throw() must not violate the entry/exit criteria. 9824 CS->getCapturedDecl()->setNothrow(); 9825 for (int ThisCaptureLevel = 9826 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 9827 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9828 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9829 // 1.2.2 OpenMP Language Terminology 9830 // Structured block - An executable statement with a single entry at the 9831 // top and a single exit at the bottom. 9832 // The point of exit cannot be a branch out of the structured block. 9833 // longjmp() and throw() must not violate the entry/exit criteria. 9834 CS->getCapturedDecl()->setNothrow(); 9835 } 9836 9837 9838 OMPLoopDirective::HelperExprs B; 9839 // In presence of clause 'collapse' with number of loops, it will 9840 // define the nested loops number. 9841 unsigned NestedLoopCount = checkOpenMPLoop( 9842 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 9843 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9844 VarsWithImplicitDSA, B); 9845 9846 if (NestedLoopCount == 0) 9847 return StmtError(); 9848 9849 assert((CurContext->isDependentContext() || B.builtAll()) && 9850 "omp teams distribute simd loop exprs were not built"); 9851 9852 if (!CurContext->isDependentContext()) { 9853 // Finalize the clauses that need pre-built expressions for CodeGen. 9854 for (OMPClause *C : Clauses) { 9855 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9856 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9857 B.NumIterations, *this, CurScope, 9858 DSAStack)) 9859 return StmtError(); 9860 } 9861 } 9862 9863 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9864 return StmtError(); 9865 9866 setFunctionHasBranchProtectedScope(); 9867 9868 DSAStack->setParentTeamsRegionLoc(StartLoc); 9869 9870 return OMPTeamsDistributeSimdDirective::Create( 9871 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9872} 9873 9874StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 9875 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9876 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9877 if (!AStmt) 9878 return StmtError(); 9879 9880 auto *CS = cast<CapturedStmt>(AStmt); 9881 // 1.2.2 OpenMP Language Terminology 9882 // Structured block - An executable statement with a single entry at the 9883 // top and a single exit at the bottom. 9884 // The point of exit cannot be a branch out of the structured block. 9885 // longjmp() and throw() must not violate the entry/exit criteria. 9886 CS->getCapturedDecl()->setNothrow(); 9887 9888 for (int ThisCaptureLevel = 9889 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 9890 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9891 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9892 // 1.2.2 OpenMP Language Terminology 9893 // Structured block - An executable statement with a single entry at the 9894 // top and a single exit at the bottom. 9895 // The point of exit cannot be a branch out of the structured block. 9896 // longjmp() and throw() must not violate the entry/exit criteria. 9897 CS->getCapturedDecl()->setNothrow(); 9898 } 9899 9900 OMPLoopDirective::HelperExprs B; 9901 // In presence of clause 'collapse' with number of loops, it will 9902 // define the nested loops number. 9903 unsigned NestedLoopCount = checkOpenMPLoop( 9904 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 9905 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9906 VarsWithImplicitDSA, B); 9907 9908 if (NestedLoopCount == 0) 9909 return StmtError(); 9910 9911 assert((CurContext->isDependentContext() || B.builtAll()) && 9912 "omp for loop exprs were not built"); 9913 9914 if (!CurContext->isDependentContext()) { 9915 // Finalize the clauses that need pre-built expressions for CodeGen. 9916 for (OMPClause *C : Clauses) { 9917 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 9918 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 9919 B.NumIterations, *this, CurScope, 9920 DSAStack)) 9921 return StmtError(); 9922 } 9923 } 9924 9925 if (checkSimdlenSafelenSpecified(*this, Clauses)) 9926 return StmtError(); 9927 9928 setFunctionHasBranchProtectedScope(); 9929 9930 DSAStack->setParentTeamsRegionLoc(StartLoc); 9931 9932 return OMPTeamsDistributeParallelForSimdDirective::Create( 9933 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 9934} 9935 9936StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 9937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 9938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 9939 if (!AStmt) 9940 return StmtError(); 9941 9942 auto *CS = cast<CapturedStmt>(AStmt); 9943 // 1.2.2 OpenMP Language Terminology 9944 // Structured block - An executable statement with a single entry at the 9945 // top and a single exit at the bottom. 9946 // The point of exit cannot be a branch out of the structured block. 9947 // longjmp() and throw() must not violate the entry/exit criteria. 9948 CS->getCapturedDecl()->setNothrow(); 9949 9950 for (int ThisCaptureLevel = 9951 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 9952 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9953 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9954 // 1.2.2 OpenMP Language Terminology 9955 // Structured block - An executable statement with a single entry at the 9956 // top and a single exit at the bottom. 9957 // The point of exit cannot be a branch out of the structured block. 9958 // longjmp() and throw() must not violate the entry/exit criteria. 9959 CS->getCapturedDecl()->setNothrow(); 9960 } 9961 9962 OMPLoopDirective::HelperExprs B; 9963 // In presence of clause 'collapse' with number of loops, it will 9964 // define the nested loops number. 9965 unsigned NestedLoopCount = checkOpenMPLoop( 9966 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 9967 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 9968 VarsWithImplicitDSA, B); 9969 9970 if (NestedLoopCount == 0) 9971 return StmtError(); 9972 9973 assert((CurContext->isDependentContext() || B.builtAll()) && 9974 "omp for loop exprs were not built"); 9975 9976 setFunctionHasBranchProtectedScope(); 9977 9978 DSAStack->setParentTeamsRegionLoc(StartLoc); 9979 9980 return OMPTeamsDistributeParallelForDirective::Create( 9981 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 9982 DSAStack->isCancelRegion()); 9983} 9984 9985StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 9986 Stmt *AStmt, 9987 SourceLocation StartLoc, 9988 SourceLocation EndLoc) { 9989 if (!AStmt) 9990 return StmtError(); 9991 9992 auto *CS = cast<CapturedStmt>(AStmt); 9993 // 1.2.2 OpenMP Language Terminology 9994 // Structured block - An executable statement with a single entry at the 9995 // top and a single exit at the bottom. 9996 // The point of exit cannot be a branch out of the structured block. 9997 // longjmp() and throw() must not violate the entry/exit criteria. 9998 CS->getCapturedDecl()->setNothrow(); 9999 10000 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 10001 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10002 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10003 // 1.2.2 OpenMP Language Terminology 10004 // Structured block - An executable statement with a single entry at the 10005 // top and a single exit at the bottom. 10006 // The point of exit cannot be a branch out of the structured block. 10007 // longjmp() and throw() must not violate the entry/exit criteria. 10008 CS->getCapturedDecl()->setNothrow(); 10009 } 10010 setFunctionHasBranchProtectedScope(); 10011 10012 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 10013 AStmt); 10014} 10015 10016StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 10017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10018 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10019 if (!AStmt) 10020 return StmtError(); 10021 10022 auto *CS = cast<CapturedStmt>(AStmt); 10023 // 1.2.2 OpenMP Language Terminology 10024 // Structured block - An executable statement with a single entry at the 10025 // top and a single exit at the bottom. 10026 // The point of exit cannot be a branch out of the structured block. 10027 // longjmp() and throw() must not violate the entry/exit criteria. 10028 CS->getCapturedDecl()->setNothrow(); 10029 for (int ThisCaptureLevel = 10030 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 10031 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10032 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10033 // 1.2.2 OpenMP Language Terminology 10034 // Structured block - An executable statement with a single entry at the 10035 // top and a single exit at the bottom. 10036 // The point of exit cannot be a branch out of the structured block. 10037 // longjmp() and throw() must not violate the entry/exit criteria. 10038 CS->getCapturedDecl()->setNothrow(); 10039 } 10040 10041 OMPLoopDirective::HelperExprs B; 10042 // In presence of clause 'collapse' with number of loops, it will 10043 // define the nested loops number. 10044 unsigned NestedLoopCount = checkOpenMPLoop( 10045 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 10046 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10047 VarsWithImplicitDSA, B); 10048 if (NestedLoopCount == 0) 10049 return StmtError(); 10050 10051 assert((CurContext->isDependentContext() || B.builtAll()) && 10052 "omp target teams distribute loop exprs were not built"); 10053 10054 setFunctionHasBranchProtectedScope(); 10055 return OMPTargetTeamsDistributeDirective::Create( 10056 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10057} 10058 10059StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 10060 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10061 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10062 if (!AStmt) 10063 return StmtError(); 10064 10065 auto *CS = cast<CapturedStmt>(AStmt); 10066 // 1.2.2 OpenMP Language Terminology 10067 // Structured block - An executable statement with a single entry at the 10068 // top and a single exit at the bottom. 10069 // The point of exit cannot be a branch out of the structured block. 10070 // longjmp() and throw() must not violate the entry/exit criteria. 10071 CS->getCapturedDecl()->setNothrow(); 10072 for (int ThisCaptureLevel = 10073 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 10074 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10075 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10076 // 1.2.2 OpenMP Language Terminology 10077 // Structured block - An executable statement with a single entry at the 10078 // top and a single exit at the bottom. 10079 // The point of exit cannot be a branch out of the structured block. 10080 // longjmp() and throw() must not violate the entry/exit criteria. 10081 CS->getCapturedDecl()->setNothrow(); 10082 } 10083 10084 OMPLoopDirective::HelperExprs B; 10085 // In presence of clause 'collapse' with number of loops, it will 10086 // define the nested loops number. 10087 unsigned NestedLoopCount = checkOpenMPLoop( 10088 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10089 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10090 VarsWithImplicitDSA, B); 10091 if (NestedLoopCount == 0) 10092 return StmtError(); 10093 10094 assert((CurContext->isDependentContext() || B.builtAll()) && 10095 "omp target teams distribute parallel for loop exprs were not built"); 10096 10097 if (!CurContext->isDependentContext()) { 10098 // Finalize the clauses that need pre-built expressions for CodeGen. 10099 for (OMPClause *C : Clauses) { 10100 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10102 B.NumIterations, *this, CurScope, 10103 DSAStack)) 10104 return StmtError(); 10105 } 10106 } 10107 10108 setFunctionHasBranchProtectedScope(); 10109 return OMPTargetTeamsDistributeParallelForDirective::Create( 10110 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10111 DSAStack->isCancelRegion()); 10112} 10113 10114StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 10115 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10116 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10117 if (!AStmt) 10118 return StmtError(); 10119 10120 auto *CS = cast<CapturedStmt>(AStmt); 10121 // 1.2.2 OpenMP Language Terminology 10122 // Structured block - An executable statement with a single entry at the 10123 // top and a single exit at the bottom. 10124 // The point of exit cannot be a branch out of the structured block. 10125 // longjmp() and throw() must not violate the entry/exit criteria. 10126 CS->getCapturedDecl()->setNothrow(); 10127 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 10128 OMPD_target_teams_distribute_parallel_for_simd); 10129 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10130 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10131 // 1.2.2 OpenMP Language Terminology 10132 // Structured block - An executable statement with a single entry at the 10133 // top and a single exit at the bottom. 10134 // The point of exit cannot be a branch out of the structured block. 10135 // longjmp() and throw() must not violate the entry/exit criteria. 10136 CS->getCapturedDecl()->setNothrow(); 10137 } 10138 10139 OMPLoopDirective::HelperExprs B; 10140 // In presence of clause 'collapse' with number of loops, it will 10141 // define the nested loops number. 10142 unsigned NestedLoopCount = 10143 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 10144 getCollapseNumberExpr(Clauses), 10145 nullptr /*ordered not a clause on distribute*/, CS, *this, 10146 *DSAStack, VarsWithImplicitDSA, B); 10147 if (NestedLoopCount == 0) 10148 return StmtError(); 10149 10150 assert((CurContext->isDependentContext() || B.builtAll()) && 10151 "omp target teams distribute parallel for simd loop exprs were not " 10152 "built"); 10153 10154 if (!CurContext->isDependentContext()) { 10155 // Finalize the clauses that need pre-built expressions for CodeGen. 10156 for (OMPClause *C : Clauses) { 10157 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10158 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10159 B.NumIterations, *this, CurScope, 10160 DSAStack)) 10161 return StmtError(); 10162 } 10163 } 10164 10165 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10166 return StmtError(); 10167 10168 setFunctionHasBranchProtectedScope(); 10169 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 10170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10171} 10172 10173StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 10174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10175 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10176 if (!AStmt) 10177 return StmtError(); 10178 10179 auto *CS = cast<CapturedStmt>(AStmt); 10180 // 1.2.2 OpenMP Language Terminology 10181 // Structured block - An executable statement with a single entry at the 10182 // top and a single exit at the bottom. 10183 // The point of exit cannot be a branch out of the structured block. 10184 // longjmp() and throw() must not violate the entry/exit criteria. 10185 CS->getCapturedDecl()->setNothrow(); 10186 for (int ThisCaptureLevel = 10187 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 10188 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10189 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10190 // 1.2.2 OpenMP Language Terminology 10191 // Structured block - An executable statement with a single entry at the 10192 // top and a single exit at the bottom. 10193 // The point of exit cannot be a branch out of the structured block. 10194 // longjmp() and throw() must not violate the entry/exit criteria. 10195 CS->getCapturedDecl()->setNothrow(); 10196 } 10197 10198 OMPLoopDirective::HelperExprs B; 10199 // In presence of clause 'collapse' with number of loops, it will 10200 // define the nested loops number. 10201 unsigned NestedLoopCount = checkOpenMPLoop( 10202 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 10203 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10204 VarsWithImplicitDSA, B); 10205 if (NestedLoopCount == 0) 10206 return StmtError(); 10207 10208 assert((CurContext->isDependentContext() || B.builtAll()) && 10209 "omp target teams distribute simd loop exprs were not built"); 10210 10211 if (!CurContext->isDependentContext()) { 10212 // Finalize the clauses that need pre-built expressions for CodeGen. 10213 for (OMPClause *C : Clauses) { 10214 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10215 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10216 B.NumIterations, *this, CurScope, 10217 DSAStack)) 10218 return StmtError(); 10219 } 10220 } 10221 10222 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10223 return StmtError(); 10224 10225 setFunctionHasBranchProtectedScope(); 10226 return OMPTargetTeamsDistributeSimdDirective::Create( 10227 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10228} 10229 10230OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 10231 SourceLocation StartLoc, 10232 SourceLocation LParenLoc, 10233 SourceLocation EndLoc) { 10234 OMPClause *Res = nullptr; 10235 switch (Kind) { 10236 case OMPC_final: 10237 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 10238 break; 10239 case OMPC_num_threads: 10240 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 10241 break; 10242 case OMPC_safelen: 10243 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 10244 break; 10245 case OMPC_simdlen: 10246 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 10247 break; 10248 case OMPC_allocator: 10249 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 10250 break; 10251 case OMPC_collapse: 10252 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 10253 break; 10254 case OMPC_ordered: 10255 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 10256 break; 10257 case OMPC_device: 10258 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 10259 break; 10260 case OMPC_num_teams: 10261 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 10262 break; 10263 case OMPC_thread_limit: 10264 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 10265 break; 10266 case OMPC_priority: 10267 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 10268 break; 10269 case OMPC_grainsize: 10270 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 10271 break; 10272 case OMPC_num_tasks: 10273 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 10274 break; 10275 case OMPC_hint: 10276 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 10277 break; 10278 case OMPC_if: 10279 case OMPC_default: 10280 case OMPC_proc_bind: 10281 case OMPC_schedule: 10282 case OMPC_private: 10283 case OMPC_firstprivate: 10284 case OMPC_lastprivate: 10285 case OMPC_shared: 10286 case OMPC_reduction: 10287 case OMPC_task_reduction: 10288 case OMPC_in_reduction: 10289 case OMPC_linear: 10290 case OMPC_aligned: 10291 case OMPC_copyin: 10292 case OMPC_copyprivate: 10293 case OMPC_nowait: 10294 case OMPC_untied: 10295 case OMPC_mergeable: 10296 case OMPC_threadprivate: 10297 case OMPC_allocate: 10298 case OMPC_flush: 10299 case OMPC_read: 10300 case OMPC_write: 10301 case OMPC_update: 10302 case OMPC_capture: 10303 case OMPC_seq_cst: 10304 case OMPC_depend: 10305 case OMPC_threads: 10306 case OMPC_simd: 10307 case OMPC_map: 10308 case OMPC_nogroup: 10309 case OMPC_dist_schedule: 10310 case OMPC_defaultmap: 10311 case OMPC_unknown: 10312 case OMPC_uniform: 10313 case OMPC_to: 10314 case OMPC_from: 10315 case OMPC_use_device_ptr: 10316 case OMPC_is_device_ptr: 10317 case OMPC_unified_address: 10318 case OMPC_unified_shared_memory: 10319 case OMPC_reverse_offload: 10320 case OMPC_dynamic_allocators: 10321 case OMPC_atomic_default_mem_order: 10322 case OMPC_device_type: 10323 case OMPC_match: 10324 llvm_unreachable("Clause is not allowed."); 10325 } 10326 return Res; 10327} 10328 10329// An OpenMP directive such as 'target parallel' has two captured regions: 10330// for the 'target' and 'parallel' respectively. This function returns 10331// the region in which to capture expressions associated with a clause. 10332// A return value of OMPD_unknown signifies that the expression should not 10333// be captured. 10334static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 10335 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 10336 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 10337 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10338 switch (CKind) { 10339 case OMPC_if: 10340 switch (DKind) { 10341 case OMPD_target_parallel: 10342 case OMPD_target_parallel_for: 10343 case OMPD_target_parallel_for_simd: 10344 // If this clause applies to the nested 'parallel' region, capture within 10345 // the 'target' region, otherwise do not capture. 10346 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10347 CaptureRegion = OMPD_target; 10348 break; 10349 case OMPD_target_teams_distribute_parallel_for: 10350 case OMPD_target_teams_distribute_parallel_for_simd: 10351 // If this clause applies to the nested 'parallel' region, capture within 10352 // the 'teams' region, otherwise do not capture. 10353 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 10354 CaptureRegion = OMPD_teams; 10355 break; 10356 case OMPD_teams_distribute_parallel_for: 10357 case OMPD_teams_distribute_parallel_for_simd: 10358 CaptureRegion = OMPD_teams; 10359 break; 10360 case OMPD_target_update: 10361 case OMPD_target_enter_data: 10362 case OMPD_target_exit_data: 10363 CaptureRegion = OMPD_task; 10364 break; 10365 case OMPD_parallel_master_taskloop: 10366 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 10367 CaptureRegion = OMPD_parallel; 10368 break; 10369 case OMPD_cancel: 10370 case OMPD_parallel: 10371 case OMPD_parallel_sections: 10372 case OMPD_parallel_for: 10373 case OMPD_parallel_for_simd: 10374 case OMPD_target: 10375 case OMPD_target_simd: 10376 case OMPD_target_teams: 10377 case OMPD_target_teams_distribute: 10378 case OMPD_target_teams_distribute_simd: 10379 case OMPD_distribute_parallel_for: 10380 case OMPD_distribute_parallel_for_simd: 10381 case OMPD_task: 10382 case OMPD_taskloop: 10383 case OMPD_taskloop_simd: 10384 case OMPD_master_taskloop: 10385 case OMPD_master_taskloop_simd: 10386 case OMPD_target_data: 10387 // Do not capture if-clause expressions. 10388 break; 10389 case OMPD_threadprivate: 10390 case OMPD_allocate: 10391 case OMPD_taskyield: 10392 case OMPD_barrier: 10393 case OMPD_taskwait: 10394 case OMPD_cancellation_point: 10395 case OMPD_flush: 10396 case OMPD_declare_reduction: 10397 case OMPD_declare_mapper: 10398 case OMPD_declare_simd: 10399 case OMPD_declare_variant: 10400 case OMPD_declare_target: 10401 case OMPD_end_declare_target: 10402 case OMPD_teams: 10403 case OMPD_simd: 10404 case OMPD_for: 10405 case OMPD_for_simd: 10406 case OMPD_sections: 10407 case OMPD_section: 10408 case OMPD_single: 10409 case OMPD_master: 10410 case OMPD_critical: 10411 case OMPD_taskgroup: 10412 case OMPD_distribute: 10413 case OMPD_ordered: 10414 case OMPD_atomic: 10415 case OMPD_distribute_simd: 10416 case OMPD_teams_distribute: 10417 case OMPD_teams_distribute_simd: 10418 case OMPD_requires: 10419 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 10420 case OMPD_unknown: 10421 llvm_unreachable("Unknown OpenMP directive"); 10422 } 10423 break; 10424 case OMPC_num_threads: 10425 switch (DKind) { 10426 case OMPD_target_parallel: 10427 case OMPD_target_parallel_for: 10428 case OMPD_target_parallel_for_simd: 10429 CaptureRegion = OMPD_target; 10430 break; 10431 case OMPD_teams_distribute_parallel_for: 10432 case OMPD_teams_distribute_parallel_for_simd: 10433 case OMPD_target_teams_distribute_parallel_for: 10434 case OMPD_target_teams_distribute_parallel_for_simd: 10435 CaptureRegion = OMPD_teams; 10436 break; 10437 case OMPD_parallel: 10438 case OMPD_parallel_sections: 10439 case OMPD_parallel_for: 10440 case OMPD_parallel_for_simd: 10441 case OMPD_distribute_parallel_for: 10442 case OMPD_distribute_parallel_for_simd: 10443 case OMPD_parallel_master_taskloop: 10444 // Do not capture num_threads-clause expressions. 10445 break; 10446 case OMPD_target_data: 10447 case OMPD_target_enter_data: 10448 case OMPD_target_exit_data: 10449 case OMPD_target_update: 10450 case OMPD_target: 10451 case OMPD_target_simd: 10452 case OMPD_target_teams: 10453 case OMPD_target_teams_distribute: 10454 case OMPD_target_teams_distribute_simd: 10455 case OMPD_cancel: 10456 case OMPD_task: 10457 case OMPD_taskloop: 10458 case OMPD_taskloop_simd: 10459 case OMPD_master_taskloop: 10460 case OMPD_master_taskloop_simd: 10461 case OMPD_threadprivate: 10462 case OMPD_allocate: 10463 case OMPD_taskyield: 10464 case OMPD_barrier: 10465 case OMPD_taskwait: 10466 case OMPD_cancellation_point: 10467 case OMPD_flush: 10468 case OMPD_declare_reduction: 10469 case OMPD_declare_mapper: 10470 case OMPD_declare_simd: 10471 case OMPD_declare_variant: 10472 case OMPD_declare_target: 10473 case OMPD_end_declare_target: 10474 case OMPD_teams: 10475 case OMPD_simd: 10476 case OMPD_for: 10477 case OMPD_for_simd: 10478 case OMPD_sections: 10479 case OMPD_section: 10480 case OMPD_single: 10481 case OMPD_master: 10482 case OMPD_critical: 10483 case OMPD_taskgroup: 10484 case OMPD_distribute: 10485 case OMPD_ordered: 10486 case OMPD_atomic: 10487 case OMPD_distribute_simd: 10488 case OMPD_teams_distribute: 10489 case OMPD_teams_distribute_simd: 10490 case OMPD_requires: 10491 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 10492 case OMPD_unknown: 10493 llvm_unreachable("Unknown OpenMP directive"); 10494 } 10495 break; 10496 case OMPC_num_teams: 10497 switch (DKind) { 10498 case OMPD_target_teams: 10499 case OMPD_target_teams_distribute: 10500 case OMPD_target_teams_distribute_simd: 10501 case OMPD_target_teams_distribute_parallel_for: 10502 case OMPD_target_teams_distribute_parallel_for_simd: 10503 CaptureRegion = OMPD_target; 10504 break; 10505 case OMPD_teams_distribute_parallel_for: 10506 case OMPD_teams_distribute_parallel_for_simd: 10507 case OMPD_teams: 10508 case OMPD_teams_distribute: 10509 case OMPD_teams_distribute_simd: 10510 // Do not capture num_teams-clause expressions. 10511 break; 10512 case OMPD_distribute_parallel_for: 10513 case OMPD_distribute_parallel_for_simd: 10514 case OMPD_task: 10515 case OMPD_taskloop: 10516 case OMPD_taskloop_simd: 10517 case OMPD_master_taskloop: 10518 case OMPD_master_taskloop_simd: 10519 case OMPD_parallel_master_taskloop: 10520 case OMPD_target_data: 10521 case OMPD_target_enter_data: 10522 case OMPD_target_exit_data: 10523 case OMPD_target_update: 10524 case OMPD_cancel: 10525 case OMPD_parallel: 10526 case OMPD_parallel_sections: 10527 case OMPD_parallel_for: 10528 case OMPD_parallel_for_simd: 10529 case OMPD_target: 10530 case OMPD_target_simd: 10531 case OMPD_target_parallel: 10532 case OMPD_target_parallel_for: 10533 case OMPD_target_parallel_for_simd: 10534 case OMPD_threadprivate: 10535 case OMPD_allocate: 10536 case OMPD_taskyield: 10537 case OMPD_barrier: 10538 case OMPD_taskwait: 10539 case OMPD_cancellation_point: 10540 case OMPD_flush: 10541 case OMPD_declare_reduction: 10542 case OMPD_declare_mapper: 10543 case OMPD_declare_simd: 10544 case OMPD_declare_variant: 10545 case OMPD_declare_target: 10546 case OMPD_end_declare_target: 10547 case OMPD_simd: 10548 case OMPD_for: 10549 case OMPD_for_simd: 10550 case OMPD_sections: 10551 case OMPD_section: 10552 case OMPD_single: 10553 case OMPD_master: 10554 case OMPD_critical: 10555 case OMPD_taskgroup: 10556 case OMPD_distribute: 10557 case OMPD_ordered: 10558 case OMPD_atomic: 10559 case OMPD_distribute_simd: 10560 case OMPD_requires: 10561 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10562 case OMPD_unknown: 10563 llvm_unreachable("Unknown OpenMP directive"); 10564 } 10565 break; 10566 case OMPC_thread_limit: 10567 switch (DKind) { 10568 case OMPD_target_teams: 10569 case OMPD_target_teams_distribute: 10570 case OMPD_target_teams_distribute_simd: 10571 case OMPD_target_teams_distribute_parallel_for: 10572 case OMPD_target_teams_distribute_parallel_for_simd: 10573 CaptureRegion = OMPD_target; 10574 break; 10575 case OMPD_teams_distribute_parallel_for: 10576 case OMPD_teams_distribute_parallel_for_simd: 10577 case OMPD_teams: 10578 case OMPD_teams_distribute: 10579 case OMPD_teams_distribute_simd: 10580 // Do not capture thread_limit-clause expressions. 10581 break; 10582 case OMPD_distribute_parallel_for: 10583 case OMPD_distribute_parallel_for_simd: 10584 case OMPD_task: 10585 case OMPD_taskloop: 10586 case OMPD_taskloop_simd: 10587 case OMPD_master_taskloop: 10588 case OMPD_master_taskloop_simd: 10589 case OMPD_parallel_master_taskloop: 10590 case OMPD_target_data: 10591 case OMPD_target_enter_data: 10592 case OMPD_target_exit_data: 10593 case OMPD_target_update: 10594 case OMPD_cancel: 10595 case OMPD_parallel: 10596 case OMPD_parallel_sections: 10597 case OMPD_parallel_for: 10598 case OMPD_parallel_for_simd: 10599 case OMPD_target: 10600 case OMPD_target_simd: 10601 case OMPD_target_parallel: 10602 case OMPD_target_parallel_for: 10603 case OMPD_target_parallel_for_simd: 10604 case OMPD_threadprivate: 10605 case OMPD_allocate: 10606 case OMPD_taskyield: 10607 case OMPD_barrier: 10608 case OMPD_taskwait: 10609 case OMPD_cancellation_point: 10610 case OMPD_flush: 10611 case OMPD_declare_reduction: 10612 case OMPD_declare_mapper: 10613 case OMPD_declare_simd: 10614 case OMPD_declare_variant: 10615 case OMPD_declare_target: 10616 case OMPD_end_declare_target: 10617 case OMPD_simd: 10618 case OMPD_for: 10619 case OMPD_for_simd: 10620 case OMPD_sections: 10621 case OMPD_section: 10622 case OMPD_single: 10623 case OMPD_master: 10624 case OMPD_critical: 10625 case OMPD_taskgroup: 10626 case OMPD_distribute: 10627 case OMPD_ordered: 10628 case OMPD_atomic: 10629 case OMPD_distribute_simd: 10630 case OMPD_requires: 10631 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 10632 case OMPD_unknown: 10633 llvm_unreachable("Unknown OpenMP directive"); 10634 } 10635 break; 10636 case OMPC_schedule: 10637 switch (DKind) { 10638 case OMPD_parallel_for: 10639 case OMPD_parallel_for_simd: 10640 case OMPD_distribute_parallel_for: 10641 case OMPD_distribute_parallel_for_simd: 10642 case OMPD_teams_distribute_parallel_for: 10643 case OMPD_teams_distribute_parallel_for_simd: 10644 case OMPD_target_parallel_for: 10645 case OMPD_target_parallel_for_simd: 10646 case OMPD_target_teams_distribute_parallel_for: 10647 case OMPD_target_teams_distribute_parallel_for_simd: 10648 CaptureRegion = OMPD_parallel; 10649 break; 10650 case OMPD_for: 10651 case OMPD_for_simd: 10652 // Do not capture schedule-clause expressions. 10653 break; 10654 case OMPD_task: 10655 case OMPD_taskloop: 10656 case OMPD_taskloop_simd: 10657 case OMPD_master_taskloop: 10658 case OMPD_master_taskloop_simd: 10659 case OMPD_parallel_master_taskloop: 10660 case OMPD_target_data: 10661 case OMPD_target_enter_data: 10662 case OMPD_target_exit_data: 10663 case OMPD_target_update: 10664 case OMPD_teams: 10665 case OMPD_teams_distribute: 10666 case OMPD_teams_distribute_simd: 10667 case OMPD_target_teams_distribute: 10668 case OMPD_target_teams_distribute_simd: 10669 case OMPD_target: 10670 case OMPD_target_simd: 10671 case OMPD_target_parallel: 10672 case OMPD_cancel: 10673 case OMPD_parallel: 10674 case OMPD_parallel_sections: 10675 case OMPD_threadprivate: 10676 case OMPD_allocate: 10677 case OMPD_taskyield: 10678 case OMPD_barrier: 10679 case OMPD_taskwait: 10680 case OMPD_cancellation_point: 10681 case OMPD_flush: 10682 case OMPD_declare_reduction: 10683 case OMPD_declare_mapper: 10684 case OMPD_declare_simd: 10685 case OMPD_declare_variant: 10686 case OMPD_declare_target: 10687 case OMPD_end_declare_target: 10688 case OMPD_simd: 10689 case OMPD_sections: 10690 case OMPD_section: 10691 case OMPD_single: 10692 case OMPD_master: 10693 case OMPD_critical: 10694 case OMPD_taskgroup: 10695 case OMPD_distribute: 10696 case OMPD_ordered: 10697 case OMPD_atomic: 10698 case OMPD_distribute_simd: 10699 case OMPD_target_teams: 10700 case OMPD_requires: 10701 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10702 case OMPD_unknown: 10703 llvm_unreachable("Unknown OpenMP directive"); 10704 } 10705 break; 10706 case OMPC_dist_schedule: 10707 switch (DKind) { 10708 case OMPD_teams_distribute_parallel_for: 10709 case OMPD_teams_distribute_parallel_for_simd: 10710 case OMPD_teams_distribute: 10711 case OMPD_teams_distribute_simd: 10712 case OMPD_target_teams_distribute_parallel_for: 10713 case OMPD_target_teams_distribute_parallel_for_simd: 10714 case OMPD_target_teams_distribute: 10715 case OMPD_target_teams_distribute_simd: 10716 CaptureRegion = OMPD_teams; 10717 break; 10718 case OMPD_distribute_parallel_for: 10719 case OMPD_distribute_parallel_for_simd: 10720 case OMPD_distribute: 10721 case OMPD_distribute_simd: 10722 // Do not capture thread_limit-clause expressions. 10723 break; 10724 case OMPD_parallel_for: 10725 case OMPD_parallel_for_simd: 10726 case OMPD_target_parallel_for_simd: 10727 case OMPD_target_parallel_for: 10728 case OMPD_task: 10729 case OMPD_taskloop: 10730 case OMPD_taskloop_simd: 10731 case OMPD_master_taskloop: 10732 case OMPD_master_taskloop_simd: 10733 case OMPD_parallel_master_taskloop: 10734 case OMPD_target_data: 10735 case OMPD_target_enter_data: 10736 case OMPD_target_exit_data: 10737 case OMPD_target_update: 10738 case OMPD_teams: 10739 case OMPD_target: 10740 case OMPD_target_simd: 10741 case OMPD_target_parallel: 10742 case OMPD_cancel: 10743 case OMPD_parallel: 10744 case OMPD_parallel_sections: 10745 case OMPD_threadprivate: 10746 case OMPD_allocate: 10747 case OMPD_taskyield: 10748 case OMPD_barrier: 10749 case OMPD_taskwait: 10750 case OMPD_cancellation_point: 10751 case OMPD_flush: 10752 case OMPD_declare_reduction: 10753 case OMPD_declare_mapper: 10754 case OMPD_declare_simd: 10755 case OMPD_declare_variant: 10756 case OMPD_declare_target: 10757 case OMPD_end_declare_target: 10758 case OMPD_simd: 10759 case OMPD_for: 10760 case OMPD_for_simd: 10761 case OMPD_sections: 10762 case OMPD_section: 10763 case OMPD_single: 10764 case OMPD_master: 10765 case OMPD_critical: 10766 case OMPD_taskgroup: 10767 case OMPD_ordered: 10768 case OMPD_atomic: 10769 case OMPD_target_teams: 10770 case OMPD_requires: 10771 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 10772 case OMPD_unknown: 10773 llvm_unreachable("Unknown OpenMP directive"); 10774 } 10775 break; 10776 case OMPC_device: 10777 switch (DKind) { 10778 case OMPD_target_update: 10779 case OMPD_target_enter_data: 10780 case OMPD_target_exit_data: 10781 case OMPD_target: 10782 case OMPD_target_simd: 10783 case OMPD_target_teams: 10784 case OMPD_target_parallel: 10785 case OMPD_target_teams_distribute: 10786 case OMPD_target_teams_distribute_simd: 10787 case OMPD_target_parallel_for: 10788 case OMPD_target_parallel_for_simd: 10789 case OMPD_target_teams_distribute_parallel_for: 10790 case OMPD_target_teams_distribute_parallel_for_simd: 10791 CaptureRegion = OMPD_task; 10792 break; 10793 case OMPD_target_data: 10794 // Do not capture device-clause expressions. 10795 break; 10796 case OMPD_teams_distribute_parallel_for: 10797 case OMPD_teams_distribute_parallel_for_simd: 10798 case OMPD_teams: 10799 case OMPD_teams_distribute: 10800 case OMPD_teams_distribute_simd: 10801 case OMPD_distribute_parallel_for: 10802 case OMPD_distribute_parallel_for_simd: 10803 case OMPD_task: 10804 case OMPD_taskloop: 10805 case OMPD_taskloop_simd: 10806 case OMPD_master_taskloop: 10807 case OMPD_master_taskloop_simd: 10808 case OMPD_parallel_master_taskloop: 10809 case OMPD_cancel: 10810 case OMPD_parallel: 10811 case OMPD_parallel_sections: 10812 case OMPD_parallel_for: 10813 case OMPD_parallel_for_simd: 10814 case OMPD_threadprivate: 10815 case OMPD_allocate: 10816 case OMPD_taskyield: 10817 case OMPD_barrier: 10818 case OMPD_taskwait: 10819 case OMPD_cancellation_point: 10820 case OMPD_flush: 10821 case OMPD_declare_reduction: 10822 case OMPD_declare_mapper: 10823 case OMPD_declare_simd: 10824 case OMPD_declare_variant: 10825 case OMPD_declare_target: 10826 case OMPD_end_declare_target: 10827 case OMPD_simd: 10828 case OMPD_for: 10829 case OMPD_for_simd: 10830 case OMPD_sections: 10831 case OMPD_section: 10832 case OMPD_single: 10833 case OMPD_master: 10834 case OMPD_critical: 10835 case OMPD_taskgroup: 10836 case OMPD_distribute: 10837 case OMPD_ordered: 10838 case OMPD_atomic: 10839 case OMPD_distribute_simd: 10840 case OMPD_requires: 10841 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 10842 case OMPD_unknown: 10843 llvm_unreachable("Unknown OpenMP directive"); 10844 } 10845 break; 10846 case OMPC_grainsize: 10847 case OMPC_num_tasks: 10848 case OMPC_final: 10849 case OMPC_priority: 10850 switch (DKind) { 10851 case OMPD_task: 10852 case OMPD_taskloop: 10853 case OMPD_taskloop_simd: 10854 case OMPD_master_taskloop: 10855 case OMPD_master_taskloop_simd: 10856 break; 10857 case OMPD_parallel_master_taskloop: 10858 CaptureRegion = OMPD_parallel; 10859 break; 10860 case OMPD_target_update: 10861 case OMPD_target_enter_data: 10862 case OMPD_target_exit_data: 10863 case OMPD_target: 10864 case OMPD_target_simd: 10865 case OMPD_target_teams: 10866 case OMPD_target_parallel: 10867 case OMPD_target_teams_distribute: 10868 case OMPD_target_teams_distribute_simd: 10869 case OMPD_target_parallel_for: 10870 case OMPD_target_parallel_for_simd: 10871 case OMPD_target_teams_distribute_parallel_for: 10872 case OMPD_target_teams_distribute_parallel_for_simd: 10873 case OMPD_target_data: 10874 case OMPD_teams_distribute_parallel_for: 10875 case OMPD_teams_distribute_parallel_for_simd: 10876 case OMPD_teams: 10877 case OMPD_teams_distribute: 10878 case OMPD_teams_distribute_simd: 10879 case OMPD_distribute_parallel_for: 10880 case OMPD_distribute_parallel_for_simd: 10881 case OMPD_cancel: 10882 case OMPD_parallel: 10883 case OMPD_parallel_sections: 10884 case OMPD_parallel_for: 10885 case OMPD_parallel_for_simd: 10886 case OMPD_threadprivate: 10887 case OMPD_allocate: 10888 case OMPD_taskyield: 10889 case OMPD_barrier: 10890 case OMPD_taskwait: 10891 case OMPD_cancellation_point: 10892 case OMPD_flush: 10893 case OMPD_declare_reduction: 10894 case OMPD_declare_mapper: 10895 case OMPD_declare_simd: 10896 case OMPD_declare_variant: 10897 case OMPD_declare_target: 10898 case OMPD_end_declare_target: 10899 case OMPD_simd: 10900 case OMPD_for: 10901 case OMPD_for_simd: 10902 case OMPD_sections: 10903 case OMPD_section: 10904 case OMPD_single: 10905 case OMPD_master: 10906 case OMPD_critical: 10907 case OMPD_taskgroup: 10908 case OMPD_distribute: 10909 case OMPD_ordered: 10910 case OMPD_atomic: 10911 case OMPD_distribute_simd: 10912 case OMPD_requires: 10913 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 10914 case OMPD_unknown: 10915 llvm_unreachable("Unknown OpenMP directive"); 10916 } 10917 break; 10918 case OMPC_firstprivate: 10919 case OMPC_lastprivate: 10920 case OMPC_reduction: 10921 case OMPC_task_reduction: 10922 case OMPC_in_reduction: 10923 case OMPC_linear: 10924 case OMPC_default: 10925 case OMPC_proc_bind: 10926 case OMPC_safelen: 10927 case OMPC_simdlen: 10928 case OMPC_allocator: 10929 case OMPC_collapse: 10930 case OMPC_private: 10931 case OMPC_shared: 10932 case OMPC_aligned: 10933 case OMPC_copyin: 10934 case OMPC_copyprivate: 10935 case OMPC_ordered: 10936 case OMPC_nowait: 10937 case OMPC_untied: 10938 case OMPC_mergeable: 10939 case OMPC_threadprivate: 10940 case OMPC_allocate: 10941 case OMPC_flush: 10942 case OMPC_read: 10943 case OMPC_write: 10944 case OMPC_update: 10945 case OMPC_capture: 10946 case OMPC_seq_cst: 10947 case OMPC_depend: 10948 case OMPC_threads: 10949 case OMPC_simd: 10950 case OMPC_map: 10951 case OMPC_nogroup: 10952 case OMPC_hint: 10953 case OMPC_defaultmap: 10954 case OMPC_unknown: 10955 case OMPC_uniform: 10956 case OMPC_to: 10957 case OMPC_from: 10958 case OMPC_use_device_ptr: 10959 case OMPC_is_device_ptr: 10960 case OMPC_unified_address: 10961 case OMPC_unified_shared_memory: 10962 case OMPC_reverse_offload: 10963 case OMPC_dynamic_allocators: 10964 case OMPC_atomic_default_mem_order: 10965 case OMPC_device_type: 10966 case OMPC_match: 10967 llvm_unreachable("Unexpected OpenMP clause."); 10968 } 10969 return CaptureRegion; 10970} 10971 10972OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 10973 Expr *Condition, SourceLocation StartLoc, 10974 SourceLocation LParenLoc, 10975 SourceLocation NameModifierLoc, 10976 SourceLocation ColonLoc, 10977 SourceLocation EndLoc) { 10978 Expr *ValExpr = Condition; 10979 Stmt *HelperValStmt = nullptr; 10980 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 10981 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 10982 !Condition->isInstantiationDependent() && 10983 !Condition->containsUnexpandedParameterPack()) { 10984 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 10985 if (Val.isInvalid()) 10986 return nullptr; 10987 10988 ValExpr = Val.get(); 10989 10990 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10991 CaptureRegion = 10992 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 10993 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 10994 ValExpr = MakeFullExpr(ValExpr).get(); 10995 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 10996 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10997 HelperValStmt = buildPreInits(Context, Captures); 10998 } 10999 } 11000 11001 return new (Context) 11002 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 11003 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 11004} 11005 11006OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 11007 SourceLocation StartLoc, 11008 SourceLocation LParenLoc, 11009 SourceLocation EndLoc) { 11010 Expr *ValExpr = Condition; 11011 Stmt *HelperValStmt = nullptr; 11012 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11013 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 11014 !Condition->isInstantiationDependent() && 11015 !Condition->containsUnexpandedParameterPack()) { 11016 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 11017 if (Val.isInvalid()) 11018 return nullptr; 11019 11020 ValExpr = MakeFullExpr(Val.get()).get(); 11021 11022 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11023 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final); 11024 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11025 ValExpr = MakeFullExpr(ValExpr).get(); 11026 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11027 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11028 HelperValStmt = buildPreInits(Context, Captures); 11029 } 11030 } 11031 11032 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 11033 StartLoc, LParenLoc, EndLoc); 11034} 11035 11036ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 11037 Expr *Op) { 11038 if (!Op) 11039 return ExprError(); 11040 11041 class IntConvertDiagnoser : public ICEConvertDiagnoser { 11042 public: 11043 IntConvertDiagnoser() 11044 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 11045 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 11046 QualType T) override { 11047 return S.Diag(Loc, diag::err_omp_not_integral) << T; 11048 } 11049 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 11050 QualType T) override { 11051 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 11052 } 11053 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 11054 QualType T, 11055 QualType ConvTy) override { 11056 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 11057 } 11058 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 11059 QualType ConvTy) override { 11060 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11061 << ConvTy->isEnumeralType() << ConvTy; 11062 } 11063 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 11064 QualType T) override { 11065 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 11066 } 11067 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 11068 QualType ConvTy) override { 11069 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 11070 << ConvTy->isEnumeralType() << ConvTy; 11071 } 11072 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 11073 QualType) override { 11074 llvm_unreachable("conversion functions are permitted"); 11075 } 11076 } ConvertDiagnoser; 11077 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 11078} 11079 11080static bool 11081isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 11082 bool StrictlyPositive, bool BuildCapture = false, 11083 OpenMPDirectiveKind DKind = OMPD_unknown, 11084 OpenMPDirectiveKind *CaptureRegion = nullptr, 11085 Stmt **HelperValStmt = nullptr) { 11086 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 11087 !ValExpr->isInstantiationDependent()) { 11088 SourceLocation Loc = ValExpr->getExprLoc(); 11089 ExprResult Value = 11090 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 11091 if (Value.isInvalid()) 11092 return false; 11093 11094 ValExpr = Value.get(); 11095 // The expression must evaluate to a non-negative integer value. 11096 llvm::APSInt Result; 11097 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 11098 Result.isSigned() && 11099 !((!StrictlyPositive && Result.isNonNegative()) || 11100 (StrictlyPositive && Result.isStrictlyPositive()))) { 11101 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 11102 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11103 << ValExpr->getSourceRange(); 11104 return false; 11105 } 11106 if (!BuildCapture) 11107 return true; 11108 *CaptureRegion = getOpenMPCaptureRegionForClause(DKind, CKind); 11109 if (*CaptureRegion != OMPD_unknown && 11110 !SemaRef.CurContext->isDependentContext()) { 11111 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 11112 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11113 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 11114 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 11115 } 11116 } 11117 return true; 11118} 11119 11120OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 11121 SourceLocation StartLoc, 11122 SourceLocation LParenLoc, 11123 SourceLocation EndLoc) { 11124 Expr *ValExpr = NumThreads; 11125 Stmt *HelperValStmt = nullptr; 11126 11127 // OpenMP [2.5, Restrictions] 11128 // The num_threads expression must evaluate to a positive integer value. 11129 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 11130 /*StrictlyPositive=*/true)) 11131 return nullptr; 11132 11133 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11134 OpenMPDirectiveKind CaptureRegion = 11135 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 11136 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11137 ValExpr = MakeFullExpr(ValExpr).get(); 11138 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11139 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11140 HelperValStmt = buildPreInits(Context, Captures); 11141 } 11142 11143 return new (Context) OMPNumThreadsClause( 11144 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11145} 11146 11147ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 11148 OpenMPClauseKind CKind, 11149 bool StrictlyPositive) { 11150 if (!E) 11151 return ExprError(); 11152 if (E->isValueDependent() || E->isTypeDependent() || 11153 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 11154 return E; 11155 llvm::APSInt Result; 11156 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 11157 if (ICE.isInvalid()) 11158 return ExprError(); 11159 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 11160 (!StrictlyPositive && !Result.isNonNegative())) { 11161 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 11162 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 11163 << E->getSourceRange(); 11164 return ExprError(); 11165 } 11166 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 11167 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 11168 << E->getSourceRange(); 11169 return ExprError(); 11170 } 11171 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 11172 DSAStack->setAssociatedLoops(Result.getExtValue()); 11173 else if (CKind == OMPC_ordered) 11174 DSAStack->setAssociatedLoops(Result.getExtValue()); 11175 return ICE; 11176} 11177 11178OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 11179 SourceLocation LParenLoc, 11180 SourceLocation EndLoc) { 11181 // OpenMP [2.8.1, simd construct, Description] 11182 // The parameter of the safelen clause must be a constant 11183 // positive integer expression. 11184 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 11185 if (Safelen.isInvalid()) 11186 return nullptr; 11187 return new (Context) 11188 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 11189} 11190 11191OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 11192 SourceLocation LParenLoc, 11193 SourceLocation EndLoc) { 11194 // OpenMP [2.8.1, simd construct, Description] 11195 // The parameter of the simdlen clause must be a constant 11196 // positive integer expression. 11197 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 11198 if (Simdlen.isInvalid()) 11199 return nullptr; 11200 return new (Context) 11201 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 11202} 11203 11204/// Tries to find omp_allocator_handle_t type. 11205static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 11206 DSAStackTy *Stack) { 11207 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 11208 if (!OMPAllocatorHandleT.isNull()) 11209 return true; 11210 // Build the predefined allocator expressions. 11211 bool ErrorFound = false; 11212 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 11213 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 11214 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 11215 StringRef Allocator = 11216 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 11217 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 11218 auto *VD = dyn_cast_or_null<ValueDecl>( 11219 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 11220 if (!VD) { 11221 ErrorFound = true; 11222 break; 11223 } 11224 QualType AllocatorType = 11225 VD->getType().getNonLValueExprType(S.getASTContext()); 11226 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 11227 if (!Res.isUsable()) { 11228 ErrorFound = true; 11229 break; 11230 } 11231 if (OMPAllocatorHandleT.isNull()) 11232 OMPAllocatorHandleT = AllocatorType; 11233 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 11234 ErrorFound = true; 11235 break; 11236 } 11237 Stack->setAllocator(AllocatorKind, Res.get()); 11238 } 11239 if (ErrorFound) { 11240 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 11241 return false; 11242 } 11243 OMPAllocatorHandleT.addConst(); 11244 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 11245 return true; 11246} 11247 11248OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 11249 SourceLocation LParenLoc, 11250 SourceLocation EndLoc) { 11251 // OpenMP [2.11.3, allocate Directive, Description] 11252 // allocator is an expression of omp_allocator_handle_t type. 11253 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 11254 return nullptr; 11255 11256 ExprResult Allocator = DefaultLvalueConversion(A); 11257 if (Allocator.isInvalid()) 11258 return nullptr; 11259 Allocator = PerformImplicitConversion(Allocator.get(), 11260 DSAStack->getOMPAllocatorHandleT(), 11261 Sema::AA_Initializing, 11262 /*AllowExplicit=*/true); 11263 if (Allocator.isInvalid()) 11264 return nullptr; 11265 return new (Context) 11266 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 11267} 11268 11269OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 11270 SourceLocation StartLoc, 11271 SourceLocation LParenLoc, 11272 SourceLocation EndLoc) { 11273 // OpenMP [2.7.1, loop construct, Description] 11274 // OpenMP [2.8.1, simd construct, Description] 11275 // OpenMP [2.9.6, distribute construct, Description] 11276 // The parameter of the collapse clause must be a constant 11277 // positive integer expression. 11278 ExprResult NumForLoopsResult = 11279 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 11280 if (NumForLoopsResult.isInvalid()) 11281 return nullptr; 11282 return new (Context) 11283 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 11284} 11285 11286OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 11287 SourceLocation EndLoc, 11288 SourceLocation LParenLoc, 11289 Expr *NumForLoops) { 11290 // OpenMP [2.7.1, loop construct, Description] 11291 // OpenMP [2.8.1, simd construct, Description] 11292 // OpenMP [2.9.6, distribute construct, Description] 11293 // The parameter of the ordered clause must be a constant 11294 // positive integer expression if any. 11295 if (NumForLoops && LParenLoc.isValid()) { 11296 ExprResult NumForLoopsResult = 11297 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 11298 if (NumForLoopsResult.isInvalid()) 11299 return nullptr; 11300 NumForLoops = NumForLoopsResult.get(); 11301 } else { 11302 NumForLoops = nullptr; 11303 } 11304 auto *Clause = OMPOrderedClause::Create( 11305 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 11306 StartLoc, LParenLoc, EndLoc); 11307 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 11308 return Clause; 11309} 11310 11311OMPClause *Sema::ActOnOpenMPSimpleClause( 11312 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 11313 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11314 OMPClause *Res = nullptr; 11315 switch (Kind) { 11316 case OMPC_default: 11317 Res = 11318 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 11319 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11320 break; 11321 case OMPC_proc_bind: 11322 Res = ActOnOpenMPProcBindClause( 11323 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 11324 LParenLoc, EndLoc); 11325 break; 11326 case OMPC_atomic_default_mem_order: 11327 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 11328 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 11329 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 11330 break; 11331 case OMPC_if: 11332 case OMPC_final: 11333 case OMPC_num_threads: 11334 case OMPC_safelen: 11335 case OMPC_simdlen: 11336 case OMPC_allocator: 11337 case OMPC_collapse: 11338 case OMPC_schedule: 11339 case OMPC_private: 11340 case OMPC_firstprivate: 11341 case OMPC_lastprivate: 11342 case OMPC_shared: 11343 case OMPC_reduction: 11344 case OMPC_task_reduction: 11345 case OMPC_in_reduction: 11346 case OMPC_linear: 11347 case OMPC_aligned: 11348 case OMPC_copyin: 11349 case OMPC_copyprivate: 11350 case OMPC_ordered: 11351 case OMPC_nowait: 11352 case OMPC_untied: 11353 case OMPC_mergeable: 11354 case OMPC_threadprivate: 11355 case OMPC_allocate: 11356 case OMPC_flush: 11357 case OMPC_read: 11358 case OMPC_write: 11359 case OMPC_update: 11360 case OMPC_capture: 11361 case OMPC_seq_cst: 11362 case OMPC_depend: 11363 case OMPC_device: 11364 case OMPC_threads: 11365 case OMPC_simd: 11366 case OMPC_map: 11367 case OMPC_num_teams: 11368 case OMPC_thread_limit: 11369 case OMPC_priority: 11370 case OMPC_grainsize: 11371 case OMPC_nogroup: 11372 case OMPC_num_tasks: 11373 case OMPC_hint: 11374 case OMPC_dist_schedule: 11375 case OMPC_defaultmap: 11376 case OMPC_unknown: 11377 case OMPC_uniform: 11378 case OMPC_to: 11379 case OMPC_from: 11380 case OMPC_use_device_ptr: 11381 case OMPC_is_device_ptr: 11382 case OMPC_unified_address: 11383 case OMPC_unified_shared_memory: 11384 case OMPC_reverse_offload: 11385 case OMPC_dynamic_allocators: 11386 case OMPC_device_type: 11387 case OMPC_match: 11388 llvm_unreachable("Clause is not allowed."); 11389 } 11390 return Res; 11391} 11392 11393static std::string 11394getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 11395 ArrayRef<unsigned> Exclude = llvm::None) { 11396 SmallString<256> Buffer; 11397 llvm::raw_svector_ostream Out(Buffer); 11398 unsigned Bound = Last >= 2 ? Last - 2 : 0; 11399 unsigned Skipped = Exclude.size(); 11400 auto S = Exclude.begin(), E = Exclude.end(); 11401 for (unsigned I = First; I < Last; ++I) { 11402 if (std::find(S, E, I) != E) { 11403 --Skipped; 11404 continue; 11405 } 11406 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 11407 if (I == Bound - Skipped) 11408 Out << " or "; 11409 else if (I != Bound + 1 - Skipped) 11410 Out << ", "; 11411 } 11412 return Out.str(); 11413} 11414 11415OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 11416 SourceLocation KindKwLoc, 11417 SourceLocation StartLoc, 11418 SourceLocation LParenLoc, 11419 SourceLocation EndLoc) { 11420 if (Kind == OMPC_DEFAULT_unknown) { 11421 static_assert(OMPC_DEFAULT_unknown > 0, 11422 "OMPC_DEFAULT_unknown not greater than 0"); 11423 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11424 << getListOfPossibleValues(OMPC_default, /*First=*/0, 11425 /*Last=*/OMPC_DEFAULT_unknown) 11426 << getOpenMPClauseName(OMPC_default); 11427 return nullptr; 11428 } 11429 switch (Kind) { 11430 case OMPC_DEFAULT_none: 11431 DSAStack->setDefaultDSANone(KindKwLoc); 11432 break; 11433 case OMPC_DEFAULT_shared: 11434 DSAStack->setDefaultDSAShared(KindKwLoc); 11435 break; 11436 case OMPC_DEFAULT_unknown: 11437 llvm_unreachable("Clause kind is not allowed."); 11438 break; 11439 } 11440 return new (Context) 11441 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11442} 11443 11444OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 11445 SourceLocation KindKwLoc, 11446 SourceLocation StartLoc, 11447 SourceLocation LParenLoc, 11448 SourceLocation EndLoc) { 11449 if (Kind == OMPC_PROC_BIND_unknown) { 11450 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11451 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 11452 /*Last=*/OMPC_PROC_BIND_unknown) 11453 << getOpenMPClauseName(OMPC_proc_bind); 11454 return nullptr; 11455 } 11456 return new (Context) 11457 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 11458} 11459 11460OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 11461 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 11462 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 11463 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 11464 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 11465 << getListOfPossibleValues( 11466 OMPC_atomic_default_mem_order, /*First=*/0, 11467 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 11468 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 11469 return nullptr; 11470 } 11471 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 11472 LParenLoc, EndLoc); 11473} 11474 11475OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 11476 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 11477 SourceLocation StartLoc, SourceLocation LParenLoc, 11478 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 11479 SourceLocation EndLoc) { 11480 OMPClause *Res = nullptr; 11481 switch (Kind) { 11482 case OMPC_schedule: 11483 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 11484 assert(Argument.size() == NumberOfElements && 11485 ArgumentLoc.size() == NumberOfElements); 11486 Res = ActOnOpenMPScheduleClause( 11487 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 11488 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 11489 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 11490 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 11491 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 11492 break; 11493 case OMPC_if: 11494 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 11495 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 11496 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 11497 DelimLoc, EndLoc); 11498 break; 11499 case OMPC_dist_schedule: 11500 Res = ActOnOpenMPDistScheduleClause( 11501 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 11502 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 11503 break; 11504 case OMPC_defaultmap: 11505 enum { Modifier, DefaultmapKind }; 11506 Res = ActOnOpenMPDefaultmapClause( 11507 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 11508 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 11509 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 11510 EndLoc); 11511 break; 11512 case OMPC_final: 11513 case OMPC_num_threads: 11514 case OMPC_safelen: 11515 case OMPC_simdlen: 11516 case OMPC_allocator: 11517 case OMPC_collapse: 11518 case OMPC_default: 11519 case OMPC_proc_bind: 11520 case OMPC_private: 11521 case OMPC_firstprivate: 11522 case OMPC_lastprivate: 11523 case OMPC_shared: 11524 case OMPC_reduction: 11525 case OMPC_task_reduction: 11526 case OMPC_in_reduction: 11527 case OMPC_linear: 11528 case OMPC_aligned: 11529 case OMPC_copyin: 11530 case OMPC_copyprivate: 11531 case OMPC_ordered: 11532 case OMPC_nowait: 11533 case OMPC_untied: 11534 case OMPC_mergeable: 11535 case OMPC_threadprivate: 11536 case OMPC_allocate: 11537 case OMPC_flush: 11538 case OMPC_read: 11539 case OMPC_write: 11540 case OMPC_update: 11541 case OMPC_capture: 11542 case OMPC_seq_cst: 11543 case OMPC_depend: 11544 case OMPC_device: 11545 case OMPC_threads: 11546 case OMPC_simd: 11547 case OMPC_map: 11548 case OMPC_num_teams: 11549 case OMPC_thread_limit: 11550 case OMPC_priority: 11551 case OMPC_grainsize: 11552 case OMPC_nogroup: 11553 case OMPC_num_tasks: 11554 case OMPC_hint: 11555 case OMPC_unknown: 11556 case OMPC_uniform: 11557 case OMPC_to: 11558 case OMPC_from: 11559 case OMPC_use_device_ptr: 11560 case OMPC_is_device_ptr: 11561 case OMPC_unified_address: 11562 case OMPC_unified_shared_memory: 11563 case OMPC_reverse_offload: 11564 case OMPC_dynamic_allocators: 11565 case OMPC_atomic_default_mem_order: 11566 case OMPC_device_type: 11567 case OMPC_match: 11568 llvm_unreachable("Clause is not allowed."); 11569 } 11570 return Res; 11571} 11572 11573static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 11574 OpenMPScheduleClauseModifier M2, 11575 SourceLocation M1Loc, SourceLocation M2Loc) { 11576 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 11577 SmallVector<unsigned, 2> Excluded; 11578 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 11579 Excluded.push_back(M2); 11580 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 11581 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 11582 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 11583 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 11584 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 11585 << getListOfPossibleValues(OMPC_schedule, 11586 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 11587 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11588 Excluded) 11589 << getOpenMPClauseName(OMPC_schedule); 11590 return true; 11591 } 11592 return false; 11593} 11594 11595OMPClause *Sema::ActOnOpenMPScheduleClause( 11596 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 11597 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11598 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 11599 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 11600 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 11601 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 11602 return nullptr; 11603 // OpenMP, 2.7.1, Loop Construct, Restrictions 11604 // Either the monotonic modifier or the nonmonotonic modifier can be specified 11605 // but not both. 11606 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 11607 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 11608 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 11609 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 11610 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 11611 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 11612 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 11613 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 11614 return nullptr; 11615 } 11616 if (Kind == OMPC_SCHEDULE_unknown) { 11617 std::string Values; 11618 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 11619 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 11620 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11621 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 11622 Exclude); 11623 } else { 11624 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 11625 /*Last=*/OMPC_SCHEDULE_unknown); 11626 } 11627 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11628 << Values << getOpenMPClauseName(OMPC_schedule); 11629 return nullptr; 11630 } 11631 // OpenMP, 2.7.1, Loop Construct, Restrictions 11632 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 11633 // schedule(guided). 11634 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 11635 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 11636 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 11637 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 11638 diag::err_omp_schedule_nonmonotonic_static); 11639 return nullptr; 11640 } 11641 Expr *ValExpr = ChunkSize; 11642 Stmt *HelperValStmt = nullptr; 11643 if (ChunkSize) { 11644 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11645 !ChunkSize->isInstantiationDependent() && 11646 !ChunkSize->containsUnexpandedParameterPack()) { 11647 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 11648 ExprResult Val = 11649 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11650 if (Val.isInvalid()) 11651 return nullptr; 11652 11653 ValExpr = Val.get(); 11654 11655 // OpenMP [2.7.1, Restrictions] 11656 // chunk_size must be a loop invariant integer expression with a positive 11657 // value. 11658 llvm::APSInt Result; 11659 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11660 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11661 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11662 << "schedule" << 1 << ChunkSize->getSourceRange(); 11663 return nullptr; 11664 } 11665 } else if (getOpenMPCaptureRegionForClause( 11666 DSAStack->getCurrentDirective(), OMPC_schedule) != 11667 OMPD_unknown && 11668 !CurContext->isDependentContext()) { 11669 ValExpr = MakeFullExpr(ValExpr).get(); 11670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 11671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11672 HelperValStmt = buildPreInits(Context, Captures); 11673 } 11674 } 11675 } 11676 11677 return new (Context) 11678 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 11679 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 11680} 11681 11682OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 11683 SourceLocation StartLoc, 11684 SourceLocation EndLoc) { 11685 OMPClause *Res = nullptr; 11686 switch (Kind) { 11687 case OMPC_ordered: 11688 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 11689 break; 11690 case OMPC_nowait: 11691 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 11692 break; 11693 case OMPC_untied: 11694 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 11695 break; 11696 case OMPC_mergeable: 11697 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 11698 break; 11699 case OMPC_read: 11700 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 11701 break; 11702 case OMPC_write: 11703 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 11704 break; 11705 case OMPC_update: 11706 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 11707 break; 11708 case OMPC_capture: 11709 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 11710 break; 11711 case OMPC_seq_cst: 11712 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 11713 break; 11714 case OMPC_threads: 11715 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 11716 break; 11717 case OMPC_simd: 11718 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 11719 break; 11720 case OMPC_nogroup: 11721 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 11722 break; 11723 case OMPC_unified_address: 11724 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 11725 break; 11726 case OMPC_unified_shared_memory: 11727 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11728 break; 11729 case OMPC_reverse_offload: 11730 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 11731 break; 11732 case OMPC_dynamic_allocators: 11733 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 11734 break; 11735 case OMPC_if: 11736 case OMPC_final: 11737 case OMPC_num_threads: 11738 case OMPC_safelen: 11739 case OMPC_simdlen: 11740 case OMPC_allocator: 11741 case OMPC_collapse: 11742 case OMPC_schedule: 11743 case OMPC_private: 11744 case OMPC_firstprivate: 11745 case OMPC_lastprivate: 11746 case OMPC_shared: 11747 case OMPC_reduction: 11748 case OMPC_task_reduction: 11749 case OMPC_in_reduction: 11750 case OMPC_linear: 11751 case OMPC_aligned: 11752 case OMPC_copyin: 11753 case OMPC_copyprivate: 11754 case OMPC_default: 11755 case OMPC_proc_bind: 11756 case OMPC_threadprivate: 11757 case OMPC_allocate: 11758 case OMPC_flush: 11759 case OMPC_depend: 11760 case OMPC_device: 11761 case OMPC_map: 11762 case OMPC_num_teams: 11763 case OMPC_thread_limit: 11764 case OMPC_priority: 11765 case OMPC_grainsize: 11766 case OMPC_num_tasks: 11767 case OMPC_hint: 11768 case OMPC_dist_schedule: 11769 case OMPC_defaultmap: 11770 case OMPC_unknown: 11771 case OMPC_uniform: 11772 case OMPC_to: 11773 case OMPC_from: 11774 case OMPC_use_device_ptr: 11775 case OMPC_is_device_ptr: 11776 case OMPC_atomic_default_mem_order: 11777 case OMPC_device_type: 11778 case OMPC_match: 11779 llvm_unreachable("Clause is not allowed."); 11780 } 11781 return Res; 11782} 11783 11784OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 11785 SourceLocation EndLoc) { 11786 DSAStack->setNowaitRegion(); 11787 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 11788} 11789 11790OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 11791 SourceLocation EndLoc) { 11792 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 11793} 11794 11795OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 11796 SourceLocation EndLoc) { 11797 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 11798} 11799 11800OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 11801 SourceLocation EndLoc) { 11802 return new (Context) OMPReadClause(StartLoc, EndLoc); 11803} 11804 11805OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 11806 SourceLocation EndLoc) { 11807 return new (Context) OMPWriteClause(StartLoc, EndLoc); 11808} 11809 11810OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 11811 SourceLocation EndLoc) { 11812 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 11813} 11814 11815OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 11816 SourceLocation EndLoc) { 11817 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 11818} 11819 11820OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 11821 SourceLocation EndLoc) { 11822 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 11823} 11824 11825OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 11826 SourceLocation EndLoc) { 11827 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 11828} 11829 11830OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 11831 SourceLocation EndLoc) { 11832 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 11833} 11834 11835OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 11836 SourceLocation EndLoc) { 11837 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 11838} 11839 11840OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 11841 SourceLocation EndLoc) { 11842 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 11843} 11844 11845OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 11846 SourceLocation EndLoc) { 11847 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 11848} 11849 11850OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 11851 SourceLocation EndLoc) { 11852 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 11853} 11854 11855OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 11856 SourceLocation EndLoc) { 11857 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 11858} 11859 11860OMPClause *Sema::ActOnOpenMPVarListClause( 11861 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 11862 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 11863 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 11864 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 11865 OpenMPLinearClauseKind LinKind, 11866 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 11867 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 11868 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 11869 SourceLocation StartLoc = Locs.StartLoc; 11870 SourceLocation LParenLoc = Locs.LParenLoc; 11871 SourceLocation EndLoc = Locs.EndLoc; 11872 OMPClause *Res = nullptr; 11873 switch (Kind) { 11874 case OMPC_private: 11875 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11876 break; 11877 case OMPC_firstprivate: 11878 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11879 break; 11880 case OMPC_lastprivate: 11881 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11882 break; 11883 case OMPC_shared: 11884 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 11885 break; 11886 case OMPC_reduction: 11887 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11888 EndLoc, ReductionOrMapperIdScopeSpec, 11889 ReductionOrMapperId); 11890 break; 11891 case OMPC_task_reduction: 11892 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11893 EndLoc, ReductionOrMapperIdScopeSpec, 11894 ReductionOrMapperId); 11895 break; 11896 case OMPC_in_reduction: 11897 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 11898 EndLoc, ReductionOrMapperIdScopeSpec, 11899 ReductionOrMapperId); 11900 break; 11901 case OMPC_linear: 11902 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 11903 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 11904 break; 11905 case OMPC_aligned: 11906 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 11907 ColonLoc, EndLoc); 11908 break; 11909 case OMPC_copyin: 11910 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 11911 break; 11912 case OMPC_copyprivate: 11913 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 11914 break; 11915 case OMPC_flush: 11916 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 11917 break; 11918 case OMPC_depend: 11919 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 11920 StartLoc, LParenLoc, EndLoc); 11921 break; 11922 case OMPC_map: 11923 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 11924 ReductionOrMapperIdScopeSpec, 11925 ReductionOrMapperId, MapType, IsMapTypeImplicit, 11926 DepLinMapLoc, ColonLoc, VarList, Locs); 11927 break; 11928 case OMPC_to: 11929 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 11930 ReductionOrMapperId, Locs); 11931 break; 11932 case OMPC_from: 11933 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 11934 ReductionOrMapperId, Locs); 11935 break; 11936 case OMPC_use_device_ptr: 11937 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 11938 break; 11939 case OMPC_is_device_ptr: 11940 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 11941 break; 11942 case OMPC_allocate: 11943 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc, 11944 ColonLoc, EndLoc); 11945 break; 11946 case OMPC_if: 11947 case OMPC_final: 11948 case OMPC_num_threads: 11949 case OMPC_safelen: 11950 case OMPC_simdlen: 11951 case OMPC_allocator: 11952 case OMPC_collapse: 11953 case OMPC_default: 11954 case OMPC_proc_bind: 11955 case OMPC_schedule: 11956 case OMPC_ordered: 11957 case OMPC_nowait: 11958 case OMPC_untied: 11959 case OMPC_mergeable: 11960 case OMPC_threadprivate: 11961 case OMPC_read: 11962 case OMPC_write: 11963 case OMPC_update: 11964 case OMPC_capture: 11965 case OMPC_seq_cst: 11966 case OMPC_device: 11967 case OMPC_threads: 11968 case OMPC_simd: 11969 case OMPC_num_teams: 11970 case OMPC_thread_limit: 11971 case OMPC_priority: 11972 case OMPC_grainsize: 11973 case OMPC_nogroup: 11974 case OMPC_num_tasks: 11975 case OMPC_hint: 11976 case OMPC_dist_schedule: 11977 case OMPC_defaultmap: 11978 case OMPC_unknown: 11979 case OMPC_uniform: 11980 case OMPC_unified_address: 11981 case OMPC_unified_shared_memory: 11982 case OMPC_reverse_offload: 11983 case OMPC_dynamic_allocators: 11984 case OMPC_atomic_default_mem_order: 11985 case OMPC_device_type: 11986 case OMPC_match: 11987 llvm_unreachable("Clause is not allowed."); 11988 } 11989 return Res; 11990} 11991 11992ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 11993 ExprObjectKind OK, SourceLocation Loc) { 11994 ExprResult Res = BuildDeclRefExpr( 11995 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 11996 if (!Res.isUsable()) 11997 return ExprError(); 11998 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 11999 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 12000 if (!Res.isUsable()) 12001 return ExprError(); 12002 } 12003 if (VK != VK_LValue && Res.get()->isGLValue()) { 12004 Res = DefaultLvalueConversion(Res.get()); 12005 if (!Res.isUsable()) 12006 return ExprError(); 12007 } 12008 return Res; 12009} 12010 12011OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 12012 SourceLocation StartLoc, 12013 SourceLocation LParenLoc, 12014 SourceLocation EndLoc) { 12015 SmallVector<Expr *, 8> Vars; 12016 SmallVector<Expr *, 8> PrivateCopies; 12017 for (Expr *RefExpr : VarList) { 12018 assert(RefExpr && "NULL expr in OpenMP private clause."); 12019 SourceLocation ELoc; 12020 SourceRange ERange; 12021 Expr *SimpleRefExpr = RefExpr; 12022 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12023 if (Res.second) { 12024 // It will be analyzed later. 12025 Vars.push_back(RefExpr); 12026 PrivateCopies.push_back(nullptr); 12027 } 12028 ValueDecl *D = Res.first; 12029 if (!D) 12030 continue; 12031 12032 QualType Type = D->getType(); 12033 auto *VD = dyn_cast<VarDecl>(D); 12034 12035 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12036 // A variable that appears in a private clause must not have an incomplete 12037 // type or a reference type. 12038 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 12039 continue; 12040 Type = Type.getNonReferenceType(); 12041 12042 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12043 // A variable that is privatized must not have a const-qualified type 12044 // unless it is of class type with a mutable member. This restriction does 12045 // not apply to the firstprivate clause. 12046 // 12047 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 12048 // A variable that appears in a private clause must not have a 12049 // const-qualified type unless it is of class type with a mutable member. 12050 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 12051 continue; 12052 12053 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12054 // in a Construct] 12055 // Variables with the predetermined data-sharing attributes may not be 12056 // listed in data-sharing attributes clauses, except for the cases 12057 // listed below. For these exceptions only, listing a predetermined 12058 // variable in a data-sharing attribute clause is allowed and overrides 12059 // the variable's predetermined data-sharing attributes. 12060 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12061 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 12062 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12063 << getOpenMPClauseName(OMPC_private); 12064 reportOriginalDsa(*this, DSAStack, D, DVar); 12065 continue; 12066 } 12067 12068 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12069 // Variably modified types are not supported for tasks. 12070 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12071 isOpenMPTaskingDirective(CurrDir)) { 12072 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12073 << getOpenMPClauseName(OMPC_private) << Type 12074 << getOpenMPDirectiveName(CurrDir); 12075 bool IsDecl = 12076 !VD || 12077 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12078 Diag(D->getLocation(), 12079 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12080 << D; 12081 continue; 12082 } 12083 12084 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12085 // A list item cannot appear in both a map clause and a data-sharing 12086 // attribute clause on the same construct 12087 // 12088 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12089 // A list item cannot appear in both a map clause and a data-sharing 12090 // attribute clause on the same construct unless the construct is a 12091 // combined construct. 12092 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 12093 CurrDir == OMPD_target) { 12094 OpenMPClauseKind ConflictKind; 12095 if (DSAStack->checkMappableExprComponentListsForDecl( 12096 VD, /*CurrentRegionOnly=*/true, 12097 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 12098 OpenMPClauseKind WhereFoundClauseKind) -> bool { 12099 ConflictKind = WhereFoundClauseKind; 12100 return true; 12101 })) { 12102 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12103 << getOpenMPClauseName(OMPC_private) 12104 << getOpenMPClauseName(ConflictKind) 12105 << getOpenMPDirectiveName(CurrDir); 12106 reportOriginalDsa(*this, DSAStack, D, DVar); 12107 continue; 12108 } 12109 } 12110 12111 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 12112 // A variable of class type (or array thereof) that appears in a private 12113 // clause requires an accessible, unambiguous default constructor for the 12114 // class type. 12115 // Generate helper private variable and initialize it with the default 12116 // value. The address of the original variable is replaced by the address of 12117 // the new private variable in CodeGen. This new variable is not added to 12118 // IdResolver, so the code in the OpenMP region uses original variable for 12119 // proper diagnostics. 12120 Type = Type.getUnqualifiedType(); 12121 VarDecl *VDPrivate = 12122 buildVarDecl(*this, ELoc, Type, D->getName(), 12123 D->hasAttrs() ? &D->getAttrs() : nullptr, 12124 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12125 ActOnUninitializedDecl(VDPrivate); 12126 if (VDPrivate->isInvalidDecl()) 12127 continue; 12128 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12129 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12130 12131 DeclRefExpr *Ref = nullptr; 12132 if (!VD && !CurContext->isDependentContext()) 12133 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12134 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 12135 Vars.push_back((VD || CurContext->isDependentContext()) 12136 ? RefExpr->IgnoreParens() 12137 : Ref); 12138 PrivateCopies.push_back(VDPrivateRefExpr); 12139 } 12140 12141 if (Vars.empty()) 12142 return nullptr; 12143 12144 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12145 PrivateCopies); 12146} 12147 12148namespace { 12149class DiagsUninitializedSeveretyRAII { 12150private: 12151 DiagnosticsEngine &Diags; 12152 SourceLocation SavedLoc; 12153 bool IsIgnored = false; 12154 12155public: 12156 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 12157 bool IsIgnored) 12158 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 12159 if (!IsIgnored) { 12160 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 12161 /*Map*/ diag::Severity::Ignored, Loc); 12162 } 12163 } 12164 ~DiagsUninitializedSeveretyRAII() { 12165 if (!IsIgnored) 12166 Diags.popMappings(SavedLoc); 12167 } 12168}; 12169} 12170 12171OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 12172 SourceLocation StartLoc, 12173 SourceLocation LParenLoc, 12174 SourceLocation EndLoc) { 12175 SmallVector<Expr *, 8> Vars; 12176 SmallVector<Expr *, 8> PrivateCopies; 12177 SmallVector<Expr *, 8> Inits; 12178 SmallVector<Decl *, 4> ExprCaptures; 12179 bool IsImplicitClause = 12180 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 12181 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 12182 12183 for (Expr *RefExpr : VarList) { 12184 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 12185 SourceLocation ELoc; 12186 SourceRange ERange; 12187 Expr *SimpleRefExpr = RefExpr; 12188 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12189 if (Res.second) { 12190 // It will be analyzed later. 12191 Vars.push_back(RefExpr); 12192 PrivateCopies.push_back(nullptr); 12193 Inits.push_back(nullptr); 12194 } 12195 ValueDecl *D = Res.first; 12196 if (!D) 12197 continue; 12198 12199 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 12200 QualType Type = D->getType(); 12201 auto *VD = dyn_cast<VarDecl>(D); 12202 12203 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 12204 // A variable that appears in a private clause must not have an incomplete 12205 // type or a reference type. 12206 if (RequireCompleteType(ELoc, Type, 12207 diag::err_omp_firstprivate_incomplete_type)) 12208 continue; 12209 Type = Type.getNonReferenceType(); 12210 12211 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 12212 // A variable of class type (or array thereof) that appears in a private 12213 // clause requires an accessible, unambiguous copy constructor for the 12214 // class type. 12215 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12216 12217 // If an implicit firstprivate variable found it was checked already. 12218 DSAStackTy::DSAVarData TopDVar; 12219 if (!IsImplicitClause) { 12220 DSAStackTy::DSAVarData DVar = 12221 DSAStack->getTopDSA(D, /*FromParent=*/false); 12222 TopDVar = DVar; 12223 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12224 bool IsConstant = ElemType.isConstant(Context); 12225 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 12226 // A list item that specifies a given variable may not appear in more 12227 // than one clause on the same directive, except that a variable may be 12228 // specified in both firstprivate and lastprivate clauses. 12229 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12230 // A list item may appear in a firstprivate or lastprivate clause but not 12231 // both. 12232 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 12233 (isOpenMPDistributeDirective(CurrDir) || 12234 DVar.CKind != OMPC_lastprivate) && 12235 DVar.RefExpr) { 12236 Diag(ELoc, diag::err_omp_wrong_dsa) 12237 << getOpenMPClauseName(DVar.CKind) 12238 << getOpenMPClauseName(OMPC_firstprivate); 12239 reportOriginalDsa(*this, DSAStack, D, DVar); 12240 continue; 12241 } 12242 12243 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12244 // in a Construct] 12245 // Variables with the predetermined data-sharing attributes may not be 12246 // listed in data-sharing attributes clauses, except for the cases 12247 // listed below. For these exceptions only, listing a predetermined 12248 // variable in a data-sharing attribute clause is allowed and overrides 12249 // the variable's predetermined data-sharing attributes. 12250 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12251 // in a Construct, C/C++, p.2] 12252 // Variables with const-qualified type having no mutable member may be 12253 // listed in a firstprivate clause, even if they are static data members. 12254 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 12255 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 12256 Diag(ELoc, diag::err_omp_wrong_dsa) 12257 << getOpenMPClauseName(DVar.CKind) 12258 << getOpenMPClauseName(OMPC_firstprivate); 12259 reportOriginalDsa(*this, DSAStack, D, DVar); 12260 continue; 12261 } 12262 12263 // OpenMP [2.9.3.4, Restrictions, p.2] 12264 // A list item that is private within a parallel region must not appear 12265 // in a firstprivate clause on a worksharing construct if any of the 12266 // worksharing regions arising from the worksharing construct ever bind 12267 // to any of the parallel regions arising from the parallel construct. 12268 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12269 // A list item that is private within a teams region must not appear in a 12270 // firstprivate clause on a distribute construct if any of the distribute 12271 // regions arising from the distribute construct ever bind to any of the 12272 // teams regions arising from the teams construct. 12273 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 12274 // A list item that appears in a reduction clause of a teams construct 12275 // must not appear in a firstprivate clause on a distribute construct if 12276 // any of the distribute regions arising from the distribute construct 12277 // ever bind to any of the teams regions arising from the teams construct. 12278 if ((isOpenMPWorksharingDirective(CurrDir) || 12279 isOpenMPDistributeDirective(CurrDir)) && 12280 !isOpenMPParallelDirective(CurrDir) && 12281 !isOpenMPTeamsDirective(CurrDir)) { 12282 DVar = DSAStack->getImplicitDSA(D, true); 12283 if (DVar.CKind != OMPC_shared && 12284 (isOpenMPParallelDirective(DVar.DKind) || 12285 isOpenMPTeamsDirective(DVar.DKind) || 12286 DVar.DKind == OMPD_unknown)) { 12287 Diag(ELoc, diag::err_omp_required_access) 12288 << getOpenMPClauseName(OMPC_firstprivate) 12289 << getOpenMPClauseName(OMPC_shared); 12290 reportOriginalDsa(*this, DSAStack, D, DVar); 12291 continue; 12292 } 12293 } 12294 // OpenMP [2.9.3.4, Restrictions, p.3] 12295 // A list item that appears in a reduction clause of a parallel construct 12296 // must not appear in a firstprivate clause on a worksharing or task 12297 // construct if any of the worksharing or task regions arising from the 12298 // worksharing or task construct ever bind to any of the parallel regions 12299 // arising from the parallel construct. 12300 // OpenMP [2.9.3.4, Restrictions, p.4] 12301 // A list item that appears in a reduction clause in worksharing 12302 // construct must not appear in a firstprivate clause in a task construct 12303 // encountered during execution of any of the worksharing regions arising 12304 // from the worksharing construct. 12305 if (isOpenMPTaskingDirective(CurrDir)) { 12306 DVar = DSAStack->hasInnermostDSA( 12307 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 12308 [](OpenMPDirectiveKind K) { 12309 return isOpenMPParallelDirective(K) || 12310 isOpenMPWorksharingDirective(K) || 12311 isOpenMPTeamsDirective(K); 12312 }, 12313 /*FromParent=*/true); 12314 if (DVar.CKind == OMPC_reduction && 12315 (isOpenMPParallelDirective(DVar.DKind) || 12316 isOpenMPWorksharingDirective(DVar.DKind) || 12317 isOpenMPTeamsDirective(DVar.DKind))) { 12318 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 12319 << getOpenMPDirectiveName(DVar.DKind); 12320 reportOriginalDsa(*this, DSAStack, D, DVar); 12321 continue; 12322 } 12323 } 12324 12325 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12326 // A list item cannot appear in both a map clause and a data-sharing 12327 // attribute clause on the same construct 12328 // 12329 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 12330 // A list item cannot appear in both a map clause and a data-sharing 12331 // attribute clause on the same construct unless the construct is a 12332 // combined construct. 12333 if ((LangOpts.OpenMP <= 45 && 12334 isOpenMPTargetExecutionDirective(CurrDir)) || 12335 CurrDir == OMPD_target) { 12336 OpenMPClauseKind ConflictKind; 12337 if (DSAStack->checkMappableExprComponentListsForDecl( 12338 VD, /*CurrentRegionOnly=*/true, 12339 [&ConflictKind]( 12340 OMPClauseMappableExprCommon::MappableExprComponentListRef, 12341 OpenMPClauseKind WhereFoundClauseKind) { 12342 ConflictKind = WhereFoundClauseKind; 12343 return true; 12344 })) { 12345 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12346 << getOpenMPClauseName(OMPC_firstprivate) 12347 << getOpenMPClauseName(ConflictKind) 12348 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12349 reportOriginalDsa(*this, DSAStack, D, DVar); 12350 continue; 12351 } 12352 } 12353 } 12354 12355 // Variably modified types are not supported for tasks. 12356 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 12357 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 12358 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12359 << getOpenMPClauseName(OMPC_firstprivate) << Type 12360 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12361 bool IsDecl = 12362 !VD || 12363 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12364 Diag(D->getLocation(), 12365 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12366 << D; 12367 continue; 12368 } 12369 12370 Type = Type.getUnqualifiedType(); 12371 VarDecl *VDPrivate = 12372 buildVarDecl(*this, ELoc, Type, D->getName(), 12373 D->hasAttrs() ? &D->getAttrs() : nullptr, 12374 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12375 // Generate helper private variable and initialize it with the value of the 12376 // original variable. The address of the original variable is replaced by 12377 // the address of the new private variable in the CodeGen. This new variable 12378 // is not added to IdResolver, so the code in the OpenMP region uses 12379 // original variable for proper diagnostics and variable capturing. 12380 Expr *VDInitRefExpr = nullptr; 12381 // For arrays generate initializer for single element and replace it by the 12382 // original array element in CodeGen. 12383 if (Type->isArrayType()) { 12384 VarDecl *VDInit = 12385 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 12386 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 12387 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 12388 ElemType = ElemType.getUnqualifiedType(); 12389 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 12390 ".firstprivate.temp"); 12391 InitializedEntity Entity = 12392 InitializedEntity::InitializeVariable(VDInitTemp); 12393 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 12394 12395 InitializationSequence InitSeq(*this, Entity, Kind, Init); 12396 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 12397 if (Result.isInvalid()) 12398 VDPrivate->setInvalidDecl(); 12399 else 12400 VDPrivate->setInit(Result.getAs<Expr>()); 12401 // Remove temp variable declaration. 12402 Context.Deallocate(VDInitTemp); 12403 } else { 12404 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 12405 ".firstprivate.temp"); 12406 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12407 RefExpr->getExprLoc()); 12408 AddInitializerToDecl(VDPrivate, 12409 DefaultLvalueConversion(VDInitRefExpr).get(), 12410 /*DirectInit=*/false); 12411 } 12412 if (VDPrivate->isInvalidDecl()) { 12413 if (IsImplicitClause) { 12414 Diag(RefExpr->getExprLoc(), 12415 diag::note_omp_task_predetermined_firstprivate_here); 12416 } 12417 continue; 12418 } 12419 CurContext->addDecl(VDPrivate); 12420 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 12421 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 12422 RefExpr->getExprLoc()); 12423 DeclRefExpr *Ref = nullptr; 12424 if (!VD && !CurContext->isDependentContext()) { 12425 if (TopDVar.CKind == OMPC_lastprivate) { 12426 Ref = TopDVar.PrivateCopy; 12427 } else { 12428 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12429 if (!isOpenMPCapturedDecl(D)) 12430 ExprCaptures.push_back(Ref->getDecl()); 12431 } 12432 } 12433 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12434 Vars.push_back((VD || CurContext->isDependentContext()) 12435 ? RefExpr->IgnoreParens() 12436 : Ref); 12437 PrivateCopies.push_back(VDPrivateRefExpr); 12438 Inits.push_back(VDInitRefExpr); 12439 } 12440 12441 if (Vars.empty()) 12442 return nullptr; 12443 12444 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12445 Vars, PrivateCopies, Inits, 12446 buildPreInits(Context, ExprCaptures)); 12447} 12448 12449OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 12450 SourceLocation StartLoc, 12451 SourceLocation LParenLoc, 12452 SourceLocation EndLoc) { 12453 SmallVector<Expr *, 8> Vars; 12454 SmallVector<Expr *, 8> SrcExprs; 12455 SmallVector<Expr *, 8> DstExprs; 12456 SmallVector<Expr *, 8> AssignmentOps; 12457 SmallVector<Decl *, 4> ExprCaptures; 12458 SmallVector<Expr *, 4> ExprPostUpdates; 12459 for (Expr *RefExpr : VarList) { 12460 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12461 SourceLocation ELoc; 12462 SourceRange ERange; 12463 Expr *SimpleRefExpr = RefExpr; 12464 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12465 if (Res.second) { 12466 // It will be analyzed later. 12467 Vars.push_back(RefExpr); 12468 SrcExprs.push_back(nullptr); 12469 DstExprs.push_back(nullptr); 12470 AssignmentOps.push_back(nullptr); 12471 } 12472 ValueDecl *D = Res.first; 12473 if (!D) 12474 continue; 12475 12476 QualType Type = D->getType(); 12477 auto *VD = dyn_cast<VarDecl>(D); 12478 12479 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 12480 // A variable that appears in a lastprivate clause must not have an 12481 // incomplete type or a reference type. 12482 if (RequireCompleteType(ELoc, Type, 12483 diag::err_omp_lastprivate_incomplete_type)) 12484 continue; 12485 Type = Type.getNonReferenceType(); 12486 12487 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12488 // A variable that is privatized must not have a const-qualified type 12489 // unless it is of class type with a mutable member. This restriction does 12490 // not apply to the firstprivate clause. 12491 // 12492 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 12493 // A variable that appears in a lastprivate clause must not have a 12494 // const-qualified type unless it is of class type with a mutable member. 12495 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 12496 continue; 12497 12498 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 12499 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 12500 // in a Construct] 12501 // Variables with the predetermined data-sharing attributes may not be 12502 // listed in data-sharing attributes clauses, except for the cases 12503 // listed below. 12504 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 12505 // A list item may appear in a firstprivate or lastprivate clause but not 12506 // both. 12507 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12508 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 12509 (isOpenMPDistributeDirective(CurrDir) || 12510 DVar.CKind != OMPC_firstprivate) && 12511 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 12512 Diag(ELoc, diag::err_omp_wrong_dsa) 12513 << getOpenMPClauseName(DVar.CKind) 12514 << getOpenMPClauseName(OMPC_lastprivate); 12515 reportOriginalDsa(*this, DSAStack, D, DVar); 12516 continue; 12517 } 12518 12519 // OpenMP [2.14.3.5, Restrictions, p.2] 12520 // A list item that is private within a parallel region, or that appears in 12521 // the reduction clause of a parallel construct, must not appear in a 12522 // lastprivate clause on a worksharing construct if any of the corresponding 12523 // worksharing regions ever binds to any of the corresponding parallel 12524 // regions. 12525 DSAStackTy::DSAVarData TopDVar = DVar; 12526 if (isOpenMPWorksharingDirective(CurrDir) && 12527 !isOpenMPParallelDirective(CurrDir) && 12528 !isOpenMPTeamsDirective(CurrDir)) { 12529 DVar = DSAStack->getImplicitDSA(D, true); 12530 if (DVar.CKind != OMPC_shared) { 12531 Diag(ELoc, diag::err_omp_required_access) 12532 << getOpenMPClauseName(OMPC_lastprivate) 12533 << getOpenMPClauseName(OMPC_shared); 12534 reportOriginalDsa(*this, DSAStack, D, DVar); 12535 continue; 12536 } 12537 } 12538 12539 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 12540 // A variable of class type (or array thereof) that appears in a 12541 // lastprivate clause requires an accessible, unambiguous default 12542 // constructor for the class type, unless the list item is also specified 12543 // in a firstprivate clause. 12544 // A variable of class type (or array thereof) that appears in a 12545 // lastprivate clause requires an accessible, unambiguous copy assignment 12546 // operator for the class type. 12547 Type = Context.getBaseElementType(Type).getNonReferenceType(); 12548 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 12549 Type.getUnqualifiedType(), ".lastprivate.src", 12550 D->hasAttrs() ? &D->getAttrs() : nullptr); 12551 DeclRefExpr *PseudoSrcExpr = 12552 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 12553 VarDecl *DstVD = 12554 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 12555 D->hasAttrs() ? &D->getAttrs() : nullptr); 12556 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12557 // For arrays generate assignment operation for single element and replace 12558 // it by the original array element in CodeGen. 12559 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 12560 PseudoDstExpr, PseudoSrcExpr); 12561 if (AssignmentOp.isInvalid()) 12562 continue; 12563 AssignmentOp = 12564 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12565 if (AssignmentOp.isInvalid()) 12566 continue; 12567 12568 DeclRefExpr *Ref = nullptr; 12569 if (!VD && !CurContext->isDependentContext()) { 12570 if (TopDVar.CKind == OMPC_firstprivate) { 12571 Ref = TopDVar.PrivateCopy; 12572 } else { 12573 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12574 if (!isOpenMPCapturedDecl(D)) 12575 ExprCaptures.push_back(Ref->getDecl()); 12576 } 12577 if (TopDVar.CKind == OMPC_firstprivate || 12578 (!isOpenMPCapturedDecl(D) && 12579 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 12580 ExprResult RefRes = DefaultLvalueConversion(Ref); 12581 if (!RefRes.isUsable()) 12582 continue; 12583 ExprResult PostUpdateRes = 12584 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 12585 RefRes.get()); 12586 if (!PostUpdateRes.isUsable()) 12587 continue; 12588 ExprPostUpdates.push_back( 12589 IgnoredValueConversions(PostUpdateRes.get()).get()); 12590 } 12591 } 12592 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 12593 Vars.push_back((VD || CurContext->isDependentContext()) 12594 ? RefExpr->IgnoreParens() 12595 : Ref); 12596 SrcExprs.push_back(PseudoSrcExpr); 12597 DstExprs.push_back(PseudoDstExpr); 12598 AssignmentOps.push_back(AssignmentOp.get()); 12599 } 12600 12601 if (Vars.empty()) 12602 return nullptr; 12603 12604 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12605 Vars, SrcExprs, DstExprs, AssignmentOps, 12606 buildPreInits(Context, ExprCaptures), 12607 buildPostUpdate(*this, ExprPostUpdates)); 12608} 12609 12610OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 12611 SourceLocation StartLoc, 12612 SourceLocation LParenLoc, 12613 SourceLocation EndLoc) { 12614 SmallVector<Expr *, 8> Vars; 12615 for (Expr *RefExpr : VarList) { 12616 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 12617 SourceLocation ELoc; 12618 SourceRange ERange; 12619 Expr *SimpleRefExpr = RefExpr; 12620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12621 if (Res.second) { 12622 // It will be analyzed later. 12623 Vars.push_back(RefExpr); 12624 } 12625 ValueDecl *D = Res.first; 12626 if (!D) 12627 continue; 12628 12629 auto *VD = dyn_cast<VarDecl>(D); 12630 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 12631 // in a Construct] 12632 // Variables with the predetermined data-sharing attributes may not be 12633 // listed in data-sharing attributes clauses, except for the cases 12634 // listed below. For these exceptions only, listing a predetermined 12635 // variable in a data-sharing attribute clause is allowed and overrides 12636 // the variable's predetermined data-sharing attributes. 12637 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12638 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 12639 DVar.RefExpr) { 12640 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12641 << getOpenMPClauseName(OMPC_shared); 12642 reportOriginalDsa(*this, DSAStack, D, DVar); 12643 continue; 12644 } 12645 12646 DeclRefExpr *Ref = nullptr; 12647 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 12648 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12649 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 12650 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 12651 ? RefExpr->IgnoreParens() 12652 : Ref); 12653 } 12654 12655 if (Vars.empty()) 12656 return nullptr; 12657 12658 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 12659} 12660 12661namespace { 12662class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 12663 DSAStackTy *Stack; 12664 12665public: 12666 bool VisitDeclRefExpr(DeclRefExpr *E) { 12667 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 12668 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 12669 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 12670 return false; 12671 if (DVar.CKind != OMPC_unknown) 12672 return true; 12673 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 12674 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 12675 /*FromParent=*/true); 12676 return DVarPrivate.CKind != OMPC_unknown; 12677 } 12678 return false; 12679 } 12680 bool VisitStmt(Stmt *S) { 12681 for (Stmt *Child : S->children()) { 12682 if (Child && Visit(Child)) 12683 return true; 12684 } 12685 return false; 12686 } 12687 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 12688}; 12689} // namespace 12690 12691namespace { 12692// Transform MemberExpression for specified FieldDecl of current class to 12693// DeclRefExpr to specified OMPCapturedExprDecl. 12694class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 12695 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 12696 ValueDecl *Field = nullptr; 12697 DeclRefExpr *CapturedExpr = nullptr; 12698 12699public: 12700 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 12701 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 12702 12703 ExprResult TransformMemberExpr(MemberExpr *E) { 12704 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 12705 E->getMemberDecl() == Field) { 12706 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 12707 return CapturedExpr; 12708 } 12709 return BaseTransform::TransformMemberExpr(E); 12710 } 12711 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 12712}; 12713} // namespace 12714 12715template <typename T, typename U> 12716static T filterLookupForUDReductionAndMapper( 12717 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 12718 for (U &Set : Lookups) { 12719 for (auto *D : Set) { 12720 if (T Res = Gen(cast<ValueDecl>(D))) 12721 return Res; 12722 } 12723 } 12724 return T(); 12725} 12726 12727static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 12728 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 12729 12730 for (auto RD : D->redecls()) { 12731 // Don't bother with extra checks if we already know this one isn't visible. 12732 if (RD == D) 12733 continue; 12734 12735 auto ND = cast<NamedDecl>(RD); 12736 if (LookupResult::isVisible(SemaRef, ND)) 12737 return ND; 12738 } 12739 12740 return nullptr; 12741} 12742 12743static void 12744argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 12745 SourceLocation Loc, QualType Ty, 12746 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 12747 // Find all of the associated namespaces and classes based on the 12748 // arguments we have. 12749 Sema::AssociatedNamespaceSet AssociatedNamespaces; 12750 Sema::AssociatedClassSet AssociatedClasses; 12751 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 12752 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 12753 AssociatedClasses); 12754 12755 // C++ [basic.lookup.argdep]p3: 12756 // Let X be the lookup set produced by unqualified lookup (3.4.1) 12757 // and let Y be the lookup set produced by argument dependent 12758 // lookup (defined as follows). If X contains [...] then Y is 12759 // empty. Otherwise Y is the set of declarations found in the 12760 // namespaces associated with the argument types as described 12761 // below. The set of declarations found by the lookup of the name 12762 // is the union of X and Y. 12763 // 12764 // Here, we compute Y and add its members to the overloaded 12765 // candidate set. 12766 for (auto *NS : AssociatedNamespaces) { 12767 // When considering an associated namespace, the lookup is the 12768 // same as the lookup performed when the associated namespace is 12769 // used as a qualifier (3.4.3.2) except that: 12770 // 12771 // -- Any using-directives in the associated namespace are 12772 // ignored. 12773 // 12774 // -- Any namespace-scope friend functions declared in 12775 // associated classes are visible within their respective 12776 // namespaces even if they are not visible during an ordinary 12777 // lookup (11.4). 12778 DeclContext::lookup_result R = NS->lookup(Id.getName()); 12779 for (auto *D : R) { 12780 auto *Underlying = D; 12781 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12782 Underlying = USD->getTargetDecl(); 12783 12784 if (!isa<OMPDeclareReductionDecl>(Underlying) && 12785 !isa<OMPDeclareMapperDecl>(Underlying)) 12786 continue; 12787 12788 if (!SemaRef.isVisible(D)) { 12789 D = findAcceptableDecl(SemaRef, D); 12790 if (!D) 12791 continue; 12792 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 12793 Underlying = USD->getTargetDecl(); 12794 } 12795 Lookups.emplace_back(); 12796 Lookups.back().addDecl(Underlying); 12797 } 12798 } 12799} 12800 12801static ExprResult 12802buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 12803 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 12804 const DeclarationNameInfo &ReductionId, QualType Ty, 12805 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 12806 if (ReductionIdScopeSpec.isInvalid()) 12807 return ExprError(); 12808 SmallVector<UnresolvedSet<8>, 4> Lookups; 12809 if (S) { 12810 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12811 Lookup.suppressDiagnostics(); 12812 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 12813 NamedDecl *D = Lookup.getRepresentativeDecl(); 12814 do { 12815 S = S->getParent(); 12816 } while (S && !S->isDeclScope(D)); 12817 if (S) 12818 S = S->getParent(); 12819 Lookups.emplace_back(); 12820 Lookups.back().append(Lookup.begin(), Lookup.end()); 12821 Lookup.clear(); 12822 } 12823 } else if (auto *ULE = 12824 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 12825 Lookups.push_back(UnresolvedSet<8>()); 12826 Decl *PrevD = nullptr; 12827 for (NamedDecl *D : ULE->decls()) { 12828 if (D == PrevD) 12829 Lookups.push_back(UnresolvedSet<8>()); 12830 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 12831 Lookups.back().addDecl(DRD); 12832 PrevD = D; 12833 } 12834 } 12835 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 12836 Ty->isInstantiationDependentType() || 12837 Ty->containsUnexpandedParameterPack() || 12838 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 12839 return !D->isInvalidDecl() && 12840 (D->getType()->isDependentType() || 12841 D->getType()->isInstantiationDependentType() || 12842 D->getType()->containsUnexpandedParameterPack()); 12843 })) { 12844 UnresolvedSet<8> ResSet; 12845 for (const UnresolvedSet<8> &Set : Lookups) { 12846 if (Set.empty()) 12847 continue; 12848 ResSet.append(Set.begin(), Set.end()); 12849 // The last item marks the end of all declarations at the specified scope. 12850 ResSet.addDecl(Set[Set.size() - 1]); 12851 } 12852 return UnresolvedLookupExpr::Create( 12853 SemaRef.Context, /*NamingClass=*/nullptr, 12854 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 12855 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 12856 } 12857 // Lookup inside the classes. 12858 // C++ [over.match.oper]p3: 12859 // For a unary operator @ with an operand of a type whose 12860 // cv-unqualified version is T1, and for a binary operator @ with 12861 // a left operand of a type whose cv-unqualified version is T1 and 12862 // a right operand of a type whose cv-unqualified version is T2, 12863 // three sets of candidate functions, designated member 12864 // candidates, non-member candidates and built-in candidates, are 12865 // constructed as follows: 12866 // -- If T1 is a complete class type or a class currently being 12867 // defined, the set of member candidates is the result of the 12868 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 12869 // the set of member candidates is empty. 12870 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 12871 Lookup.suppressDiagnostics(); 12872 if (const auto *TyRec = Ty->getAs<RecordType>()) { 12873 // Complete the type if it can be completed. 12874 // If the type is neither complete nor being defined, bail out now. 12875 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 12876 TyRec->getDecl()->getDefinition()) { 12877 Lookup.clear(); 12878 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 12879 if (Lookup.empty()) { 12880 Lookups.emplace_back(); 12881 Lookups.back().append(Lookup.begin(), Lookup.end()); 12882 } 12883 } 12884 } 12885 // Perform ADL. 12886 if (SemaRef.getLangOpts().CPlusPlus) 12887 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 12888 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12889 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 12890 if (!D->isInvalidDecl() && 12891 SemaRef.Context.hasSameType(D->getType(), Ty)) 12892 return D; 12893 return nullptr; 12894 })) 12895 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 12896 VK_LValue, Loc); 12897 if (SemaRef.getLangOpts().CPlusPlus) { 12898 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 12899 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 12900 if (!D->isInvalidDecl() && 12901 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 12902 !Ty.isMoreQualifiedThan(D->getType())) 12903 return D; 12904 return nullptr; 12905 })) { 12906 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 12907 /*DetectVirtual=*/false); 12908 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 12909 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 12910 VD->getType().getUnqualifiedType()))) { 12911 if (SemaRef.CheckBaseClassAccess( 12912 Loc, VD->getType(), Ty, Paths.front(), 12913 /*DiagID=*/0) != Sema::AR_inaccessible) { 12914 SemaRef.BuildBasePathArray(Paths, BasePath); 12915 return SemaRef.BuildDeclRefExpr( 12916 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 12917 } 12918 } 12919 } 12920 } 12921 } 12922 if (ReductionIdScopeSpec.isSet()) { 12923 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 12924 return ExprError(); 12925 } 12926 return ExprEmpty(); 12927} 12928 12929namespace { 12930/// Data for the reduction-based clauses. 12931struct ReductionData { 12932 /// List of original reduction items. 12933 SmallVector<Expr *, 8> Vars; 12934 /// List of private copies of the reduction items. 12935 SmallVector<Expr *, 8> Privates; 12936 /// LHS expressions for the reduction_op expressions. 12937 SmallVector<Expr *, 8> LHSs; 12938 /// RHS expressions for the reduction_op expressions. 12939 SmallVector<Expr *, 8> RHSs; 12940 /// Reduction operation expression. 12941 SmallVector<Expr *, 8> ReductionOps; 12942 /// Taskgroup descriptors for the corresponding reduction items in 12943 /// in_reduction clauses. 12944 SmallVector<Expr *, 8> TaskgroupDescriptors; 12945 /// List of captures for clause. 12946 SmallVector<Decl *, 4> ExprCaptures; 12947 /// List of postupdate expressions. 12948 SmallVector<Expr *, 4> ExprPostUpdates; 12949 ReductionData() = delete; 12950 /// Reserves required memory for the reduction data. 12951 ReductionData(unsigned Size) { 12952 Vars.reserve(Size); 12953 Privates.reserve(Size); 12954 LHSs.reserve(Size); 12955 RHSs.reserve(Size); 12956 ReductionOps.reserve(Size); 12957 TaskgroupDescriptors.reserve(Size); 12958 ExprCaptures.reserve(Size); 12959 ExprPostUpdates.reserve(Size); 12960 } 12961 /// Stores reduction item and reduction operation only (required for dependent 12962 /// reduction item). 12963 void push(Expr *Item, Expr *ReductionOp) { 12964 Vars.emplace_back(Item); 12965 Privates.emplace_back(nullptr); 12966 LHSs.emplace_back(nullptr); 12967 RHSs.emplace_back(nullptr); 12968 ReductionOps.emplace_back(ReductionOp); 12969 TaskgroupDescriptors.emplace_back(nullptr); 12970 } 12971 /// Stores reduction data. 12972 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 12973 Expr *TaskgroupDescriptor) { 12974 Vars.emplace_back(Item); 12975 Privates.emplace_back(Private); 12976 LHSs.emplace_back(LHS); 12977 RHSs.emplace_back(RHS); 12978 ReductionOps.emplace_back(ReductionOp); 12979 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 12980 } 12981}; 12982} // namespace 12983 12984static bool checkOMPArraySectionConstantForReduction( 12985 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 12986 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 12987 const Expr *Length = OASE->getLength(); 12988 if (Length == nullptr) { 12989 // For array sections of the form [1:] or [:], we would need to analyze 12990 // the lower bound... 12991 if (OASE->getColonLoc().isValid()) 12992 return false; 12993 12994 // This is an array subscript which has implicit length 1! 12995 SingleElement = true; 12996 ArraySizes.push_back(llvm::APSInt::get(1)); 12997 } else { 12998 Expr::EvalResult Result; 12999 if (!Length->EvaluateAsInt(Result, Context)) 13000 return false; 13001 13002 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13003 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 13004 ArraySizes.push_back(ConstantLengthValue); 13005 } 13006 13007 // Get the base of this array section and walk up from there. 13008 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 13009 13010 // We require length = 1 for all array sections except the right-most to 13011 // guarantee that the memory region is contiguous and has no holes in it. 13012 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 13013 Length = TempOASE->getLength(); 13014 if (Length == nullptr) { 13015 // For array sections of the form [1:] or [:], we would need to analyze 13016 // the lower bound... 13017 if (OASE->getColonLoc().isValid()) 13018 return false; 13019 13020 // This is an array subscript which has implicit length 1! 13021 ArraySizes.push_back(llvm::APSInt::get(1)); 13022 } else { 13023 Expr::EvalResult Result; 13024 if (!Length->EvaluateAsInt(Result, Context)) 13025 return false; 13026 13027 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 13028 if (ConstantLengthValue.getSExtValue() != 1) 13029 return false; 13030 13031 ArraySizes.push_back(ConstantLengthValue); 13032 } 13033 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 13034 } 13035 13036 // If we have a single element, we don't need to add the implicit lengths. 13037 if (!SingleElement) { 13038 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 13039 // Has implicit length 1! 13040 ArraySizes.push_back(llvm::APSInt::get(1)); 13041 Base = TempASE->getBase()->IgnoreParenImpCasts(); 13042 } 13043 } 13044 13045 // This array section can be privatized as a single value or as a constant 13046 // sized array. 13047 return true; 13048} 13049 13050static bool actOnOMPReductionKindClause( 13051 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 13052 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13053 SourceLocation ColonLoc, SourceLocation EndLoc, 13054 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13055 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 13056 DeclarationName DN = ReductionId.getName(); 13057 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 13058 BinaryOperatorKind BOK = BO_Comma; 13059 13060 ASTContext &Context = S.Context; 13061 // OpenMP [2.14.3.6, reduction clause] 13062 // C 13063 // reduction-identifier is either an identifier or one of the following 13064 // operators: +, -, *, &, |, ^, && and || 13065 // C++ 13066 // reduction-identifier is either an id-expression or one of the following 13067 // operators: +, -, *, &, |, ^, && and || 13068 switch (OOK) { 13069 case OO_Plus: 13070 case OO_Minus: 13071 BOK = BO_Add; 13072 break; 13073 case OO_Star: 13074 BOK = BO_Mul; 13075 break; 13076 case OO_Amp: 13077 BOK = BO_And; 13078 break; 13079 case OO_Pipe: 13080 BOK = BO_Or; 13081 break; 13082 case OO_Caret: 13083 BOK = BO_Xor; 13084 break; 13085 case OO_AmpAmp: 13086 BOK = BO_LAnd; 13087 break; 13088 case OO_PipePipe: 13089 BOK = BO_LOr; 13090 break; 13091 case OO_New: 13092 case OO_Delete: 13093 case OO_Array_New: 13094 case OO_Array_Delete: 13095 case OO_Slash: 13096 case OO_Percent: 13097 case OO_Tilde: 13098 case OO_Exclaim: 13099 case OO_Equal: 13100 case OO_Less: 13101 case OO_Greater: 13102 case OO_LessEqual: 13103 case OO_GreaterEqual: 13104 case OO_PlusEqual: 13105 case OO_MinusEqual: 13106 case OO_StarEqual: 13107 case OO_SlashEqual: 13108 case OO_PercentEqual: 13109 case OO_CaretEqual: 13110 case OO_AmpEqual: 13111 case OO_PipeEqual: 13112 case OO_LessLess: 13113 case OO_GreaterGreater: 13114 case OO_LessLessEqual: 13115 case OO_GreaterGreaterEqual: 13116 case OO_EqualEqual: 13117 case OO_ExclaimEqual: 13118 case OO_Spaceship: 13119 case OO_PlusPlus: 13120 case OO_MinusMinus: 13121 case OO_Comma: 13122 case OO_ArrowStar: 13123 case OO_Arrow: 13124 case OO_Call: 13125 case OO_Subscript: 13126 case OO_Conditional: 13127 case OO_Coawait: 13128 case NUM_OVERLOADED_OPERATORS: 13129 llvm_unreachable("Unexpected reduction identifier"); 13130 case OO_None: 13131 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 13132 if (II->isStr("max")) 13133 BOK = BO_GT; 13134 else if (II->isStr("min")) 13135 BOK = BO_LT; 13136 } 13137 break; 13138 } 13139 SourceRange ReductionIdRange; 13140 if (ReductionIdScopeSpec.isValid()) 13141 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 13142 else 13143 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 13144 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 13145 13146 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 13147 bool FirstIter = true; 13148 for (Expr *RefExpr : VarList) { 13149 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 13150 // OpenMP [2.1, C/C++] 13151 // A list item is a variable or array section, subject to the restrictions 13152 // specified in Section 2.4 on page 42 and in each of the sections 13153 // describing clauses and directives for which a list appears. 13154 // OpenMP [2.14.3.3, Restrictions, p.1] 13155 // A variable that is part of another variable (as an array or 13156 // structure element) cannot appear in a private clause. 13157 if (!FirstIter && IR != ER) 13158 ++IR; 13159 FirstIter = false; 13160 SourceLocation ELoc; 13161 SourceRange ERange; 13162 Expr *SimpleRefExpr = RefExpr; 13163 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 13164 /*AllowArraySection=*/true); 13165 if (Res.second) { 13166 // Try to find 'declare reduction' corresponding construct before using 13167 // builtin/overloaded operators. 13168 QualType Type = Context.DependentTy; 13169 CXXCastPath BasePath; 13170 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13171 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13172 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13173 Expr *ReductionOp = nullptr; 13174 if (S.CurContext->isDependentContext() && 13175 (DeclareReductionRef.isUnset() || 13176 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 13177 ReductionOp = DeclareReductionRef.get(); 13178 // It will be analyzed later. 13179 RD.push(RefExpr, ReductionOp); 13180 } 13181 ValueDecl *D = Res.first; 13182 if (!D) 13183 continue; 13184 13185 Expr *TaskgroupDescriptor = nullptr; 13186 QualType Type; 13187 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 13188 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 13189 if (ASE) { 13190 Type = ASE->getType().getNonReferenceType(); 13191 } else if (OASE) { 13192 QualType BaseType = 13193 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 13194 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 13195 Type = ATy->getElementType(); 13196 else 13197 Type = BaseType->getPointeeType(); 13198 Type = Type.getNonReferenceType(); 13199 } else { 13200 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 13201 } 13202 auto *VD = dyn_cast<VarDecl>(D); 13203 13204 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13205 // A variable that appears in a private clause must not have an incomplete 13206 // type or a reference type. 13207 if (S.RequireCompleteType(ELoc, D->getType(), 13208 diag::err_omp_reduction_incomplete_type)) 13209 continue; 13210 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13211 // A list item that appears in a reduction clause must not be 13212 // const-qualified. 13213 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 13214 /*AcceptIfMutable*/ false, ASE || OASE)) 13215 continue; 13216 13217 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 13218 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 13219 // If a list-item is a reference type then it must bind to the same object 13220 // for all threads of the team. 13221 if (!ASE && !OASE) { 13222 if (VD) { 13223 VarDecl *VDDef = VD->getDefinition(); 13224 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 13225 DSARefChecker Check(Stack); 13226 if (Check.Visit(VDDef->getInit())) { 13227 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 13228 << getOpenMPClauseName(ClauseKind) << ERange; 13229 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 13230 continue; 13231 } 13232 } 13233 } 13234 13235 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13236 // in a Construct] 13237 // Variables with the predetermined data-sharing attributes may not be 13238 // listed in data-sharing attributes clauses, except for the cases 13239 // listed below. For these exceptions only, listing a predetermined 13240 // variable in a data-sharing attribute clause is allowed and overrides 13241 // the variable's predetermined data-sharing attributes. 13242 // OpenMP [2.14.3.6, Restrictions, p.3] 13243 // Any number of reduction clauses can be specified on the directive, 13244 // but a list item can appear only once in the reduction clauses for that 13245 // directive. 13246 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 13247 if (DVar.CKind == OMPC_reduction) { 13248 S.Diag(ELoc, diag::err_omp_once_referenced) 13249 << getOpenMPClauseName(ClauseKind); 13250 if (DVar.RefExpr) 13251 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 13252 continue; 13253 } 13254 if (DVar.CKind != OMPC_unknown) { 13255 S.Diag(ELoc, diag::err_omp_wrong_dsa) 13256 << getOpenMPClauseName(DVar.CKind) 13257 << getOpenMPClauseName(OMPC_reduction); 13258 reportOriginalDsa(S, Stack, D, DVar); 13259 continue; 13260 } 13261 13262 // OpenMP [2.14.3.6, Restrictions, p.1] 13263 // A list item that appears in a reduction clause of a worksharing 13264 // construct must be shared in the parallel regions to which any of the 13265 // worksharing regions arising from the worksharing construct bind. 13266 if (isOpenMPWorksharingDirective(CurrDir) && 13267 !isOpenMPParallelDirective(CurrDir) && 13268 !isOpenMPTeamsDirective(CurrDir)) { 13269 DVar = Stack->getImplicitDSA(D, true); 13270 if (DVar.CKind != OMPC_shared) { 13271 S.Diag(ELoc, diag::err_omp_required_access) 13272 << getOpenMPClauseName(OMPC_reduction) 13273 << getOpenMPClauseName(OMPC_shared); 13274 reportOriginalDsa(S, Stack, D, DVar); 13275 continue; 13276 } 13277 } 13278 } 13279 13280 // Try to find 'declare reduction' corresponding construct before using 13281 // builtin/overloaded operators. 13282 CXXCastPath BasePath; 13283 ExprResult DeclareReductionRef = buildDeclareReductionRef( 13284 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 13285 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 13286 if (DeclareReductionRef.isInvalid()) 13287 continue; 13288 if (S.CurContext->isDependentContext() && 13289 (DeclareReductionRef.isUnset() || 13290 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 13291 RD.push(RefExpr, DeclareReductionRef.get()); 13292 continue; 13293 } 13294 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 13295 // Not allowed reduction identifier is found. 13296 S.Diag(ReductionId.getBeginLoc(), 13297 diag::err_omp_unknown_reduction_identifier) 13298 << Type << ReductionIdRange; 13299 continue; 13300 } 13301 13302 // OpenMP [2.14.3.6, reduction clause, Restrictions] 13303 // The type of a list item that appears in a reduction clause must be valid 13304 // for the reduction-identifier. For a max or min reduction in C, the type 13305 // of the list item must be an allowed arithmetic data type: char, int, 13306 // float, double, or _Bool, possibly modified with long, short, signed, or 13307 // unsigned. For a max or min reduction in C++, the type of the list item 13308 // must be an allowed arithmetic data type: char, wchar_t, int, float, 13309 // double, or bool, possibly modified with long, short, signed, or unsigned. 13310 if (DeclareReductionRef.isUnset()) { 13311 if ((BOK == BO_GT || BOK == BO_LT) && 13312 !(Type->isScalarType() || 13313 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 13314 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 13315 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 13316 if (!ASE && !OASE) { 13317 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13318 VarDecl::DeclarationOnly; 13319 S.Diag(D->getLocation(), 13320 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13321 << D; 13322 } 13323 continue; 13324 } 13325 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 13326 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 13327 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 13328 << getOpenMPClauseName(ClauseKind); 13329 if (!ASE && !OASE) { 13330 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13331 VarDecl::DeclarationOnly; 13332 S.Diag(D->getLocation(), 13333 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13334 << D; 13335 } 13336 continue; 13337 } 13338 } 13339 13340 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 13341 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 13342 D->hasAttrs() ? &D->getAttrs() : nullptr); 13343 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 13344 D->hasAttrs() ? &D->getAttrs() : nullptr); 13345 QualType PrivateTy = Type; 13346 13347 // Try if we can determine constant lengths for all array sections and avoid 13348 // the VLA. 13349 bool ConstantLengthOASE = false; 13350 if (OASE) { 13351 bool SingleElement; 13352 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 13353 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 13354 Context, OASE, SingleElement, ArraySizes); 13355 13356 // If we don't have a single element, we must emit a constant array type. 13357 if (ConstantLengthOASE && !SingleElement) { 13358 for (llvm::APSInt &Size : ArraySizes) 13359 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 13360 ArrayType::Normal, 13361 /*IndexTypeQuals=*/0); 13362 } 13363 } 13364 13365 if ((OASE && !ConstantLengthOASE) || 13366 (!OASE && !ASE && 13367 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 13368 if (!Context.getTargetInfo().isVLASupported()) { 13369 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 13370 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13371 S.Diag(ELoc, diag::note_vla_unsupported); 13372 } else { 13373 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 13374 S.targetDiag(ELoc, diag::note_vla_unsupported); 13375 } 13376 continue; 13377 } 13378 // For arrays/array sections only: 13379 // Create pseudo array type for private copy. The size for this array will 13380 // be generated during codegen. 13381 // For array subscripts or single variables Private Ty is the same as Type 13382 // (type of the variable or single array element). 13383 PrivateTy = Context.getVariableArrayType( 13384 Type, 13385 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 13386 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 13387 } else if (!ASE && !OASE && 13388 Context.getAsArrayType(D->getType().getNonReferenceType())) { 13389 PrivateTy = D->getType().getNonReferenceType(); 13390 } 13391 // Private copy. 13392 VarDecl *PrivateVD = 13393 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 13394 D->hasAttrs() ? &D->getAttrs() : nullptr, 13395 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13396 // Add initializer for private variable. 13397 Expr *Init = nullptr; 13398 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 13399 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 13400 if (DeclareReductionRef.isUsable()) { 13401 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 13402 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 13403 if (DRD->getInitializer()) { 13404 Init = DRDRef; 13405 RHSVD->setInit(DRDRef); 13406 RHSVD->setInitStyle(VarDecl::CallInit); 13407 } 13408 } else { 13409 switch (BOK) { 13410 case BO_Add: 13411 case BO_Xor: 13412 case BO_Or: 13413 case BO_LOr: 13414 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 13415 if (Type->isScalarType() || Type->isAnyComplexType()) 13416 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 13417 break; 13418 case BO_Mul: 13419 case BO_LAnd: 13420 if (Type->isScalarType() || Type->isAnyComplexType()) { 13421 // '*' and '&&' reduction ops - initializer is '1'. 13422 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 13423 } 13424 break; 13425 case BO_And: { 13426 // '&' reduction op - initializer is '~0'. 13427 QualType OrigType = Type; 13428 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 13429 Type = ComplexTy->getElementType(); 13430 if (Type->isRealFloatingType()) { 13431 llvm::APFloat InitValue = 13432 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 13433 /*isIEEE=*/true); 13434 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13435 Type, ELoc); 13436 } else if (Type->isScalarType()) { 13437 uint64_t Size = Context.getTypeSize(Type); 13438 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 13439 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 13440 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13441 } 13442 if (Init && OrigType->isAnyComplexType()) { 13443 // Init = 0xFFFF + 0xFFFFi; 13444 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 13445 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 13446 } 13447 Type = OrigType; 13448 break; 13449 } 13450 case BO_LT: 13451 case BO_GT: { 13452 // 'min' reduction op - initializer is 'Largest representable number in 13453 // the reduction list item type'. 13454 // 'max' reduction op - initializer is 'Least representable number in 13455 // the reduction list item type'. 13456 if (Type->isIntegerType() || Type->isPointerType()) { 13457 bool IsSigned = Type->hasSignedIntegerRepresentation(); 13458 uint64_t Size = Context.getTypeSize(Type); 13459 QualType IntTy = 13460 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 13461 llvm::APInt InitValue = 13462 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 13463 : llvm::APInt::getMinValue(Size) 13464 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 13465 : llvm::APInt::getMaxValue(Size); 13466 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 13467 if (Type->isPointerType()) { 13468 // Cast to pointer type. 13469 ExprResult CastExpr = S.BuildCStyleCastExpr( 13470 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 13471 if (CastExpr.isInvalid()) 13472 continue; 13473 Init = CastExpr.get(); 13474 } 13475 } else if (Type->isRealFloatingType()) { 13476 llvm::APFloat InitValue = llvm::APFloat::getLargest( 13477 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 13478 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 13479 Type, ELoc); 13480 } 13481 break; 13482 } 13483 case BO_PtrMemD: 13484 case BO_PtrMemI: 13485 case BO_MulAssign: 13486 case BO_Div: 13487 case BO_Rem: 13488 case BO_Sub: 13489 case BO_Shl: 13490 case BO_Shr: 13491 case BO_LE: 13492 case BO_GE: 13493 case BO_EQ: 13494 case BO_NE: 13495 case BO_Cmp: 13496 case BO_AndAssign: 13497 case BO_XorAssign: 13498 case BO_OrAssign: 13499 case BO_Assign: 13500 case BO_AddAssign: 13501 case BO_SubAssign: 13502 case BO_DivAssign: 13503 case BO_RemAssign: 13504 case BO_ShlAssign: 13505 case BO_ShrAssign: 13506 case BO_Comma: 13507 llvm_unreachable("Unexpected reduction operation"); 13508 } 13509 } 13510 if (Init && DeclareReductionRef.isUnset()) 13511 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 13512 else if (!Init) 13513 S.ActOnUninitializedDecl(RHSVD); 13514 if (RHSVD->isInvalidDecl()) 13515 continue; 13516 if (!RHSVD->hasInit() && 13517 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 13518 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 13519 << Type << ReductionIdRange; 13520 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13521 VarDecl::DeclarationOnly; 13522 S.Diag(D->getLocation(), 13523 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13524 << D; 13525 continue; 13526 } 13527 // Store initializer for single element in private copy. Will be used during 13528 // codegen. 13529 PrivateVD->setInit(RHSVD->getInit()); 13530 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 13531 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 13532 ExprResult ReductionOp; 13533 if (DeclareReductionRef.isUsable()) { 13534 QualType RedTy = DeclareReductionRef.get()->getType(); 13535 QualType PtrRedTy = Context.getPointerType(RedTy); 13536 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 13537 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 13538 if (!BasePath.empty()) { 13539 LHS = S.DefaultLvalueConversion(LHS.get()); 13540 RHS = S.DefaultLvalueConversion(RHS.get()); 13541 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13542 CK_UncheckedDerivedToBase, LHS.get(), 13543 &BasePath, LHS.get()->getValueKind()); 13544 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 13545 CK_UncheckedDerivedToBase, RHS.get(), 13546 &BasePath, RHS.get()->getValueKind()); 13547 } 13548 FunctionProtoType::ExtProtoInfo EPI; 13549 QualType Params[] = {PtrRedTy, PtrRedTy}; 13550 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 13551 auto *OVE = new (Context) OpaqueValueExpr( 13552 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 13553 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 13554 Expr *Args[] = {LHS.get(), RHS.get()}; 13555 ReductionOp = 13556 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 13557 } else { 13558 ReductionOp = S.BuildBinOp( 13559 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 13560 if (ReductionOp.isUsable()) { 13561 if (BOK != BO_LT && BOK != BO_GT) { 13562 ReductionOp = 13563 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13564 BO_Assign, LHSDRE, ReductionOp.get()); 13565 } else { 13566 auto *ConditionalOp = new (Context) 13567 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 13568 Type, VK_LValue, OK_Ordinary); 13569 ReductionOp = 13570 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 13571 BO_Assign, LHSDRE, ConditionalOp); 13572 } 13573 if (ReductionOp.isUsable()) 13574 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 13575 /*DiscardedValue*/ false); 13576 } 13577 if (!ReductionOp.isUsable()) 13578 continue; 13579 } 13580 13581 // OpenMP [2.15.4.6, Restrictions, p.2] 13582 // A list item that appears in an in_reduction clause of a task construct 13583 // must appear in a task_reduction clause of a construct associated with a 13584 // taskgroup region that includes the participating task in its taskgroup 13585 // set. The construct associated with the innermost region that meets this 13586 // condition must specify the same reduction-identifier as the in_reduction 13587 // clause. 13588 if (ClauseKind == OMPC_in_reduction) { 13589 SourceRange ParentSR; 13590 BinaryOperatorKind ParentBOK; 13591 const Expr *ParentReductionOp; 13592 Expr *ParentBOKTD, *ParentReductionOpTD; 13593 DSAStackTy::DSAVarData ParentBOKDSA = 13594 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 13595 ParentBOKTD); 13596 DSAStackTy::DSAVarData ParentReductionOpDSA = 13597 Stack->getTopMostTaskgroupReductionData( 13598 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 13599 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 13600 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 13601 if (!IsParentBOK && !IsParentReductionOp) { 13602 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 13603 continue; 13604 } 13605 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 13606 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 13607 IsParentReductionOp) { 13608 bool EmitError = true; 13609 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 13610 llvm::FoldingSetNodeID RedId, ParentRedId; 13611 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 13612 DeclareReductionRef.get()->Profile(RedId, Context, 13613 /*Canonical=*/true); 13614 EmitError = RedId != ParentRedId; 13615 } 13616 if (EmitError) { 13617 S.Diag(ReductionId.getBeginLoc(), 13618 diag::err_omp_reduction_identifier_mismatch) 13619 << ReductionIdRange << RefExpr->getSourceRange(); 13620 S.Diag(ParentSR.getBegin(), 13621 diag::note_omp_previous_reduction_identifier) 13622 << ParentSR 13623 << (IsParentBOK ? ParentBOKDSA.RefExpr 13624 : ParentReductionOpDSA.RefExpr) 13625 ->getSourceRange(); 13626 continue; 13627 } 13628 } 13629 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 13630 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 13631 } 13632 13633 DeclRefExpr *Ref = nullptr; 13634 Expr *VarsExpr = RefExpr->IgnoreParens(); 13635 if (!VD && !S.CurContext->isDependentContext()) { 13636 if (ASE || OASE) { 13637 TransformExprToCaptures RebuildToCapture(S, D); 13638 VarsExpr = 13639 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 13640 Ref = RebuildToCapture.getCapturedExpr(); 13641 } else { 13642 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 13643 } 13644 if (!S.isOpenMPCapturedDecl(D)) { 13645 RD.ExprCaptures.emplace_back(Ref->getDecl()); 13646 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13647 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 13648 if (!RefRes.isUsable()) 13649 continue; 13650 ExprResult PostUpdateRes = 13651 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 13652 RefRes.get()); 13653 if (!PostUpdateRes.isUsable()) 13654 continue; 13655 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 13656 Stack->getCurrentDirective() == OMPD_taskgroup) { 13657 S.Diag(RefExpr->getExprLoc(), 13658 diag::err_omp_reduction_non_addressable_expression) 13659 << RefExpr->getSourceRange(); 13660 continue; 13661 } 13662 RD.ExprPostUpdates.emplace_back( 13663 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 13664 } 13665 } 13666 } 13667 // All reduction items are still marked as reduction (to do not increase 13668 // code base size). 13669 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 13670 if (CurrDir == OMPD_taskgroup) { 13671 if (DeclareReductionRef.isUsable()) 13672 Stack->addTaskgroupReductionData(D, ReductionIdRange, 13673 DeclareReductionRef.get()); 13674 else 13675 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 13676 } 13677 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 13678 TaskgroupDescriptor); 13679 } 13680 return RD.Vars.empty(); 13681} 13682 13683OMPClause *Sema::ActOnOpenMPReductionClause( 13684 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13685 SourceLocation ColonLoc, SourceLocation EndLoc, 13686 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13687 ArrayRef<Expr *> UnresolvedReductions) { 13688 ReductionData RD(VarList.size()); 13689 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 13690 StartLoc, LParenLoc, ColonLoc, EndLoc, 13691 ReductionIdScopeSpec, ReductionId, 13692 UnresolvedReductions, RD)) 13693 return nullptr; 13694 13695 return OMPReductionClause::Create( 13696 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13697 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13698 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13699 buildPreInits(Context, RD.ExprCaptures), 13700 buildPostUpdate(*this, RD.ExprPostUpdates)); 13701} 13702 13703OMPClause *Sema::ActOnOpenMPTaskReductionClause( 13704 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13705 SourceLocation ColonLoc, SourceLocation EndLoc, 13706 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13707 ArrayRef<Expr *> UnresolvedReductions) { 13708 ReductionData RD(VarList.size()); 13709 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 13710 StartLoc, LParenLoc, ColonLoc, EndLoc, 13711 ReductionIdScopeSpec, ReductionId, 13712 UnresolvedReductions, RD)) 13713 return nullptr; 13714 13715 return OMPTaskReductionClause::Create( 13716 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13717 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13718 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 13719 buildPreInits(Context, RD.ExprCaptures), 13720 buildPostUpdate(*this, RD.ExprPostUpdates)); 13721} 13722 13723OMPClause *Sema::ActOnOpenMPInReductionClause( 13724 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 13725 SourceLocation ColonLoc, SourceLocation EndLoc, 13726 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 13727 ArrayRef<Expr *> UnresolvedReductions) { 13728 ReductionData RD(VarList.size()); 13729 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 13730 StartLoc, LParenLoc, ColonLoc, EndLoc, 13731 ReductionIdScopeSpec, ReductionId, 13732 UnresolvedReductions, RD)) 13733 return nullptr; 13734 13735 return OMPInReductionClause::Create( 13736 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 13737 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 13738 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 13739 buildPreInits(Context, RD.ExprCaptures), 13740 buildPostUpdate(*this, RD.ExprPostUpdates)); 13741} 13742 13743bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 13744 SourceLocation LinLoc) { 13745 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 13746 LinKind == OMPC_LINEAR_unknown) { 13747 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 13748 return true; 13749 } 13750 return false; 13751} 13752 13753bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 13754 OpenMPLinearClauseKind LinKind, 13755 QualType Type) { 13756 const auto *VD = dyn_cast_or_null<VarDecl>(D); 13757 // A variable must not have an incomplete type or a reference type. 13758 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 13759 return true; 13760 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 13761 !Type->isReferenceType()) { 13762 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 13763 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 13764 return true; 13765 } 13766 Type = Type.getNonReferenceType(); 13767 13768 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13769 // A variable that is privatized must not have a const-qualified type 13770 // unless it is of class type with a mutable member. This restriction does 13771 // not apply to the firstprivate clause. 13772 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 13773 return true; 13774 13775 // A list item must be of integral or pointer type. 13776 Type = Type.getUnqualifiedType().getCanonicalType(); 13777 const auto *Ty = Type.getTypePtrOrNull(); 13778 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 13779 !Ty->isPointerType())) { 13780 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 13781 if (D) { 13782 bool IsDecl = 13783 !VD || 13784 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13785 Diag(D->getLocation(), 13786 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13787 << D; 13788 } 13789 return true; 13790 } 13791 return false; 13792} 13793 13794OMPClause *Sema::ActOnOpenMPLinearClause( 13795 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 13796 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 13797 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 13798 SmallVector<Expr *, 8> Vars; 13799 SmallVector<Expr *, 8> Privates; 13800 SmallVector<Expr *, 8> Inits; 13801 SmallVector<Decl *, 4> ExprCaptures; 13802 SmallVector<Expr *, 4> ExprPostUpdates; 13803 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 13804 LinKind = OMPC_LINEAR_val; 13805 for (Expr *RefExpr : VarList) { 13806 assert(RefExpr && "NULL expr in OpenMP linear clause."); 13807 SourceLocation ELoc; 13808 SourceRange ERange; 13809 Expr *SimpleRefExpr = RefExpr; 13810 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13811 if (Res.second) { 13812 // It will be analyzed later. 13813 Vars.push_back(RefExpr); 13814 Privates.push_back(nullptr); 13815 Inits.push_back(nullptr); 13816 } 13817 ValueDecl *D = Res.first; 13818 if (!D) 13819 continue; 13820 13821 QualType Type = D->getType(); 13822 auto *VD = dyn_cast<VarDecl>(D); 13823 13824 // OpenMP [2.14.3.7, linear clause] 13825 // A list-item cannot appear in more than one linear clause. 13826 // A list-item that appears in a linear clause cannot appear in any 13827 // other data-sharing attribute clause. 13828 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13829 if (DVar.RefExpr) { 13830 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13831 << getOpenMPClauseName(OMPC_linear); 13832 reportOriginalDsa(*this, DSAStack, D, DVar); 13833 continue; 13834 } 13835 13836 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 13837 continue; 13838 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 13839 13840 // Build private copy of original var. 13841 VarDecl *Private = 13842 buildVarDecl(*this, ELoc, Type, D->getName(), 13843 D->hasAttrs() ? &D->getAttrs() : nullptr, 13844 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13845 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 13846 // Build var to save initial value. 13847 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 13848 Expr *InitExpr; 13849 DeclRefExpr *Ref = nullptr; 13850 if (!VD && !CurContext->isDependentContext()) { 13851 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13852 if (!isOpenMPCapturedDecl(D)) { 13853 ExprCaptures.push_back(Ref->getDecl()); 13854 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 13855 ExprResult RefRes = DefaultLvalueConversion(Ref); 13856 if (!RefRes.isUsable()) 13857 continue; 13858 ExprResult PostUpdateRes = 13859 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 13860 SimpleRefExpr, RefRes.get()); 13861 if (!PostUpdateRes.isUsable()) 13862 continue; 13863 ExprPostUpdates.push_back( 13864 IgnoredValueConversions(PostUpdateRes.get()).get()); 13865 } 13866 } 13867 } 13868 if (LinKind == OMPC_LINEAR_uval) 13869 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 13870 else 13871 InitExpr = VD ? SimpleRefExpr : Ref; 13872 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 13873 /*DirectInit=*/false); 13874 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 13875 13876 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 13877 Vars.push_back((VD || CurContext->isDependentContext()) 13878 ? RefExpr->IgnoreParens() 13879 : Ref); 13880 Privates.push_back(PrivateRef); 13881 Inits.push_back(InitRef); 13882 } 13883 13884 if (Vars.empty()) 13885 return nullptr; 13886 13887 Expr *StepExpr = Step; 13888 Expr *CalcStepExpr = nullptr; 13889 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 13890 !Step->isInstantiationDependent() && 13891 !Step->containsUnexpandedParameterPack()) { 13892 SourceLocation StepLoc = Step->getBeginLoc(); 13893 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 13894 if (Val.isInvalid()) 13895 return nullptr; 13896 StepExpr = Val.get(); 13897 13898 // Build var to save the step value. 13899 VarDecl *SaveVar = 13900 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 13901 ExprResult SaveRef = 13902 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 13903 ExprResult CalcStep = 13904 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 13905 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 13906 13907 // Warn about zero linear step (it would be probably better specified as 13908 // making corresponding variables 'const'). 13909 llvm::APSInt Result; 13910 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 13911 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 13912 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 13913 << (Vars.size() > 1); 13914 if (!IsConstant && CalcStep.isUsable()) { 13915 // Calculate the step beforehand instead of doing this on each iteration. 13916 // (This is not used if the number of iterations may be kfold-ed). 13917 CalcStepExpr = CalcStep.get(); 13918 } 13919 } 13920 13921 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 13922 ColonLoc, EndLoc, Vars, Privates, Inits, 13923 StepExpr, CalcStepExpr, 13924 buildPreInits(Context, ExprCaptures), 13925 buildPostUpdate(*this, ExprPostUpdates)); 13926} 13927 13928static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 13929 Expr *NumIterations, Sema &SemaRef, 13930 Scope *S, DSAStackTy *Stack) { 13931 // Walk the vars and build update/final expressions for the CodeGen. 13932 SmallVector<Expr *, 8> Updates; 13933 SmallVector<Expr *, 8> Finals; 13934 SmallVector<Expr *, 8> UsedExprs; 13935 Expr *Step = Clause.getStep(); 13936 Expr *CalcStep = Clause.getCalcStep(); 13937 // OpenMP [2.14.3.7, linear clause] 13938 // If linear-step is not specified it is assumed to be 1. 13939 if (!Step) 13940 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 13941 else if (CalcStep) 13942 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 13943 bool HasErrors = false; 13944 auto CurInit = Clause.inits().begin(); 13945 auto CurPrivate = Clause.privates().begin(); 13946 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 13947 for (Expr *RefExpr : Clause.varlists()) { 13948 SourceLocation ELoc; 13949 SourceRange ERange; 13950 Expr *SimpleRefExpr = RefExpr; 13951 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 13952 ValueDecl *D = Res.first; 13953 if (Res.second || !D) { 13954 Updates.push_back(nullptr); 13955 Finals.push_back(nullptr); 13956 HasErrors = true; 13957 continue; 13958 } 13959 auto &&Info = Stack->isLoopControlVariable(D); 13960 // OpenMP [2.15.11, distribute simd Construct] 13961 // A list item may not appear in a linear clause, unless it is the loop 13962 // iteration variable. 13963 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 13964 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 13965 SemaRef.Diag(ELoc, 13966 diag::err_omp_linear_distribute_var_non_loop_iteration); 13967 Updates.push_back(nullptr); 13968 Finals.push_back(nullptr); 13969 HasErrors = true; 13970 continue; 13971 } 13972 Expr *InitExpr = *CurInit; 13973 13974 // Build privatized reference to the current linear var. 13975 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 13976 Expr *CapturedRef; 13977 if (LinKind == OMPC_LINEAR_uval) 13978 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 13979 else 13980 CapturedRef = 13981 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 13982 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 13983 /*RefersToCapture=*/true); 13984 13985 // Build update: Var = InitExpr + IV * Step 13986 ExprResult Update; 13987 if (!Info.first) 13988 Update = buildCounterUpdate( 13989 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 13990 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 13991 else 13992 Update = *CurPrivate; 13993 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 13994 /*DiscardedValue*/ false); 13995 13996 // Build final: Var = InitExpr + NumIterations * Step 13997 ExprResult Final; 13998 if (!Info.first) 13999 Final = 14000 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 14001 InitExpr, NumIterations, Step, /*Subtract=*/false, 14002 /*IsNonRectangularLB=*/false); 14003 else 14004 Final = *CurPrivate; 14005 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 14006 /*DiscardedValue*/ false); 14007 14008 if (!Update.isUsable() || !Final.isUsable()) { 14009 Updates.push_back(nullptr); 14010 Finals.push_back(nullptr); 14011 UsedExprs.push_back(nullptr); 14012 HasErrors = true; 14013 } else { 14014 Updates.push_back(Update.get()); 14015 Finals.push_back(Final.get()); 14016 if (!Info.first) 14017 UsedExprs.push_back(SimpleRefExpr); 14018 } 14019 ++CurInit; 14020 ++CurPrivate; 14021 } 14022 if (Expr *S = Clause.getStep()) 14023 UsedExprs.push_back(S); 14024 // Fill the remaining part with the nullptr. 14025 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 14026 Clause.setUpdates(Updates); 14027 Clause.setFinals(Finals); 14028 Clause.setUsedExprs(UsedExprs); 14029 return HasErrors; 14030} 14031 14032OMPClause *Sema::ActOnOpenMPAlignedClause( 14033 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 14034 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 14035 SmallVector<Expr *, 8> Vars; 14036 for (Expr *RefExpr : VarList) { 14037 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14038 SourceLocation ELoc; 14039 SourceRange ERange; 14040 Expr *SimpleRefExpr = RefExpr; 14041 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14042 if (Res.second) { 14043 // It will be analyzed later. 14044 Vars.push_back(RefExpr); 14045 } 14046 ValueDecl *D = Res.first; 14047 if (!D) 14048 continue; 14049 14050 QualType QType = D->getType(); 14051 auto *VD = dyn_cast<VarDecl>(D); 14052 14053 // OpenMP [2.8.1, simd construct, Restrictions] 14054 // The type of list items appearing in the aligned clause must be 14055 // array, pointer, reference to array, or reference to pointer. 14056 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 14057 const Type *Ty = QType.getTypePtrOrNull(); 14058 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 14059 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 14060 << QType << getLangOpts().CPlusPlus << ERange; 14061 bool IsDecl = 14062 !VD || 14063 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14064 Diag(D->getLocation(), 14065 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14066 << D; 14067 continue; 14068 } 14069 14070 // OpenMP [2.8.1, simd construct, Restrictions] 14071 // A list-item cannot appear in more than one aligned clause. 14072 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 14073 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 14074 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 14075 << getOpenMPClauseName(OMPC_aligned); 14076 continue; 14077 } 14078 14079 DeclRefExpr *Ref = nullptr; 14080 if (!VD && isOpenMPCapturedDecl(D)) 14081 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14082 Vars.push_back(DefaultFunctionArrayConversion( 14083 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 14084 .get()); 14085 } 14086 14087 // OpenMP [2.8.1, simd construct, Description] 14088 // The parameter of the aligned clause, alignment, must be a constant 14089 // positive integer expression. 14090 // If no optional parameter is specified, implementation-defined default 14091 // alignments for SIMD instructions on the target platforms are assumed. 14092 if (Alignment != nullptr) { 14093 ExprResult AlignResult = 14094 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 14095 if (AlignResult.isInvalid()) 14096 return nullptr; 14097 Alignment = AlignResult.get(); 14098 } 14099 if (Vars.empty()) 14100 return nullptr; 14101 14102 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 14103 EndLoc, Vars, Alignment); 14104} 14105 14106OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 14107 SourceLocation StartLoc, 14108 SourceLocation LParenLoc, 14109 SourceLocation EndLoc) { 14110 SmallVector<Expr *, 8> Vars; 14111 SmallVector<Expr *, 8> SrcExprs; 14112 SmallVector<Expr *, 8> DstExprs; 14113 SmallVector<Expr *, 8> AssignmentOps; 14114 for (Expr *RefExpr : VarList) { 14115 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 14116 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14117 // It will be analyzed later. 14118 Vars.push_back(RefExpr); 14119 SrcExprs.push_back(nullptr); 14120 DstExprs.push_back(nullptr); 14121 AssignmentOps.push_back(nullptr); 14122 continue; 14123 } 14124 14125 SourceLocation ELoc = RefExpr->getExprLoc(); 14126 // OpenMP [2.1, C/C++] 14127 // A list item is a variable name. 14128 // OpenMP [2.14.4.1, Restrictions, p.1] 14129 // A list item that appears in a copyin clause must be threadprivate. 14130 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 14131 if (!DE || !isa<VarDecl>(DE->getDecl())) { 14132 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 14133 << 0 << RefExpr->getSourceRange(); 14134 continue; 14135 } 14136 14137 Decl *D = DE->getDecl(); 14138 auto *VD = cast<VarDecl>(D); 14139 14140 QualType Type = VD->getType(); 14141 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 14142 // It will be analyzed later. 14143 Vars.push_back(DE); 14144 SrcExprs.push_back(nullptr); 14145 DstExprs.push_back(nullptr); 14146 AssignmentOps.push_back(nullptr); 14147 continue; 14148 } 14149 14150 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 14151 // A list item that appears in a copyin clause must be threadprivate. 14152 if (!DSAStack->isThreadPrivate(VD)) { 14153 Diag(ELoc, diag::err_omp_required_access) 14154 << getOpenMPClauseName(OMPC_copyin) 14155 << getOpenMPDirectiveName(OMPD_threadprivate); 14156 continue; 14157 } 14158 14159 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14160 // A variable of class type (or array thereof) that appears in a 14161 // copyin clause requires an accessible, unambiguous copy assignment 14162 // operator for the class type. 14163 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 14164 VarDecl *SrcVD = 14165 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 14166 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14167 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 14168 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 14169 VarDecl *DstVD = 14170 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 14171 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 14172 DeclRefExpr *PseudoDstExpr = 14173 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 14174 // For arrays generate assignment operation for single element and replace 14175 // it by the original array element in CodeGen. 14176 ExprResult AssignmentOp = 14177 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 14178 PseudoSrcExpr); 14179 if (AssignmentOp.isInvalid()) 14180 continue; 14181 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 14182 /*DiscardedValue*/ false); 14183 if (AssignmentOp.isInvalid()) 14184 continue; 14185 14186 DSAStack->addDSA(VD, DE, OMPC_copyin); 14187 Vars.push_back(DE); 14188 SrcExprs.push_back(PseudoSrcExpr); 14189 DstExprs.push_back(PseudoDstExpr); 14190 AssignmentOps.push_back(AssignmentOp.get()); 14191 } 14192 14193 if (Vars.empty()) 14194 return nullptr; 14195 14196 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 14197 SrcExprs, DstExprs, AssignmentOps); 14198} 14199 14200OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 14201 SourceLocation StartLoc, 14202 SourceLocation LParenLoc, 14203 SourceLocation EndLoc) { 14204 SmallVector<Expr *, 8> Vars; 14205 SmallVector<Expr *, 8> SrcExprs; 14206 SmallVector<Expr *, 8> DstExprs; 14207 SmallVector<Expr *, 8> AssignmentOps; 14208 for (Expr *RefExpr : VarList) { 14209 assert(RefExpr && "NULL expr in OpenMP linear clause."); 14210 SourceLocation ELoc; 14211 SourceRange ERange; 14212 Expr *SimpleRefExpr = RefExpr; 14213 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14214 if (Res.second) { 14215 // It will be analyzed later. 14216 Vars.push_back(RefExpr); 14217 SrcExprs.push_back(nullptr); 14218 DstExprs.push_back(nullptr); 14219 AssignmentOps.push_back(nullptr); 14220 } 14221 ValueDecl *D = Res.first; 14222 if (!D) 14223 continue; 14224 14225 QualType Type = D->getType(); 14226 auto *VD = dyn_cast<VarDecl>(D); 14227 14228 // OpenMP [2.14.4.2, Restrictions, p.2] 14229 // A list item that appears in a copyprivate clause may not appear in a 14230 // private or firstprivate clause on the single construct. 14231 if (!VD || !DSAStack->isThreadPrivate(VD)) { 14232 DSAStackTy::DSAVarData DVar = 14233 DSAStack->getTopDSA(D, /*FromParent=*/false); 14234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 14235 DVar.RefExpr) { 14236 Diag(ELoc, diag::err_omp_wrong_dsa) 14237 << getOpenMPClauseName(DVar.CKind) 14238 << getOpenMPClauseName(OMPC_copyprivate); 14239 reportOriginalDsa(*this, DSAStack, D, DVar); 14240 continue; 14241 } 14242 14243 // OpenMP [2.11.4.2, Restrictions, p.1] 14244 // All list items that appear in a copyprivate clause must be either 14245 // threadprivate or private in the enclosing context. 14246 if (DVar.CKind == OMPC_unknown) { 14247 DVar = DSAStack->getImplicitDSA(D, false); 14248 if (DVar.CKind == OMPC_shared) { 14249 Diag(ELoc, diag::err_omp_required_access) 14250 << getOpenMPClauseName(OMPC_copyprivate) 14251 << "threadprivate or private in the enclosing context"; 14252 reportOriginalDsa(*this, DSAStack, D, DVar); 14253 continue; 14254 } 14255 } 14256 } 14257 14258 // Variably modified types are not supported. 14259 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 14260 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 14261 << getOpenMPClauseName(OMPC_copyprivate) << Type 14262 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14263 bool IsDecl = 14264 !VD || 14265 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 14266 Diag(D->getLocation(), 14267 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14268 << D; 14269 continue; 14270 } 14271 14272 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 14273 // A variable of class type (or array thereof) that appears in a 14274 // copyin clause requires an accessible, unambiguous copy assignment 14275 // operator for the class type. 14276 Type = Context.getBaseElementType(Type.getNonReferenceType()) 14277 .getUnqualifiedType(); 14278 VarDecl *SrcVD = 14279 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 14280 D->hasAttrs() ? &D->getAttrs() : nullptr); 14281 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 14282 VarDecl *DstVD = 14283 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 14284 D->hasAttrs() ? &D->getAttrs() : nullptr); 14285 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14286 ExprResult AssignmentOp = BuildBinOp( 14287 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 14288 if (AssignmentOp.isInvalid()) 14289 continue; 14290 AssignmentOp = 14291 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14292 if (AssignmentOp.isInvalid()) 14293 continue; 14294 14295 // No need to mark vars as copyprivate, they are already threadprivate or 14296 // implicitly private. 14297 assert(VD || isOpenMPCapturedDecl(D)); 14298 Vars.push_back( 14299 VD ? RefExpr->IgnoreParens() 14300 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 14301 SrcExprs.push_back(PseudoSrcExpr); 14302 DstExprs.push_back(PseudoDstExpr); 14303 AssignmentOps.push_back(AssignmentOp.get()); 14304 } 14305 14306 if (Vars.empty()) 14307 return nullptr; 14308 14309 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14310 Vars, SrcExprs, DstExprs, AssignmentOps); 14311} 14312 14313OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 14314 SourceLocation StartLoc, 14315 SourceLocation LParenLoc, 14316 SourceLocation EndLoc) { 14317 if (VarList.empty()) 14318 return nullptr; 14319 14320 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 14321} 14322 14323OMPClause * 14324Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 14325 SourceLocation DepLoc, SourceLocation ColonLoc, 14326 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 14327 SourceLocation LParenLoc, SourceLocation EndLoc) { 14328 if (DSAStack->getCurrentDirective() == OMPD_ordered && 14329 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 14330 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14331 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 14332 return nullptr; 14333 } 14334 if (DSAStack->getCurrentDirective() != OMPD_ordered && 14335 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 14336 DepKind == OMPC_DEPEND_sink)) { 14337 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 14338 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 14339 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 14340 /*Last=*/OMPC_DEPEND_unknown, Except) 14341 << getOpenMPClauseName(OMPC_depend); 14342 return nullptr; 14343 } 14344 SmallVector<Expr *, 8> Vars; 14345 DSAStackTy::OperatorOffsetTy OpsOffs; 14346 llvm::APSInt DepCounter(/*BitWidth=*/32); 14347 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 14348 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 14349 if (const Expr *OrderedCountExpr = 14350 DSAStack->getParentOrderedRegionParam().first) { 14351 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 14352 TotalDepCount.setIsUnsigned(/*Val=*/true); 14353 } 14354 } 14355 for (Expr *RefExpr : VarList) { 14356 assert(RefExpr && "NULL expr in OpenMP shared clause."); 14357 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 14358 // It will be analyzed later. 14359 Vars.push_back(RefExpr); 14360 continue; 14361 } 14362 14363 SourceLocation ELoc = RefExpr->getExprLoc(); 14364 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 14365 if (DepKind == OMPC_DEPEND_sink) { 14366 if (DSAStack->getParentOrderedRegionParam().first && 14367 DepCounter >= TotalDepCount) { 14368 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 14369 continue; 14370 } 14371 ++DepCounter; 14372 // OpenMP [2.13.9, Summary] 14373 // depend(dependence-type : vec), where dependence-type is: 14374 // 'sink' and where vec is the iteration vector, which has the form: 14375 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 14376 // where n is the value specified by the ordered clause in the loop 14377 // directive, xi denotes the loop iteration variable of the i-th nested 14378 // loop associated with the loop directive, and di is a constant 14379 // non-negative integer. 14380 if (CurContext->isDependentContext()) { 14381 // It will be analyzed later. 14382 Vars.push_back(RefExpr); 14383 continue; 14384 } 14385 SimpleExpr = SimpleExpr->IgnoreImplicit(); 14386 OverloadedOperatorKind OOK = OO_None; 14387 SourceLocation OOLoc; 14388 Expr *LHS = SimpleExpr; 14389 Expr *RHS = nullptr; 14390 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 14391 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 14392 OOLoc = BO->getOperatorLoc(); 14393 LHS = BO->getLHS()->IgnoreParenImpCasts(); 14394 RHS = BO->getRHS()->IgnoreParenImpCasts(); 14395 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 14396 OOK = OCE->getOperator(); 14397 OOLoc = OCE->getOperatorLoc(); 14398 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14399 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 14400 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 14401 OOK = MCE->getMethodDecl() 14402 ->getNameInfo() 14403 .getName() 14404 .getCXXOverloadedOperator(); 14405 OOLoc = MCE->getCallee()->getExprLoc(); 14406 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 14407 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 14408 } 14409 SourceLocation ELoc; 14410 SourceRange ERange; 14411 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 14412 if (Res.second) { 14413 // It will be analyzed later. 14414 Vars.push_back(RefExpr); 14415 } 14416 ValueDecl *D = Res.first; 14417 if (!D) 14418 continue; 14419 14420 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 14421 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 14422 continue; 14423 } 14424 if (RHS) { 14425 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 14426 RHS, OMPC_depend, /*StrictlyPositive=*/false); 14427 if (RHSRes.isInvalid()) 14428 continue; 14429 } 14430 if (!CurContext->isDependentContext() && 14431 DSAStack->getParentOrderedRegionParam().first && 14432 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 14433 const ValueDecl *VD = 14434 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 14435 if (VD) 14436 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 14437 << 1 << VD; 14438 else 14439 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 14440 continue; 14441 } 14442 OpsOffs.emplace_back(RHS, OOK); 14443 } else { 14444 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 14445 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 14446 (ASE && 14447 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 14448 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 14449 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14450 << RefExpr->getSourceRange(); 14451 continue; 14452 } 14453 14454 ExprResult Res; 14455 { 14456 Sema::TentativeAnalysisScope Trap(*this); 14457 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 14458 RefExpr->IgnoreParenImpCasts()); 14459 } 14460 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 14461 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 14462 << RefExpr->getSourceRange(); 14463 continue; 14464 } 14465 } 14466 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 14467 } 14468 14469 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 14470 TotalDepCount > VarList.size() && 14471 DSAStack->getParentOrderedRegionParam().first && 14472 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 14473 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 14474 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 14475 } 14476 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 14477 Vars.empty()) 14478 return nullptr; 14479 14480 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14481 DepKind, DepLoc, ColonLoc, Vars, 14482 TotalDepCount.getZExtValue()); 14483 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 14484 DSAStack->isParentOrderedRegion()) 14485 DSAStack->addDoacrossDependClause(C, OpsOffs); 14486 return C; 14487} 14488 14489OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 14490 SourceLocation LParenLoc, 14491 SourceLocation EndLoc) { 14492 Expr *ValExpr = Device; 14493 Stmt *HelperValStmt = nullptr; 14494 14495 // OpenMP [2.9.1, Restrictions] 14496 // The device expression must evaluate to a non-negative integer value. 14497 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 14498 /*StrictlyPositive=*/false)) 14499 return nullptr; 14500 14501 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14502 OpenMPDirectiveKind CaptureRegion = 14503 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 14504 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14505 ValExpr = MakeFullExpr(ValExpr).get(); 14506 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14507 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14508 HelperValStmt = buildPreInits(Context, Captures); 14509 } 14510 14511 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 14512 StartLoc, LParenLoc, EndLoc); 14513} 14514 14515static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 14516 DSAStackTy *Stack, QualType QTy, 14517 bool FullCheck = true) { 14518 NamedDecl *ND; 14519 if (QTy->isIncompleteType(&ND)) { 14520 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 14521 return false; 14522 } 14523 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 14524 !QTy.isTrivialType(SemaRef.Context)) 14525 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 14526 return true; 14527} 14528 14529/// Return true if it can be proven that the provided array expression 14530/// (array section or array subscript) does NOT specify the whole size of the 14531/// array whose base type is \a BaseQTy. 14532static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 14533 const Expr *E, 14534 QualType BaseQTy) { 14535 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14536 14537 // If this is an array subscript, it refers to the whole size if the size of 14538 // the dimension is constant and equals 1. Also, an array section assumes the 14539 // format of an array subscript if no colon is used. 14540 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 14541 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14542 return ATy->getSize().getSExtValue() != 1; 14543 // Size can't be evaluated statically. 14544 return false; 14545 } 14546 14547 assert(OASE && "Expecting array section if not an array subscript."); 14548 const Expr *LowerBound = OASE->getLowerBound(); 14549 const Expr *Length = OASE->getLength(); 14550 14551 // If there is a lower bound that does not evaluates to zero, we are not 14552 // covering the whole dimension. 14553 if (LowerBound) { 14554 Expr::EvalResult Result; 14555 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 14556 return false; // Can't get the integer value as a constant. 14557 14558 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 14559 if (ConstLowerBound.getSExtValue()) 14560 return true; 14561 } 14562 14563 // If we don't have a length we covering the whole dimension. 14564 if (!Length) 14565 return false; 14566 14567 // If the base is a pointer, we don't have a way to get the size of the 14568 // pointee. 14569 if (BaseQTy->isPointerType()) 14570 return false; 14571 14572 // We can only check if the length is the same as the size of the dimension 14573 // if we have a constant array. 14574 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 14575 if (!CATy) 14576 return false; 14577 14578 Expr::EvalResult Result; 14579 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14580 return false; // Can't get the integer value as a constant. 14581 14582 llvm::APSInt ConstLength = Result.Val.getInt(); 14583 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 14584} 14585 14586// Return true if it can be proven that the provided array expression (array 14587// section or array subscript) does NOT specify a single element of the array 14588// whose base type is \a BaseQTy. 14589static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 14590 const Expr *E, 14591 QualType BaseQTy) { 14592 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 14593 14594 // An array subscript always refer to a single element. Also, an array section 14595 // assumes the format of an array subscript if no colon is used. 14596 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 14597 return false; 14598 14599 assert(OASE && "Expecting array section if not an array subscript."); 14600 const Expr *Length = OASE->getLength(); 14601 14602 // If we don't have a length we have to check if the array has unitary size 14603 // for this dimension. Also, we should always expect a length if the base type 14604 // is pointer. 14605 if (!Length) { 14606 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 14607 return ATy->getSize().getSExtValue() != 1; 14608 // We cannot assume anything. 14609 return false; 14610 } 14611 14612 // Check if the length evaluates to 1. 14613 Expr::EvalResult Result; 14614 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 14615 return false; // Can't get the integer value as a constant. 14616 14617 llvm::APSInt ConstLength = Result.Val.getInt(); 14618 return ConstLength.getSExtValue() != 1; 14619} 14620 14621// Return the expression of the base of the mappable expression or null if it 14622// cannot be determined and do all the necessary checks to see if the expression 14623// is valid as a standalone mappable expression. In the process, record all the 14624// components of the expression. 14625static const Expr *checkMapClauseExpressionBase( 14626 Sema &SemaRef, Expr *E, 14627 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 14628 OpenMPClauseKind CKind, bool NoDiagnose) { 14629 SourceLocation ELoc = E->getExprLoc(); 14630 SourceRange ERange = E->getSourceRange(); 14631 14632 // The base of elements of list in a map clause have to be either: 14633 // - a reference to variable or field. 14634 // - a member expression. 14635 // - an array expression. 14636 // 14637 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 14638 // reference to 'r'. 14639 // 14640 // If we have: 14641 // 14642 // struct SS { 14643 // Bla S; 14644 // foo() { 14645 // #pragma omp target map (S.Arr[:12]); 14646 // } 14647 // } 14648 // 14649 // We want to retrieve the member expression 'this->S'; 14650 14651 const Expr *RelevantExpr = nullptr; 14652 14653 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 14654 // If a list item is an array section, it must specify contiguous storage. 14655 // 14656 // For this restriction it is sufficient that we make sure only references 14657 // to variables or fields and array expressions, and that no array sections 14658 // exist except in the rightmost expression (unless they cover the whole 14659 // dimension of the array). E.g. these would be invalid: 14660 // 14661 // r.ArrS[3:5].Arr[6:7] 14662 // 14663 // r.ArrS[3:5].x 14664 // 14665 // but these would be valid: 14666 // r.ArrS[3].Arr[6:7] 14667 // 14668 // r.ArrS[3].x 14669 14670 bool AllowUnitySizeArraySection = true; 14671 bool AllowWholeSizeArraySection = true; 14672 14673 while (!RelevantExpr) { 14674 E = E->IgnoreParenImpCasts(); 14675 14676 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 14677 if (!isa<VarDecl>(CurE->getDecl())) 14678 return nullptr; 14679 14680 RelevantExpr = CurE; 14681 14682 // If we got a reference to a declaration, we should not expect any array 14683 // section before that. 14684 AllowUnitySizeArraySection = false; 14685 AllowWholeSizeArraySection = false; 14686 14687 // Record the component. 14688 CurComponents.emplace_back(CurE, CurE->getDecl()); 14689 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 14690 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 14691 14692 if (isa<CXXThisExpr>(BaseE)) 14693 // We found a base expression: this->Val. 14694 RelevantExpr = CurE; 14695 else 14696 E = BaseE; 14697 14698 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 14699 if (!NoDiagnose) { 14700 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 14701 << CurE->getSourceRange(); 14702 return nullptr; 14703 } 14704 if (RelevantExpr) 14705 return nullptr; 14706 continue; 14707 } 14708 14709 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 14710 14711 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 14712 // A bit-field cannot appear in a map clause. 14713 // 14714 if (FD->isBitField()) { 14715 if (!NoDiagnose) { 14716 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 14717 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 14718 return nullptr; 14719 } 14720 if (RelevantExpr) 14721 return nullptr; 14722 continue; 14723 } 14724 14725 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14726 // If the type of a list item is a reference to a type T then the type 14727 // will be considered to be T for all purposes of this clause. 14728 QualType CurType = BaseE->getType().getNonReferenceType(); 14729 14730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 14731 // A list item cannot be a variable that is a member of a structure with 14732 // a union type. 14733 // 14734 if (CurType->isUnionType()) { 14735 if (!NoDiagnose) { 14736 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 14737 << CurE->getSourceRange(); 14738 return nullptr; 14739 } 14740 continue; 14741 } 14742 14743 // If we got a member expression, we should not expect any array section 14744 // before that: 14745 // 14746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 14747 // If a list item is an element of a structure, only the rightmost symbol 14748 // of the variable reference can be an array section. 14749 // 14750 AllowUnitySizeArraySection = false; 14751 AllowWholeSizeArraySection = false; 14752 14753 // Record the component. 14754 CurComponents.emplace_back(CurE, FD); 14755 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 14756 E = CurE->getBase()->IgnoreParenImpCasts(); 14757 14758 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 14759 if (!NoDiagnose) { 14760 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14761 << 0 << CurE->getSourceRange(); 14762 return nullptr; 14763 } 14764 continue; 14765 } 14766 14767 // If we got an array subscript that express the whole dimension we 14768 // can have any array expressions before. If it only expressing part of 14769 // the dimension, we can only have unitary-size array expressions. 14770 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 14771 E->getType())) 14772 AllowWholeSizeArraySection = false; 14773 14774 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14775 Expr::EvalResult Result; 14776 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 14777 if (!Result.Val.getInt().isNullValue()) { 14778 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14779 diag::err_omp_invalid_map_this_expr); 14780 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 14781 diag::note_omp_invalid_subscript_on_this_ptr_map); 14782 } 14783 } 14784 RelevantExpr = TE; 14785 } 14786 14787 // Record the component - we don't have any declaration associated. 14788 CurComponents.emplace_back(CurE, nullptr); 14789 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 14790 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 14791 E = CurE->getBase()->IgnoreParenImpCasts(); 14792 14793 QualType CurType = 14794 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14795 14796 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14797 // If the type of a list item is a reference to a type T then the type 14798 // will be considered to be T for all purposes of this clause. 14799 if (CurType->isReferenceType()) 14800 CurType = CurType->getPointeeType(); 14801 14802 bool IsPointer = CurType->isAnyPointerType(); 14803 14804 if (!IsPointer && !CurType->isArrayType()) { 14805 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 14806 << 0 << CurE->getSourceRange(); 14807 return nullptr; 14808 } 14809 14810 bool NotWhole = 14811 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 14812 bool NotUnity = 14813 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 14814 14815 if (AllowWholeSizeArraySection) { 14816 // Any array section is currently allowed. Allowing a whole size array 14817 // section implies allowing a unity array section as well. 14818 // 14819 // If this array section refers to the whole dimension we can still 14820 // accept other array sections before this one, except if the base is a 14821 // pointer. Otherwise, only unitary sections are accepted. 14822 if (NotWhole || IsPointer) 14823 AllowWholeSizeArraySection = false; 14824 } else if (AllowUnitySizeArraySection && NotUnity) { 14825 // A unity or whole array section is not allowed and that is not 14826 // compatible with the properties of the current array section. 14827 SemaRef.Diag( 14828 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 14829 << CurE->getSourceRange(); 14830 return nullptr; 14831 } 14832 14833 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 14834 Expr::EvalResult ResultR; 14835 Expr::EvalResult ResultL; 14836 if (CurE->getLength()->EvaluateAsInt(ResultR, 14837 SemaRef.getASTContext())) { 14838 if (!ResultR.Val.getInt().isOneValue()) { 14839 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14840 diag::err_omp_invalid_map_this_expr); 14841 SemaRef.Diag(CurE->getLength()->getExprLoc(), 14842 diag::note_omp_invalid_length_on_this_ptr_mapping); 14843 } 14844 } 14845 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 14846 ResultL, SemaRef.getASTContext())) { 14847 if (!ResultL.Val.getInt().isNullValue()) { 14848 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14849 diag::err_omp_invalid_map_this_expr); 14850 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 14851 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 14852 } 14853 } 14854 RelevantExpr = TE; 14855 } 14856 14857 // Record the component - we don't have any declaration associated. 14858 CurComponents.emplace_back(CurE, nullptr); 14859 } else { 14860 if (!NoDiagnose) { 14861 // If nothing else worked, this is not a valid map clause expression. 14862 SemaRef.Diag( 14863 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 14864 << ERange; 14865 } 14866 return nullptr; 14867 } 14868 } 14869 14870 return RelevantExpr; 14871} 14872 14873// Return true if expression E associated with value VD has conflicts with other 14874// map information. 14875static bool checkMapConflicts( 14876 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 14877 bool CurrentRegionOnly, 14878 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 14879 OpenMPClauseKind CKind) { 14880 assert(VD && E); 14881 SourceLocation ELoc = E->getExprLoc(); 14882 SourceRange ERange = E->getSourceRange(); 14883 14884 // In order to easily check the conflicts we need to match each component of 14885 // the expression under test with the components of the expressions that are 14886 // already in the stack. 14887 14888 assert(!CurComponents.empty() && "Map clause expression with no components!"); 14889 assert(CurComponents.back().getAssociatedDeclaration() == VD && 14890 "Map clause expression with unexpected base!"); 14891 14892 // Variables to help detecting enclosing problems in data environment nests. 14893 bool IsEnclosedByDataEnvironmentExpr = false; 14894 const Expr *EnclosingExpr = nullptr; 14895 14896 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 14897 VD, CurrentRegionOnly, 14898 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 14899 ERange, CKind, &EnclosingExpr, 14900 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 14901 StackComponents, 14902 OpenMPClauseKind) { 14903 assert(!StackComponents.empty() && 14904 "Map clause expression with no components!"); 14905 assert(StackComponents.back().getAssociatedDeclaration() == VD && 14906 "Map clause expression with unexpected base!"); 14907 (void)VD; 14908 14909 // The whole expression in the stack. 14910 const Expr *RE = StackComponents.front().getAssociatedExpression(); 14911 14912 // Expressions must start from the same base. Here we detect at which 14913 // point both expressions diverge from each other and see if we can 14914 // detect if the memory referred to both expressions is contiguous and 14915 // do not overlap. 14916 auto CI = CurComponents.rbegin(); 14917 auto CE = CurComponents.rend(); 14918 auto SI = StackComponents.rbegin(); 14919 auto SE = StackComponents.rend(); 14920 for (; CI != CE && SI != SE; ++CI, ++SI) { 14921 14922 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 14923 // At most one list item can be an array item derived from a given 14924 // variable in map clauses of the same construct. 14925 if (CurrentRegionOnly && 14926 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 14927 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 14928 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 14929 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 14930 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 14931 diag::err_omp_multiple_array_items_in_map_clause) 14932 << CI->getAssociatedExpression()->getSourceRange(); 14933 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 14934 diag::note_used_here) 14935 << SI->getAssociatedExpression()->getSourceRange(); 14936 return true; 14937 } 14938 14939 // Do both expressions have the same kind? 14940 if (CI->getAssociatedExpression()->getStmtClass() != 14941 SI->getAssociatedExpression()->getStmtClass()) 14942 break; 14943 14944 // Are we dealing with different variables/fields? 14945 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 14946 break; 14947 } 14948 // Check if the extra components of the expressions in the enclosing 14949 // data environment are redundant for the current base declaration. 14950 // If they are, the maps completely overlap, which is legal. 14951 for (; SI != SE; ++SI) { 14952 QualType Type; 14953 if (const auto *ASE = 14954 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 14955 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 14956 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 14957 SI->getAssociatedExpression())) { 14958 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 14959 Type = 14960 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 14961 } 14962 if (Type.isNull() || Type->isAnyPointerType() || 14963 checkArrayExpressionDoesNotReferToWholeSize( 14964 SemaRef, SI->getAssociatedExpression(), Type)) 14965 break; 14966 } 14967 14968 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 14969 // List items of map clauses in the same construct must not share 14970 // original storage. 14971 // 14972 // If the expressions are exactly the same or one is a subset of the 14973 // other, it means they are sharing storage. 14974 if (CI == CE && SI == SE) { 14975 if (CurrentRegionOnly) { 14976 if (CKind == OMPC_map) { 14977 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 14978 } else { 14979 assert(CKind == OMPC_to || CKind == OMPC_from); 14980 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 14981 << ERange; 14982 } 14983 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 14984 << RE->getSourceRange(); 14985 return true; 14986 } 14987 // If we find the same expression in the enclosing data environment, 14988 // that is legal. 14989 IsEnclosedByDataEnvironmentExpr = true; 14990 return false; 14991 } 14992 14993 QualType DerivedType = 14994 std::prev(CI)->getAssociatedDeclaration()->getType(); 14995 SourceLocation DerivedLoc = 14996 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 14997 14998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 14999 // If the type of a list item is a reference to a type T then the type 15000 // will be considered to be T for all purposes of this clause. 15001 DerivedType = DerivedType.getNonReferenceType(); 15002 15003 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 15004 // A variable for which the type is pointer and an array section 15005 // derived from that variable must not appear as list items of map 15006 // clauses of the same construct. 15007 // 15008 // Also, cover one of the cases in: 15009 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15010 // If any part of the original storage of a list item has corresponding 15011 // storage in the device data environment, all of the original storage 15012 // must have corresponding storage in the device data environment. 15013 // 15014 if (DerivedType->isAnyPointerType()) { 15015 if (CI == CE || SI == SE) { 15016 SemaRef.Diag( 15017 DerivedLoc, 15018 diag::err_omp_pointer_mapped_along_with_derived_section) 15019 << DerivedLoc; 15020 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15021 << RE->getSourceRange(); 15022 return true; 15023 } 15024 if (CI->getAssociatedExpression()->getStmtClass() != 15025 SI->getAssociatedExpression()->getStmtClass() || 15026 CI->getAssociatedDeclaration()->getCanonicalDecl() == 15027 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 15028 assert(CI != CE && SI != SE); 15029 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 15030 << DerivedLoc; 15031 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15032 << RE->getSourceRange(); 15033 return true; 15034 } 15035 } 15036 15037 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 15038 // List items of map clauses in the same construct must not share 15039 // original storage. 15040 // 15041 // An expression is a subset of the other. 15042 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 15043 if (CKind == OMPC_map) { 15044 if (CI != CE || SI != SE) { 15045 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 15046 // a pointer. 15047 auto Begin = 15048 CI != CE ? CurComponents.begin() : StackComponents.begin(); 15049 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 15050 auto It = Begin; 15051 while (It != End && !It->getAssociatedDeclaration()) 15052 std::advance(It, 1); 15053 assert(It != End && 15054 "Expected at least one component with the declaration."); 15055 if (It != Begin && It->getAssociatedDeclaration() 15056 ->getType() 15057 .getCanonicalType() 15058 ->isAnyPointerType()) { 15059 IsEnclosedByDataEnvironmentExpr = false; 15060 EnclosingExpr = nullptr; 15061 return false; 15062 } 15063 } 15064 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 15065 } else { 15066 assert(CKind == OMPC_to || CKind == OMPC_from); 15067 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 15068 << ERange; 15069 } 15070 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 15071 << RE->getSourceRange(); 15072 return true; 15073 } 15074 15075 // The current expression uses the same base as other expression in the 15076 // data environment but does not contain it completely. 15077 if (!CurrentRegionOnly && SI != SE) 15078 EnclosingExpr = RE; 15079 15080 // The current expression is a subset of the expression in the data 15081 // environment. 15082 IsEnclosedByDataEnvironmentExpr |= 15083 (!CurrentRegionOnly && CI != CE && SI == SE); 15084 15085 return false; 15086 }); 15087 15088 if (CurrentRegionOnly) 15089 return FoundError; 15090 15091 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 15092 // If any part of the original storage of a list item has corresponding 15093 // storage in the device data environment, all of the original storage must 15094 // have corresponding storage in the device data environment. 15095 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 15096 // If a list item is an element of a structure, and a different element of 15097 // the structure has a corresponding list item in the device data environment 15098 // prior to a task encountering the construct associated with the map clause, 15099 // then the list item must also have a corresponding list item in the device 15100 // data environment prior to the task encountering the construct. 15101 // 15102 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 15103 SemaRef.Diag(ELoc, 15104 diag::err_omp_original_storage_is_shared_and_does_not_contain) 15105 << ERange; 15106 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 15107 << EnclosingExpr->getSourceRange(); 15108 return true; 15109 } 15110 15111 return FoundError; 15112} 15113 15114// Look up the user-defined mapper given the mapper name and mapped type, and 15115// build a reference to it. 15116static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 15117 CXXScopeSpec &MapperIdScopeSpec, 15118 const DeclarationNameInfo &MapperId, 15119 QualType Type, 15120 Expr *UnresolvedMapper) { 15121 if (MapperIdScopeSpec.isInvalid()) 15122 return ExprError(); 15123 // Get the actual type for the array type. 15124 if (Type->isArrayType()) { 15125 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 15126 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 15127 } 15128 // Find all user-defined mappers with the given MapperId. 15129 SmallVector<UnresolvedSet<8>, 4> Lookups; 15130 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 15131 Lookup.suppressDiagnostics(); 15132 if (S) { 15133 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 15134 NamedDecl *D = Lookup.getRepresentativeDecl(); 15135 while (S && !S->isDeclScope(D)) 15136 S = S->getParent(); 15137 if (S) 15138 S = S->getParent(); 15139 Lookups.emplace_back(); 15140 Lookups.back().append(Lookup.begin(), Lookup.end()); 15141 Lookup.clear(); 15142 } 15143 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 15144 // Extract the user-defined mappers with the given MapperId. 15145 Lookups.push_back(UnresolvedSet<8>()); 15146 for (NamedDecl *D : ULE->decls()) { 15147 auto *DMD = cast<OMPDeclareMapperDecl>(D); 15148 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 15149 Lookups.back().addDecl(DMD); 15150 } 15151 } 15152 // Defer the lookup for dependent types. The results will be passed through 15153 // UnresolvedMapper on instantiation. 15154 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 15155 Type->isInstantiationDependentType() || 15156 Type->containsUnexpandedParameterPack() || 15157 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 15158 return !D->isInvalidDecl() && 15159 (D->getType()->isDependentType() || 15160 D->getType()->isInstantiationDependentType() || 15161 D->getType()->containsUnexpandedParameterPack()); 15162 })) { 15163 UnresolvedSet<8> URS; 15164 for (const UnresolvedSet<8> &Set : Lookups) { 15165 if (Set.empty()) 15166 continue; 15167 URS.append(Set.begin(), Set.end()); 15168 } 15169 return UnresolvedLookupExpr::Create( 15170 SemaRef.Context, /*NamingClass=*/nullptr, 15171 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 15172 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 15173 } 15174 SourceLocation Loc = MapperId.getLoc(); 15175 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15176 // The type must be of struct, union or class type in C and C++ 15177 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 15178 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 15179 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 15180 return ExprError(); 15181 } 15182 // Perform argument dependent lookup. 15183 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 15184 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 15185 // Return the first user-defined mapper with the desired type. 15186 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15187 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 15188 if (!D->isInvalidDecl() && 15189 SemaRef.Context.hasSameType(D->getType(), Type)) 15190 return D; 15191 return nullptr; 15192 })) 15193 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15194 // Find the first user-defined mapper with a type derived from the desired 15195 // type. 15196 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 15197 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 15198 if (!D->isInvalidDecl() && 15199 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 15200 !Type.isMoreQualifiedThan(D->getType())) 15201 return D; 15202 return nullptr; 15203 })) { 15204 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 15205 /*DetectVirtual=*/false); 15206 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 15207 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 15208 VD->getType().getUnqualifiedType()))) { 15209 if (SemaRef.CheckBaseClassAccess( 15210 Loc, VD->getType(), Type, Paths.front(), 15211 /*DiagID=*/0) != Sema::AR_inaccessible) { 15212 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 15213 } 15214 } 15215 } 15216 } 15217 // Report error if a mapper is specified, but cannot be found. 15218 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 15219 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 15220 << Type << MapperId.getName(); 15221 return ExprError(); 15222 } 15223 return ExprEmpty(); 15224} 15225 15226namespace { 15227// Utility struct that gathers all the related lists associated with a mappable 15228// expression. 15229struct MappableVarListInfo { 15230 // The list of expressions. 15231 ArrayRef<Expr *> VarList; 15232 // The list of processed expressions. 15233 SmallVector<Expr *, 16> ProcessedVarList; 15234 // The mappble components for each expression. 15235 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 15236 // The base declaration of the variable. 15237 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 15238 // The reference to the user-defined mapper associated with every expression. 15239 SmallVector<Expr *, 16> UDMapperList; 15240 15241 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 15242 // We have a list of components and base declarations for each entry in the 15243 // variable list. 15244 VarComponents.reserve(VarList.size()); 15245 VarBaseDeclarations.reserve(VarList.size()); 15246 } 15247}; 15248} 15249 15250// Check the validity of the provided variable list for the provided clause kind 15251// \a CKind. In the check process the valid expressions, mappable expression 15252// components, variables, and user-defined mappers are extracted and used to 15253// fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 15254// UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 15255// and \a MapperId are expected to be valid if the clause kind is 'map'. 15256static void checkMappableExpressionList( 15257 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 15258 MappableVarListInfo &MVLI, SourceLocation StartLoc, 15259 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 15260 ArrayRef<Expr *> UnresolvedMappers, 15261 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 15262 bool IsMapTypeImplicit = false) { 15263 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 15264 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 15265 "Unexpected clause kind with mappable expressions!"); 15266 15267 // If the identifier of user-defined mapper is not specified, it is "default". 15268 // We do not change the actual name in this clause to distinguish whether a 15269 // mapper is specified explicitly, i.e., it is not explicitly specified when 15270 // MapperId.getName() is empty. 15271 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 15272 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 15273 MapperId.setName(DeclNames.getIdentifier( 15274 &SemaRef.getASTContext().Idents.get("default"))); 15275 } 15276 15277 // Iterators to find the current unresolved mapper expression. 15278 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 15279 bool UpdateUMIt = false; 15280 Expr *UnresolvedMapper = nullptr; 15281 15282 // Keep track of the mappable components and base declarations in this clause. 15283 // Each entry in the list is going to have a list of components associated. We 15284 // record each set of the components so that we can build the clause later on. 15285 // In the end we should have the same amount of declarations and component 15286 // lists. 15287 15288 for (Expr *RE : MVLI.VarList) { 15289 assert(RE && "Null expr in omp to/from/map clause"); 15290 SourceLocation ELoc = RE->getExprLoc(); 15291 15292 // Find the current unresolved mapper expression. 15293 if (UpdateUMIt && UMIt != UMEnd) { 15294 UMIt++; 15295 assert( 15296 UMIt != UMEnd && 15297 "Expect the size of UnresolvedMappers to match with that of VarList"); 15298 } 15299 UpdateUMIt = true; 15300 if (UMIt != UMEnd) 15301 UnresolvedMapper = *UMIt; 15302 15303 const Expr *VE = RE->IgnoreParenLValueCasts(); 15304 15305 if (VE->isValueDependent() || VE->isTypeDependent() || 15306 VE->isInstantiationDependent() || 15307 VE->containsUnexpandedParameterPack()) { 15308 // Try to find the associated user-defined mapper. 15309 ExprResult ER = buildUserDefinedMapperRef( 15310 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15311 VE->getType().getCanonicalType(), UnresolvedMapper); 15312 if (ER.isInvalid()) 15313 continue; 15314 MVLI.UDMapperList.push_back(ER.get()); 15315 // We can only analyze this information once the missing information is 15316 // resolved. 15317 MVLI.ProcessedVarList.push_back(RE); 15318 continue; 15319 } 15320 15321 Expr *SimpleExpr = RE->IgnoreParenCasts(); 15322 15323 if (!RE->IgnoreParenImpCasts()->isLValue()) { 15324 SemaRef.Diag(ELoc, 15325 diag::err_omp_expected_named_var_member_or_array_expression) 15326 << RE->getSourceRange(); 15327 continue; 15328 } 15329 15330 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 15331 ValueDecl *CurDeclaration = nullptr; 15332 15333 // Obtain the array or member expression bases if required. Also, fill the 15334 // components array with all the components identified in the process. 15335 const Expr *BE = checkMapClauseExpressionBase( 15336 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 15337 if (!BE) 15338 continue; 15339 15340 assert(!CurComponents.empty() && 15341 "Invalid mappable expression information."); 15342 15343 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 15344 // Add store "this" pointer to class in DSAStackTy for future checking 15345 DSAS->addMappedClassesQualTypes(TE->getType()); 15346 // Try to find the associated user-defined mapper. 15347 ExprResult ER = buildUserDefinedMapperRef( 15348 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15349 VE->getType().getCanonicalType(), UnresolvedMapper); 15350 if (ER.isInvalid()) 15351 continue; 15352 MVLI.UDMapperList.push_back(ER.get()); 15353 // Skip restriction checking for variable or field declarations 15354 MVLI.ProcessedVarList.push_back(RE); 15355 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15356 MVLI.VarComponents.back().append(CurComponents.begin(), 15357 CurComponents.end()); 15358 MVLI.VarBaseDeclarations.push_back(nullptr); 15359 continue; 15360 } 15361 15362 // For the following checks, we rely on the base declaration which is 15363 // expected to be associated with the last component. The declaration is 15364 // expected to be a variable or a field (if 'this' is being mapped). 15365 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 15366 assert(CurDeclaration && "Null decl on map clause."); 15367 assert( 15368 CurDeclaration->isCanonicalDecl() && 15369 "Expecting components to have associated only canonical declarations."); 15370 15371 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 15372 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 15373 15374 assert((VD || FD) && "Only variables or fields are expected here!"); 15375 (void)FD; 15376 15377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 15378 // threadprivate variables cannot appear in a map clause. 15379 // OpenMP 4.5 [2.10.5, target update Construct] 15380 // threadprivate variables cannot appear in a from clause. 15381 if (VD && DSAS->isThreadPrivate(VD)) { 15382 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15383 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 15384 << getOpenMPClauseName(CKind); 15385 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 15386 continue; 15387 } 15388 15389 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15390 // A list item cannot appear in both a map clause and a data-sharing 15391 // attribute clause on the same construct. 15392 15393 // Check conflicts with other map clause expressions. We check the conflicts 15394 // with the current construct separately from the enclosing data 15395 // environment, because the restrictions are different. We only have to 15396 // check conflicts across regions for the map clauses. 15397 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15398 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 15399 break; 15400 if (CKind == OMPC_map && 15401 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 15402 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 15403 break; 15404 15405 // OpenMP 4.5 [2.10.5, target update Construct] 15406 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 15407 // If the type of a list item is a reference to a type T then the type will 15408 // be considered to be T for all purposes of this clause. 15409 auto I = llvm::find_if( 15410 CurComponents, 15411 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 15412 return MC.getAssociatedDeclaration(); 15413 }); 15414 assert(I != CurComponents.end() && "Null decl on map clause."); 15415 QualType Type = 15416 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 15417 15418 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 15419 // A list item in a to or from clause must have a mappable type. 15420 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 15421 // A list item must have a mappable type. 15422 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 15423 DSAS, Type)) 15424 continue; 15425 15426 if (CKind == OMPC_map) { 15427 // target enter data 15428 // OpenMP [2.10.2, Restrictions, p. 99] 15429 // A map-type must be specified in all map clauses and must be either 15430 // to or alloc. 15431 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 15432 if (DKind == OMPD_target_enter_data && 15433 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 15434 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15435 << (IsMapTypeImplicit ? 1 : 0) 15436 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15437 << getOpenMPDirectiveName(DKind); 15438 continue; 15439 } 15440 15441 // target exit_data 15442 // OpenMP [2.10.3, Restrictions, p. 102] 15443 // A map-type must be specified in all map clauses and must be either 15444 // from, release, or delete. 15445 if (DKind == OMPD_target_exit_data && 15446 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 15447 MapType == OMPC_MAP_delete)) { 15448 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 15449 << (IsMapTypeImplicit ? 1 : 0) 15450 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 15451 << getOpenMPDirectiveName(DKind); 15452 continue; 15453 } 15454 15455 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 15456 // A list item cannot appear in both a map clause and a data-sharing 15457 // attribute clause on the same construct 15458 // 15459 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 15460 // A list item cannot appear in both a map clause and a data-sharing 15461 // attribute clause on the same construct unless the construct is a 15462 // combined construct. 15463 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 15464 isOpenMPTargetExecutionDirective(DKind)) || 15465 DKind == OMPD_target)) { 15466 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 15467 if (isOpenMPPrivate(DVar.CKind)) { 15468 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 15469 << getOpenMPClauseName(DVar.CKind) 15470 << getOpenMPClauseName(OMPC_map) 15471 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 15472 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 15473 continue; 15474 } 15475 } 15476 } 15477 15478 // Try to find the associated user-defined mapper. 15479 ExprResult ER = buildUserDefinedMapperRef( 15480 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 15481 Type.getCanonicalType(), UnresolvedMapper); 15482 if (ER.isInvalid()) 15483 continue; 15484 MVLI.UDMapperList.push_back(ER.get()); 15485 15486 // Save the current expression. 15487 MVLI.ProcessedVarList.push_back(RE); 15488 15489 // Store the components in the stack so that they can be used to check 15490 // against other clauses later on. 15491 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 15492 /*WhereFoundClauseKind=*/OMPC_map); 15493 15494 // Save the components and declaration to create the clause. For purposes of 15495 // the clause creation, any component list that has has base 'this' uses 15496 // null as base declaration. 15497 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 15498 MVLI.VarComponents.back().append(CurComponents.begin(), 15499 CurComponents.end()); 15500 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 15501 : CurDeclaration); 15502 } 15503} 15504 15505OMPClause *Sema::ActOnOpenMPMapClause( 15506 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 15507 ArrayRef<SourceLocation> MapTypeModifiersLoc, 15508 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 15509 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 15510 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 15511 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 15512 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 15513 OMPC_MAP_MODIFIER_unknown, 15514 OMPC_MAP_MODIFIER_unknown}; 15515 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 15516 15517 // Process map-type-modifiers, flag errors for duplicate modifiers. 15518 unsigned Count = 0; 15519 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 15520 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 15521 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 15522 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 15523 continue; 15524 } 15525 assert(Count < OMPMapClause::NumberOfModifiers && 15526 "Modifiers exceed the allowed number of map type modifiers"); 15527 Modifiers[Count] = MapTypeModifiers[I]; 15528 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 15529 ++Count; 15530 } 15531 15532 MappableVarListInfo MVLI(VarList); 15533 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 15534 MapperIdScopeSpec, MapperId, UnresolvedMappers, 15535 MapType, IsMapTypeImplicit); 15536 15537 // We need to produce a map clause even if we don't have variables so that 15538 // other diagnostics related with non-existing map clauses are accurate. 15539 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 15540 MVLI.VarBaseDeclarations, MVLI.VarComponents, 15541 MVLI.UDMapperList, Modifiers, ModifiersLoc, 15542 MapperIdScopeSpec.getWithLocInContext(Context), 15543 MapperId, MapType, IsMapTypeImplicit, MapLoc); 15544} 15545 15546QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 15547 TypeResult ParsedType) { 15548 assert(ParsedType.isUsable()); 15549 15550 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 15551 if (ReductionType.isNull()) 15552 return QualType(); 15553 15554 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 15555 // A type name in a declare reduction directive cannot be a function type, an 15556 // array type, a reference type, or a type qualified with const, volatile or 15557 // restrict. 15558 if (ReductionType.hasQualifiers()) { 15559 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 15560 return QualType(); 15561 } 15562 15563 if (ReductionType->isFunctionType()) { 15564 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 15565 return QualType(); 15566 } 15567 if (ReductionType->isReferenceType()) { 15568 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 15569 return QualType(); 15570 } 15571 if (ReductionType->isArrayType()) { 15572 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 15573 return QualType(); 15574 } 15575 return ReductionType; 15576} 15577 15578Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 15579 Scope *S, DeclContext *DC, DeclarationName Name, 15580 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 15581 AccessSpecifier AS, Decl *PrevDeclInScope) { 15582 SmallVector<Decl *, 8> Decls; 15583 Decls.reserve(ReductionTypes.size()); 15584 15585 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 15586 forRedeclarationInCurContext()); 15587 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 15588 // A reduction-identifier may not be re-declared in the current scope for the 15589 // same type or for a type that is compatible according to the base language 15590 // rules. 15591 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15592 OMPDeclareReductionDecl *PrevDRD = nullptr; 15593 bool InCompoundScope = true; 15594 if (S != nullptr) { 15595 // Find previous declaration with the same name not referenced in other 15596 // declarations. 15597 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15598 InCompoundScope = 15599 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15600 LookupName(Lookup, S); 15601 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15602 /*AllowInlineNamespace=*/false); 15603 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 15604 LookupResult::Filter Filter = Lookup.makeFilter(); 15605 while (Filter.hasNext()) { 15606 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 15607 if (InCompoundScope) { 15608 auto I = UsedAsPrevious.find(PrevDecl); 15609 if (I == UsedAsPrevious.end()) 15610 UsedAsPrevious[PrevDecl] = false; 15611 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 15612 UsedAsPrevious[D] = true; 15613 } 15614 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15615 PrevDecl->getLocation(); 15616 } 15617 Filter.done(); 15618 if (InCompoundScope) { 15619 for (const auto &PrevData : UsedAsPrevious) { 15620 if (!PrevData.second) { 15621 PrevDRD = PrevData.first; 15622 break; 15623 } 15624 } 15625 } 15626 } else if (PrevDeclInScope != nullptr) { 15627 auto *PrevDRDInScope = PrevDRD = 15628 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 15629 do { 15630 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 15631 PrevDRDInScope->getLocation(); 15632 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 15633 } while (PrevDRDInScope != nullptr); 15634 } 15635 for (const auto &TyData : ReductionTypes) { 15636 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 15637 bool Invalid = false; 15638 if (I != PreviousRedeclTypes.end()) { 15639 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 15640 << TyData.first; 15641 Diag(I->second, diag::note_previous_definition); 15642 Invalid = true; 15643 } 15644 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 15645 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 15646 Name, TyData.first, PrevDRD); 15647 DC->addDecl(DRD); 15648 DRD->setAccess(AS); 15649 Decls.push_back(DRD); 15650 if (Invalid) 15651 DRD->setInvalidDecl(); 15652 else 15653 PrevDRD = DRD; 15654 } 15655 15656 return DeclGroupPtrTy::make( 15657 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 15658} 15659 15660void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 15661 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15662 15663 // Enter new function scope. 15664 PushFunctionScope(); 15665 setFunctionHasBranchProtectedScope(); 15666 getCurFunction()->setHasOMPDeclareReductionCombiner(); 15667 15668 if (S != nullptr) 15669 PushDeclContext(S, DRD); 15670 else 15671 CurContext = DRD; 15672 15673 PushExpressionEvaluationContext( 15674 ExpressionEvaluationContext::PotentiallyEvaluated); 15675 15676 QualType ReductionType = DRD->getType(); 15677 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 15678 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 15679 // uses semantics of argument handles by value, but it should be passed by 15680 // reference. C lang does not support references, so pass all parameters as 15681 // pointers. 15682 // Create 'T omp_in;' variable. 15683 VarDecl *OmpInParm = 15684 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 15685 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 15686 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 15687 // uses semantics of argument handles by value, but it should be passed by 15688 // reference. C lang does not support references, so pass all parameters as 15689 // pointers. 15690 // Create 'T omp_out;' variable. 15691 VarDecl *OmpOutParm = 15692 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 15693 if (S != nullptr) { 15694 PushOnScopeChains(OmpInParm, S); 15695 PushOnScopeChains(OmpOutParm, S); 15696 } else { 15697 DRD->addDecl(OmpInParm); 15698 DRD->addDecl(OmpOutParm); 15699 } 15700 Expr *InE = 15701 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 15702 Expr *OutE = 15703 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 15704 DRD->setCombinerData(InE, OutE); 15705} 15706 15707void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 15708 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15709 DiscardCleanupsInEvaluationContext(); 15710 PopExpressionEvaluationContext(); 15711 15712 PopDeclContext(); 15713 PopFunctionScopeInfo(); 15714 15715 if (Combiner != nullptr) 15716 DRD->setCombiner(Combiner); 15717 else 15718 DRD->setInvalidDecl(); 15719} 15720 15721VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 15722 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15723 15724 // Enter new function scope. 15725 PushFunctionScope(); 15726 setFunctionHasBranchProtectedScope(); 15727 15728 if (S != nullptr) 15729 PushDeclContext(S, DRD); 15730 else 15731 CurContext = DRD; 15732 15733 PushExpressionEvaluationContext( 15734 ExpressionEvaluationContext::PotentiallyEvaluated); 15735 15736 QualType ReductionType = DRD->getType(); 15737 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 15738 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 15739 // uses semantics of argument handles by value, but it should be passed by 15740 // reference. C lang does not support references, so pass all parameters as 15741 // pointers. 15742 // Create 'T omp_priv;' variable. 15743 VarDecl *OmpPrivParm = 15744 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 15745 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 15746 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 15747 // uses semantics of argument handles by value, but it should be passed by 15748 // reference. C lang does not support references, so pass all parameters as 15749 // pointers. 15750 // Create 'T omp_orig;' variable. 15751 VarDecl *OmpOrigParm = 15752 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 15753 if (S != nullptr) { 15754 PushOnScopeChains(OmpPrivParm, S); 15755 PushOnScopeChains(OmpOrigParm, S); 15756 } else { 15757 DRD->addDecl(OmpPrivParm); 15758 DRD->addDecl(OmpOrigParm); 15759 } 15760 Expr *OrigE = 15761 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 15762 Expr *PrivE = 15763 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 15764 DRD->setInitializerData(OrigE, PrivE); 15765 return OmpPrivParm; 15766} 15767 15768void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 15769 VarDecl *OmpPrivParm) { 15770 auto *DRD = cast<OMPDeclareReductionDecl>(D); 15771 DiscardCleanupsInEvaluationContext(); 15772 PopExpressionEvaluationContext(); 15773 15774 PopDeclContext(); 15775 PopFunctionScopeInfo(); 15776 15777 if (Initializer != nullptr) { 15778 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 15779 } else if (OmpPrivParm->hasInit()) { 15780 DRD->setInitializer(OmpPrivParm->getInit(), 15781 OmpPrivParm->isDirectInit() 15782 ? OMPDeclareReductionDecl::DirectInit 15783 : OMPDeclareReductionDecl::CopyInit); 15784 } else { 15785 DRD->setInvalidDecl(); 15786 } 15787} 15788 15789Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 15790 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 15791 for (Decl *D : DeclReductions.get()) { 15792 if (IsValid) { 15793 if (S) 15794 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 15795 /*AddToContext=*/false); 15796 } else { 15797 D->setInvalidDecl(); 15798 } 15799 } 15800 return DeclReductions; 15801} 15802 15803TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 15804 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 15805 QualType T = TInfo->getType(); 15806 if (D.isInvalidType()) 15807 return true; 15808 15809 if (getLangOpts().CPlusPlus) { 15810 // Check that there are no default arguments (C++ only). 15811 CheckExtraCXXDefaultArguments(D); 15812 } 15813 15814 return CreateParsedType(T, TInfo); 15815} 15816 15817QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 15818 TypeResult ParsedType) { 15819 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 15820 15821 QualType MapperType = GetTypeFromParser(ParsedType.get()); 15822 assert(!MapperType.isNull() && "Expect valid mapper type"); 15823 15824 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15825 // The type must be of struct, union or class type in C and C++ 15826 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 15827 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 15828 return QualType(); 15829 } 15830 return MapperType; 15831} 15832 15833OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 15834 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 15835 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 15836 Decl *PrevDeclInScope) { 15837 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 15838 forRedeclarationInCurContext()); 15839 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 15840 // A mapper-identifier may not be redeclared in the current scope for the 15841 // same type or for a type that is compatible according to the base language 15842 // rules. 15843 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 15844 OMPDeclareMapperDecl *PrevDMD = nullptr; 15845 bool InCompoundScope = true; 15846 if (S != nullptr) { 15847 // Find previous declaration with the same name not referenced in other 15848 // declarations. 15849 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 15850 InCompoundScope = 15851 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 15852 LookupName(Lookup, S); 15853 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 15854 /*AllowInlineNamespace=*/false); 15855 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 15856 LookupResult::Filter Filter = Lookup.makeFilter(); 15857 while (Filter.hasNext()) { 15858 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 15859 if (InCompoundScope) { 15860 auto I = UsedAsPrevious.find(PrevDecl); 15861 if (I == UsedAsPrevious.end()) 15862 UsedAsPrevious[PrevDecl] = false; 15863 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 15864 UsedAsPrevious[D] = true; 15865 } 15866 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 15867 PrevDecl->getLocation(); 15868 } 15869 Filter.done(); 15870 if (InCompoundScope) { 15871 for (const auto &PrevData : UsedAsPrevious) { 15872 if (!PrevData.second) { 15873 PrevDMD = PrevData.first; 15874 break; 15875 } 15876 } 15877 } 15878 } else if (PrevDeclInScope) { 15879 auto *PrevDMDInScope = PrevDMD = 15880 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 15881 do { 15882 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 15883 PrevDMDInScope->getLocation(); 15884 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 15885 } while (PrevDMDInScope != nullptr); 15886 } 15887 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 15888 bool Invalid = false; 15889 if (I != PreviousRedeclTypes.end()) { 15890 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 15891 << MapperType << Name; 15892 Diag(I->second, diag::note_previous_definition); 15893 Invalid = true; 15894 } 15895 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 15896 MapperType, VN, PrevDMD); 15897 DC->addDecl(DMD); 15898 DMD->setAccess(AS); 15899 if (Invalid) 15900 DMD->setInvalidDecl(); 15901 15902 // Enter new function scope. 15903 PushFunctionScope(); 15904 setFunctionHasBranchProtectedScope(); 15905 15906 CurContext = DMD; 15907 15908 return DMD; 15909} 15910 15911void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 15912 Scope *S, 15913 QualType MapperType, 15914 SourceLocation StartLoc, 15915 DeclarationName VN) { 15916 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 15917 if (S) 15918 PushOnScopeChains(VD, S); 15919 else 15920 DMD->addDecl(VD); 15921 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 15922 DMD->setMapperVarRef(MapperVarRefExpr); 15923} 15924 15925Sema::DeclGroupPtrTy 15926Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 15927 ArrayRef<OMPClause *> ClauseList) { 15928 PopDeclContext(); 15929 PopFunctionScopeInfo(); 15930 15931 if (D) { 15932 if (S) 15933 PushOnScopeChains(D, S, /*AddToContext=*/false); 15934 D->CreateClauses(Context, ClauseList); 15935 } 15936 15937 return DeclGroupPtrTy::make(DeclGroupRef(D)); 15938} 15939 15940OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 15941 SourceLocation StartLoc, 15942 SourceLocation LParenLoc, 15943 SourceLocation EndLoc) { 15944 Expr *ValExpr = NumTeams; 15945 Stmt *HelperValStmt = nullptr; 15946 15947 // OpenMP [teams Constrcut, Restrictions] 15948 // The num_teams expression must evaluate to a positive integer value. 15949 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 15950 /*StrictlyPositive=*/true)) 15951 return nullptr; 15952 15953 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15954 OpenMPDirectiveKind CaptureRegion = 15955 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 15956 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15957 ValExpr = MakeFullExpr(ValExpr).get(); 15958 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15959 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15960 HelperValStmt = buildPreInits(Context, Captures); 15961 } 15962 15963 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 15964 StartLoc, LParenLoc, EndLoc); 15965} 15966 15967OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 15968 SourceLocation StartLoc, 15969 SourceLocation LParenLoc, 15970 SourceLocation EndLoc) { 15971 Expr *ValExpr = ThreadLimit; 15972 Stmt *HelperValStmt = nullptr; 15973 15974 // OpenMP [teams Constrcut, Restrictions] 15975 // The thread_limit expression must evaluate to a positive integer value. 15976 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 15977 /*StrictlyPositive=*/true)) 15978 return nullptr; 15979 15980 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15981 OpenMPDirectiveKind CaptureRegion = 15982 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 15983 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15984 ValExpr = MakeFullExpr(ValExpr).get(); 15985 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15986 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15987 HelperValStmt = buildPreInits(Context, Captures); 15988 } 15989 15990 return new (Context) OMPThreadLimitClause( 15991 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15992} 15993 15994OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 15995 SourceLocation StartLoc, 15996 SourceLocation LParenLoc, 15997 SourceLocation EndLoc) { 15998 Expr *ValExpr = Priority; 15999 Stmt *HelperValStmt = nullptr; 16000 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16001 16002 // OpenMP [2.9.1, task Constrcut] 16003 // The priority-value is a non-negative numerical scalar expression. 16004 if (!isNonNegativeIntegerValue( 16005 ValExpr, *this, OMPC_priority, 16006 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 16007 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16008 return nullptr; 16009 16010 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 16011 StartLoc, LParenLoc, EndLoc); 16012} 16013 16014OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 16015 SourceLocation StartLoc, 16016 SourceLocation LParenLoc, 16017 SourceLocation EndLoc) { 16018 Expr *ValExpr = Grainsize; 16019 Stmt *HelperValStmt = nullptr; 16020 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16021 16022 // OpenMP [2.9.2, taskloop Constrcut] 16023 // The parameter of the grainsize clause must be a positive integer 16024 // expression. 16025 if (!isNonNegativeIntegerValue( 16026 ValExpr, *this, OMPC_grainsize, 16027 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16028 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16029 return nullptr; 16030 16031 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 16032 StartLoc, LParenLoc, EndLoc); 16033} 16034 16035OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 16036 SourceLocation StartLoc, 16037 SourceLocation LParenLoc, 16038 SourceLocation EndLoc) { 16039 Expr *ValExpr = NumTasks; 16040 Stmt *HelperValStmt = nullptr; 16041 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 16042 16043 // OpenMP [2.9.2, taskloop Constrcut] 16044 // The parameter of the num_tasks clause must be a positive integer 16045 // expression. 16046 if (!isNonNegativeIntegerValue( 16047 ValExpr, *this, OMPC_num_tasks, 16048 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 16049 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 16050 return nullptr; 16051 16052 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 16053 StartLoc, LParenLoc, EndLoc); 16054} 16055 16056OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 16057 SourceLocation LParenLoc, 16058 SourceLocation EndLoc) { 16059 // OpenMP [2.13.2, critical construct, Description] 16060 // ... where hint-expression is an integer constant expression that evaluates 16061 // to a valid lock hint. 16062 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 16063 if (HintExpr.isInvalid()) 16064 return nullptr; 16065 return new (Context) 16066 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 16067} 16068 16069OMPClause *Sema::ActOnOpenMPDistScheduleClause( 16070 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16071 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 16072 SourceLocation EndLoc) { 16073 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 16074 std::string Values; 16075 Values += "'"; 16076 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 16077 Values += "'"; 16078 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16079 << Values << getOpenMPClauseName(OMPC_dist_schedule); 16080 return nullptr; 16081 } 16082 Expr *ValExpr = ChunkSize; 16083 Stmt *HelperValStmt = nullptr; 16084 if (ChunkSize) { 16085 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16086 !ChunkSize->isInstantiationDependent() && 16087 !ChunkSize->containsUnexpandedParameterPack()) { 16088 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16089 ExprResult Val = 16090 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16091 if (Val.isInvalid()) 16092 return nullptr; 16093 16094 ValExpr = Val.get(); 16095 16096 // OpenMP [2.7.1, Restrictions] 16097 // chunk_size must be a loop invariant integer expression with a positive 16098 // value. 16099 llvm::APSInt Result; 16100 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 16101 if (Result.isSigned() && !Result.isStrictlyPositive()) { 16102 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16103 << "dist_schedule" << ChunkSize->getSourceRange(); 16104 return nullptr; 16105 } 16106 } else if (getOpenMPCaptureRegionForClause( 16107 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 16108 OMPD_unknown && 16109 !CurContext->isDependentContext()) { 16110 ValExpr = MakeFullExpr(ValExpr).get(); 16111 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16112 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16113 HelperValStmt = buildPreInits(Context, Captures); 16114 } 16115 } 16116 } 16117 16118 return new (Context) 16119 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 16120 Kind, ValExpr, HelperValStmt); 16121} 16122 16123OMPClause *Sema::ActOnOpenMPDefaultmapClause( 16124 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 16125 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 16126 SourceLocation KindLoc, SourceLocation EndLoc) { 16127 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 16128 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 16129 std::string Value; 16130 SourceLocation Loc; 16131 Value += "'"; 16132 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 16133 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16134 OMPC_DEFAULTMAP_MODIFIER_tofrom); 16135 Loc = MLoc; 16136 } else { 16137 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 16138 OMPC_DEFAULTMAP_scalar); 16139 Loc = KindLoc; 16140 } 16141 Value += "'"; 16142 Diag(Loc, diag::err_omp_unexpected_clause_value) 16143 << Value << getOpenMPClauseName(OMPC_defaultmap); 16144 return nullptr; 16145 } 16146 DSAStack->setDefaultDMAToFromScalar(StartLoc); 16147 16148 return new (Context) 16149 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 16150} 16151 16152bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 16153 DeclContext *CurLexicalContext = getCurLexicalContext(); 16154 if (!CurLexicalContext->isFileContext() && 16155 !CurLexicalContext->isExternCContext() && 16156 !CurLexicalContext->isExternCXXContext() && 16157 !isa<CXXRecordDecl>(CurLexicalContext) && 16158 !isa<ClassTemplateDecl>(CurLexicalContext) && 16159 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 16160 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 16161 Diag(Loc, diag::err_omp_region_not_file_context); 16162 return false; 16163 } 16164 ++DeclareTargetNestingLevel; 16165 return true; 16166} 16167 16168void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 16169 assert(DeclareTargetNestingLevel > 0 && 16170 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 16171 --DeclareTargetNestingLevel; 16172} 16173 16174NamedDecl * 16175Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 16176 const DeclarationNameInfo &Id, 16177 NamedDeclSetType &SameDirectiveDecls) { 16178 LookupResult Lookup(*this, Id, LookupOrdinaryName); 16179 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 16180 16181 if (Lookup.isAmbiguous()) 16182 return nullptr; 16183 Lookup.suppressDiagnostics(); 16184 16185 if (!Lookup.isSingleResult()) { 16186 VarOrFuncDeclFilterCCC CCC(*this); 16187 if (TypoCorrection Corrected = 16188 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 16189 CTK_ErrorRecovery)) { 16190 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 16191 << Id.getName()); 16192 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 16193 return nullptr; 16194 } 16195 16196 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 16197 return nullptr; 16198 } 16199 16200 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 16201 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 16202 !isa<FunctionTemplateDecl>(ND)) { 16203 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 16204 return nullptr; 16205 } 16206 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 16207 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 16208 return ND; 16209} 16210 16211void Sema::ActOnOpenMPDeclareTargetName( 16212 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 16213 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 16214 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 16215 isa<FunctionTemplateDecl>(ND)) && 16216 "Expected variable, function or function template."); 16217 16218 // Diagnose marking after use as it may lead to incorrect diagnosis and 16219 // codegen. 16220 if (LangOpts.OpenMP >= 50 && 16221 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 16222 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 16223 16224 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16225 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 16226 if (DevTy.hasValue() && *DevTy != DT) { 16227 Diag(Loc, diag::err_omp_device_type_mismatch) 16228 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 16229 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 16230 return; 16231 } 16232 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16233 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 16234 if (!Res) { 16235 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 16236 SourceRange(Loc, Loc)); 16237 ND->addAttr(A); 16238 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16239 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 16240 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 16241 } else if (*Res != MT) { 16242 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 16243 } 16244} 16245 16246static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 16247 Sema &SemaRef, Decl *D) { 16248 if (!D || !isa<VarDecl>(D)) 16249 return; 16250 auto *VD = cast<VarDecl>(D); 16251 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16252 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16253 if (SemaRef.LangOpts.OpenMP >= 50 && 16254 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 16255 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 16256 VD->hasGlobalStorage()) { 16257 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 16258 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 16259 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 16260 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 16261 // If a lambda declaration and definition appears between a 16262 // declare target directive and the matching end declare target 16263 // directive, all variables that are captured by the lambda 16264 // expression must also appear in a to clause. 16265 SemaRef.Diag(VD->getLocation(), 16266 diag::err_omp_lambda_capture_in_declare_target_not_to); 16267 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 16268 << VD << 0 << SR; 16269 return; 16270 } 16271 } 16272 if (MapTy.hasValue()) 16273 return; 16274 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 16275 SemaRef.Diag(SL, diag::note_used_here) << SR; 16276} 16277 16278static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 16279 Sema &SemaRef, DSAStackTy *Stack, 16280 ValueDecl *VD) { 16281 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 16282 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 16283 /*FullCheck=*/false); 16284} 16285 16286void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 16287 SourceLocation IdLoc) { 16288 if (!D || D->isInvalidDecl()) 16289 return; 16290 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 16291 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 16292 if (auto *VD = dyn_cast<VarDecl>(D)) { 16293 // Only global variables can be marked as declare target. 16294 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 16295 !VD->isStaticDataMember()) 16296 return; 16297 // 2.10.6: threadprivate variable cannot appear in a declare target 16298 // directive. 16299 if (DSAStack->isThreadPrivate(VD)) { 16300 Diag(SL, diag::err_omp_threadprivate_in_target); 16301 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 16302 return; 16303 } 16304 } 16305 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 16306 D = FTD->getTemplatedDecl(); 16307 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 16308 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 16309 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 16310 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 16311 Diag(IdLoc, diag::err_omp_function_in_link_clause); 16312 Diag(FD->getLocation(), diag::note_defined_here) << FD; 16313 return; 16314 } 16315 // Mark the function as must be emitted for the device. 16316 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 16317 OMPDeclareTargetDeclAttr::getDeviceType(FD); 16318 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16319 *DevTy != OMPDeclareTargetDeclAttr::DT_Host) 16320 checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false); 16321 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() && 16322 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost) 16323 checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false); 16324 } 16325 if (auto *VD = dyn_cast<ValueDecl>(D)) { 16326 // Problem if any with var declared with incomplete type will be reported 16327 // as normal, so no need to check it here. 16328 if ((E || !VD->getType()->isIncompleteType()) && 16329 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 16330 return; 16331 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 16332 // Checking declaration inside declare target region. 16333 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 16334 isa<FunctionTemplateDecl>(D)) { 16335 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 16336 Context, OMPDeclareTargetDeclAttr::MT_To, 16337 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 16338 D->addAttr(A); 16339 if (ASTMutationListener *ML = Context.getASTMutationListener()) 16340 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 16341 } 16342 return; 16343 } 16344 } 16345 if (!E) 16346 return; 16347 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 16348} 16349 16350OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 16351 CXXScopeSpec &MapperIdScopeSpec, 16352 DeclarationNameInfo &MapperId, 16353 const OMPVarListLocTy &Locs, 16354 ArrayRef<Expr *> UnresolvedMappers) { 16355 MappableVarListInfo MVLI(VarList); 16356 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 16357 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16358 if (MVLI.ProcessedVarList.empty()) 16359 return nullptr; 16360 16361 return OMPToClause::Create( 16362 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16363 MVLI.VarComponents, MVLI.UDMapperList, 16364 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16365} 16366 16367OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 16368 CXXScopeSpec &MapperIdScopeSpec, 16369 DeclarationNameInfo &MapperId, 16370 const OMPVarListLocTy &Locs, 16371 ArrayRef<Expr *> UnresolvedMappers) { 16372 MappableVarListInfo MVLI(VarList); 16373 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 16374 MapperIdScopeSpec, MapperId, UnresolvedMappers); 16375 if (MVLI.ProcessedVarList.empty()) 16376 return nullptr; 16377 16378 return OMPFromClause::Create( 16379 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 16380 MVLI.VarComponents, MVLI.UDMapperList, 16381 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 16382} 16383 16384OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 16385 const OMPVarListLocTy &Locs) { 16386 MappableVarListInfo MVLI(VarList); 16387 SmallVector<Expr *, 8> PrivateCopies; 16388 SmallVector<Expr *, 8> Inits; 16389 16390 for (Expr *RefExpr : VarList) { 16391 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 16392 SourceLocation ELoc; 16393 SourceRange ERange; 16394 Expr *SimpleRefExpr = RefExpr; 16395 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16396 if (Res.second) { 16397 // It will be analyzed later. 16398 MVLI.ProcessedVarList.push_back(RefExpr); 16399 PrivateCopies.push_back(nullptr); 16400 Inits.push_back(nullptr); 16401 } 16402 ValueDecl *D = Res.first; 16403 if (!D) 16404 continue; 16405 16406 QualType Type = D->getType(); 16407 Type = Type.getNonReferenceType().getUnqualifiedType(); 16408 16409 auto *VD = dyn_cast<VarDecl>(D); 16410 16411 // Item should be a pointer or reference to pointer. 16412 if (!Type->isPointerType()) { 16413 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 16414 << 0 << RefExpr->getSourceRange(); 16415 continue; 16416 } 16417 16418 // Build the private variable and the expression that refers to it. 16419 auto VDPrivate = 16420 buildVarDecl(*this, ELoc, Type, D->getName(), 16421 D->hasAttrs() ? &D->getAttrs() : nullptr, 16422 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 16423 if (VDPrivate->isInvalidDecl()) 16424 continue; 16425 16426 CurContext->addDecl(VDPrivate); 16427 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 16428 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 16429 16430 // Add temporary variable to initialize the private copy of the pointer. 16431 VarDecl *VDInit = 16432 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 16433 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 16434 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 16435 AddInitializerToDecl(VDPrivate, 16436 DefaultLvalueConversion(VDInitRefExpr).get(), 16437 /*DirectInit=*/false); 16438 16439 // If required, build a capture to implement the privatization initialized 16440 // with the current list item value. 16441 DeclRefExpr *Ref = nullptr; 16442 if (!VD) 16443 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 16444 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 16445 PrivateCopies.push_back(VDPrivateRefExpr); 16446 Inits.push_back(VDInitRefExpr); 16447 16448 // We need to add a data sharing attribute for this variable to make sure it 16449 // is correctly captured. A variable that shows up in a use_device_ptr has 16450 // similar properties of a first private variable. 16451 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 16452 16453 // Create a mappable component for the list item. List items in this clause 16454 // only need a component. 16455 MVLI.VarBaseDeclarations.push_back(D); 16456 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16457 MVLI.VarComponents.back().push_back( 16458 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 16459 } 16460 16461 if (MVLI.ProcessedVarList.empty()) 16462 return nullptr; 16463 16464 return OMPUseDevicePtrClause::Create( 16465 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 16466 MVLI.VarBaseDeclarations, MVLI.VarComponents); 16467} 16468 16469OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 16470 const OMPVarListLocTy &Locs) { 16471 MappableVarListInfo MVLI(VarList); 16472 for (Expr *RefExpr : VarList) { 16473 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 16474 SourceLocation ELoc; 16475 SourceRange ERange; 16476 Expr *SimpleRefExpr = RefExpr; 16477 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16478 if (Res.second) { 16479 // It will be analyzed later. 16480 MVLI.ProcessedVarList.push_back(RefExpr); 16481 } 16482 ValueDecl *D = Res.first; 16483 if (!D) 16484 continue; 16485 16486 QualType Type = D->getType(); 16487 // item should be a pointer or array or reference to pointer or array 16488 if (!Type.getNonReferenceType()->isPointerType() && 16489 !Type.getNonReferenceType()->isArrayType()) { 16490 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 16491 << 0 << RefExpr->getSourceRange(); 16492 continue; 16493 } 16494 16495 // Check if the declaration in the clause does not show up in any data 16496 // sharing attribute. 16497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 16498 if (isOpenMPPrivate(DVar.CKind)) { 16499 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 16500 << getOpenMPClauseName(DVar.CKind) 16501 << getOpenMPClauseName(OMPC_is_device_ptr) 16502 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 16503 reportOriginalDsa(*this, DSAStack, D, DVar); 16504 continue; 16505 } 16506 16507 const Expr *ConflictExpr; 16508 if (DSAStack->checkMappableExprComponentListsForDecl( 16509 D, /*CurrentRegionOnly=*/true, 16510 [&ConflictExpr]( 16511 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 16512 OpenMPClauseKind) -> bool { 16513 ConflictExpr = R.front().getAssociatedExpression(); 16514 return true; 16515 })) { 16516 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 16517 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 16518 << ConflictExpr->getSourceRange(); 16519 continue; 16520 } 16521 16522 // Store the components in the stack so that they can be used to check 16523 // against other clauses later on. 16524 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 16525 DSAStack->addMappableExpressionComponents( 16526 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 16527 16528 // Record the expression we've just processed. 16529 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 16530 16531 // Create a mappable component for the list item. List items in this clause 16532 // only need a component. We use a null declaration to signal fields in 16533 // 'this'. 16534 assert((isa<DeclRefExpr>(SimpleRefExpr) || 16535 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 16536 "Unexpected device pointer expression!"); 16537 MVLI.VarBaseDeclarations.push_back( 16538 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 16539 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 16540 MVLI.VarComponents.back().push_back(MC); 16541 } 16542 16543 if (MVLI.ProcessedVarList.empty()) 16544 return nullptr; 16545 16546 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 16547 MVLI.VarBaseDeclarations, 16548 MVLI.VarComponents); 16549} 16550 16551OMPClause *Sema::ActOnOpenMPAllocateClause( 16552 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16553 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16554 if (Allocator) { 16555 // OpenMP [2.11.4 allocate Clause, Description] 16556 // allocator is an expression of omp_allocator_handle_t type. 16557 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 16558 return nullptr; 16559 16560 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 16561 if (AllocatorRes.isInvalid()) 16562 return nullptr; 16563 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 16564 DSAStack->getOMPAllocatorHandleT(), 16565 Sema::AA_Initializing, 16566 /*AllowExplicit=*/true); 16567 if (AllocatorRes.isInvalid()) 16568 return nullptr; 16569 Allocator = AllocatorRes.get(); 16570 } else { 16571 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 16572 // allocate clauses that appear on a target construct or on constructs in a 16573 // target region must specify an allocator expression unless a requires 16574 // directive with the dynamic_allocators clause is present in the same 16575 // compilation unit. 16576 if (LangOpts.OpenMPIsDevice && 16577 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 16578 targetDiag(StartLoc, diag::err_expected_allocator_expression); 16579 } 16580 // Analyze and build list of variables. 16581 SmallVector<Expr *, 8> Vars; 16582 for (Expr *RefExpr : VarList) { 16583 assert(RefExpr && "NULL expr in OpenMP private clause."); 16584 SourceLocation ELoc; 16585 SourceRange ERange; 16586 Expr *SimpleRefExpr = RefExpr; 16587 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 16588 if (Res.second) { 16589 // It will be analyzed later. 16590 Vars.push_back(RefExpr); 16591 } 16592 ValueDecl *D = Res.first; 16593 if (!D) 16594 continue; 16595 16596 auto *VD = dyn_cast<VarDecl>(D); 16597 DeclRefExpr *Ref = nullptr; 16598 if (!VD && !CurContext->isDependentContext()) 16599 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 16600 Vars.push_back((VD || CurContext->isDependentContext()) 16601 ? RefExpr->IgnoreParens() 16602 : Ref); 16603 } 16604 16605 if (Vars.empty()) 16606 return nullptr; 16607 16608 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 16609 ColonLoc, EndLoc, Vars); 16610} 16611