1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
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
7 //===----------------------------------------------------------------------===//
9 /// This file implements semantic analysis for OpenMP directives and
12 //===----------------------------------------------------------------------===//
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/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/Frontend/OpenMP/OMPConstants.h"
41 using namespace clang;
42 using namespace llvm::omp;
44 //===----------------------------------------------------------------------===//
45 // Stack of data-sharing attributes for variables
46 //===----------------------------------------------------------------------===//
48 static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, bool NoDiagnose);
54 /// Default data sharing attributes, which can be applied to directive.
55 enum DefaultDataSharingAttributes {
56 DSA_unspecified = 0, /// Data sharing attribute not specified.
57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
62 /// Stack for tracking declarations used in OpenMP directives and
63 /// clauses and their data-sharing attributes.
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 DSAVarData() = default;
74 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
75 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
76 SourceLocation ImplicitDSALoc, unsigned Modifier)
77 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
78 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
80 using OperatorOffsetTy =
81 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
82 using DoacrossDependMapTy =
83 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
84 /// Kind of the declaration used in the uses_allocators clauses.
85 enum class UsesAllocatorsDeclKind {
86 /// Predefined allocator
88 /// User-defined allocator
90 /// The declaration that represent allocator trait
96 OpenMPClauseKind Attributes = OMPC_unknown;
97 unsigned Modifier = 0;
98 /// Pointer to a reference expression and a flag which shows that the
99 /// variable is marked as lastprivate(true) or not (false).
100 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
101 DeclRefExpr *PrivateCopy = nullptr;
103 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
104 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
105 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
106 using LoopControlVariablesMapTy =
107 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
108 /// Struct that associates a component with the clause kind where they are
110 struct MappedExprComponentTy {
111 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
112 OpenMPClauseKind Kind = OMPC_unknown;
114 using MappedExprComponentsTy =
115 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
116 using CriticalsWithHintsTy =
117 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
118 struct ReductionData {
119 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
120 SourceRange ReductionRange;
121 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
122 ReductionData() = default;
123 void set(BinaryOperatorKind BO, SourceRange RR) {
127 void set(const Expr *RefExpr, SourceRange RR) {
129 ReductionOp = RefExpr;
132 using DeclReductionMapTy =
133 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
134 struct DefaultmapInfo {
135 OpenMPDefaultmapClauseModifier ImplicitBehavior =
136 OMPC_DEFAULTMAP_MODIFIER_unknown;
138 DefaultmapInfo() = default;
139 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
140 : ImplicitBehavior(M), SLoc(Loc) {}
143 struct SharingMapTy {
144 DeclSAMapTy SharingMap;
145 DeclReductionMapTy ReductionMap;
146 UsedRefMapTy AlignedMap;
147 UsedRefMapTy NontemporalMap;
148 MappedExprComponentsTy MappedExprComponents;
149 LoopControlVariablesMapTy LCVMap;
150 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
151 SourceLocation DefaultAttrLoc;
152 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
153 OpenMPDirectiveKind Directive = OMPD_unknown;
154 DeclarationNameInfo DirectiveName;
155 Scope *CurScope = nullptr;
156 SourceLocation ConstructLoc;
157 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
158 /// get the data (loop counters etc.) about enclosing loop-based construct.
159 /// This data is required during codegen.
160 DoacrossDependMapTy DoacrossDepends;
161 /// First argument (Expr *) contains optional argument of the
162 /// 'ordered' clause, the second one is true if the regions has 'ordered'
163 /// clause, false otherwise.
164 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
165 unsigned AssociatedLoops = 1;
166 bool HasMutipleLoops = false;
167 const Decl *PossiblyLoopCounter = nullptr;
168 bool NowaitRegion = false;
169 bool CancelRegion = false;
170 bool LoopStart = false;
171 bool BodyComplete = false;
172 SourceLocation PrevScanLocation;
173 SourceLocation PrevOrderedLocation;
174 SourceLocation InnerTeamsRegionLoc;
175 /// Reference to the taskgroup task_reduction reference expression.
176 Expr *TaskgroupReductionRef = nullptr;
177 llvm::DenseSet<QualType> MappedClassesQualTypes;
178 SmallVector<Expr *, 4> InnerUsedAllocators;
179 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
180 /// List of globals marked as declare target link in this target region
181 /// (isOpenMPTargetExecutionDirective(Directive) == true).
182 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
183 /// List of decls used in inclusive/exclusive clauses of the scan directive.
184 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
185 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
187 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
188 Scope *CurScope, SourceLocation Loc)
189 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
191 SharingMapTy() = default;
194 using StackTy = SmallVector<SharingMapTy, 4>;
196 /// Stack of used declaration and their data-sharing attributes.
197 DeclSAMapTy Threadprivates;
198 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
199 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
200 /// true, if check for DSA must be from parent directive, false, if
201 /// from current directive.
202 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
204 bool ForceCapturing = false;
205 /// true if all the variables in the target executable directives must be
206 /// captured by reference.
207 bool ForceCaptureByReferenceInTargetExecutable = false;
208 CriticalsWithHintsTy Criticals;
209 unsigned IgnoredStackElements = 0;
211 /// Iterators over the stack iterate in order from innermost to outermost
213 using const_iterator = StackTy::const_reverse_iterator;
214 const_iterator begin() const {
215 return Stack.empty() ? const_iterator()
216 : Stack.back().first.rbegin() + IgnoredStackElements;
218 const_iterator end() const {
219 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
221 using iterator = StackTy::reverse_iterator;
223 return Stack.empty() ? iterator()
224 : Stack.back().first.rbegin() + IgnoredStackElements;
227 return Stack.empty() ? iterator() : Stack.back().first.rend();
230 // Convenience operations to get at the elements of the stack.
232 bool isStackEmpty() const {
233 return Stack.empty() ||
234 Stack.back().second != CurrentNonCapturingFunctionScope ||
235 Stack.back().first.size() <= IgnoredStackElements;
237 size_t getStackSize() const {
238 return isStackEmpty() ? 0
239 : Stack.back().first.size() - IgnoredStackElements;
242 SharingMapTy *getTopOfStackOrNull() {
243 size_t Size = getStackSize();
246 return &Stack.back().first[Size - 1];
248 const SharingMapTy *getTopOfStackOrNull() const {
249 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
251 SharingMapTy &getTopOfStack() {
252 assert(!isStackEmpty() && "no current directive");
253 return *getTopOfStackOrNull();
255 const SharingMapTy &getTopOfStack() const {
256 return const_cast<DSAStackTy&>(*this).getTopOfStack();
259 SharingMapTy *getSecondOnStackOrNull() {
260 size_t Size = getStackSize();
263 return &Stack.back().first[Size - 2];
265 const SharingMapTy *getSecondOnStackOrNull() const {
266 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
269 /// Get the stack element at a certain level (previously returned by
270 /// \c getNestingLevel).
272 /// Note that nesting levels count from outermost to innermost, and this is
273 /// the reverse of our iteration order where new inner levels are pushed at
274 /// the front of the stack.
275 SharingMapTy &getStackElemAtLevel(unsigned Level) {
276 assert(Level < getStackSize() && "no such stack element");
277 return Stack.back().first[Level];
279 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
280 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
283 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
285 /// Checks if the variable is a local for OpenMP region.
286 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
288 /// Vector of previously declared requires directives
289 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
290 /// omp_allocator_handle_t type.
291 QualType OMPAllocatorHandleT;
292 /// omp_depend_t type.
294 /// omp_event_handle_t type.
295 QualType OMPEventHandleT;
296 /// omp_alloctrait_t type.
297 QualType OMPAlloctraitT;
298 /// Expression for the predefined allocators.
299 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
301 /// Vector of previously encountered target directives
302 SmallVector<SourceLocation, 2> TargetLocations;
303 SourceLocation AtomicLocation;
306 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
308 /// Sets omp_allocator_handle_t type.
309 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
310 /// Gets omp_allocator_handle_t type.
311 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
312 /// Sets omp_alloctrait_t type.
313 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
314 /// Gets omp_alloctrait_t type.
315 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
316 /// Sets the given default allocator.
317 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
319 OMPPredefinedAllocators[AllocatorKind] = Allocator;
321 /// Returns the specified default allocator.
322 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
323 return OMPPredefinedAllocators[AllocatorKind];
325 /// Sets omp_depend_t type.
326 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
327 /// Gets omp_depend_t type.
328 QualType getOMPDependT() const { return OMPDependT; }
330 /// Sets omp_event_handle_t type.
331 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
332 /// Gets omp_event_handle_t type.
333 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
335 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
336 OpenMPClauseKind getClauseParsingMode() const {
337 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
338 return ClauseKindMode;
340 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
342 bool isBodyComplete() const {
343 const SharingMapTy *Top = getTopOfStackOrNull();
344 return Top && Top->BodyComplete;
346 void setBodyComplete() {
347 getTopOfStack().BodyComplete = true;
350 bool isForceVarCapturing() const { return ForceCapturing; }
351 void setForceVarCapturing(bool V) { ForceCapturing = V; }
353 void setForceCaptureByReferenceInTargetExecutable(bool V) {
354 ForceCaptureByReferenceInTargetExecutable = V;
356 bool isForceCaptureByReferenceInTargetExecutable() const {
357 return ForceCaptureByReferenceInTargetExecutable;
360 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
361 Scope *CurScope, SourceLocation Loc) {
362 assert(!IgnoredStackElements &&
363 "cannot change stack while ignoring elements");
365 Stack.back().second != CurrentNonCapturingFunctionScope)
366 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
367 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
368 Stack.back().first.back().DefaultAttrLoc = Loc;
372 assert(!IgnoredStackElements &&
373 "cannot change stack while ignoring elements");
374 assert(!Stack.back().first.empty() &&
375 "Data-sharing attributes stack is empty!");
376 Stack.back().first.pop_back();
379 /// RAII object to temporarily leave the scope of a directive when we want to
380 /// logically operate in its parent.
381 class ParentDirectiveScope {
385 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
386 : Self(Self), Active(false) {
390 ~ParentDirectiveScope() { disable(); }
393 --Self.IgnoredStackElements;
399 ++Self.IgnoredStackElements;
405 /// Marks that we're started loop parsing.
407 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
408 "Expected loop-based directive.");
409 getTopOfStack().LoopStart = true;
411 /// Start capturing of the variables in the loop context.
413 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
414 "Expected loop-based directive.");
415 getTopOfStack().LoopStart = false;
417 /// true, if variables are captured, false otherwise.
418 bool isLoopStarted() const {
419 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
420 "Expected loop-based directive.");
421 return !getTopOfStack().LoopStart;
423 /// Marks (or clears) declaration as possibly loop counter.
424 void resetPossibleLoopCounter(const Decl *D = nullptr) {
425 getTopOfStack().PossiblyLoopCounter =
426 D ? D->getCanonicalDecl() : D;
428 /// Gets the possible loop counter decl.
429 const Decl *getPossiblyLoopCunter() const {
430 return getTopOfStack().PossiblyLoopCounter;
432 /// Start new OpenMP region stack in new non-capturing function.
433 void pushFunction() {
434 assert(!IgnoredStackElements &&
435 "cannot change stack while ignoring elements");
436 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
437 assert(!isa<CapturingScopeInfo>(CurFnScope));
438 CurrentNonCapturingFunctionScope = CurFnScope;
440 /// Pop region stack for non-capturing function.
441 void popFunction(const FunctionScopeInfo *OldFSI) {
442 assert(!IgnoredStackElements &&
443 "cannot change stack while ignoring elements");
444 if (!Stack.empty() && Stack.back().second == OldFSI) {
445 assert(Stack.back().first.empty());
448 CurrentNonCapturingFunctionScope = nullptr;
449 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
450 if (!isa<CapturingScopeInfo>(FSI)) {
451 CurrentNonCapturingFunctionScope = FSI;
457 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
458 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
460 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
461 getCriticalWithHint(const DeclarationNameInfo &Name) const {
462 auto I = Criticals.find(Name.getAsString());
463 if (I != Criticals.end())
465 return std::make_pair(nullptr, llvm::APSInt());
467 /// If 'aligned' declaration for given variable \a D was not seen yet,
468 /// add it and return NULL; otherwise return previous occurrence's expression
470 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
471 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
472 /// add it and return NULL; otherwise return previous occurrence's expression
474 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
476 /// Register specified variable as loop control variable.
477 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
478 /// Check if the specified variable is a loop control variable for
480 /// \return The index of the loop control variable in the list of associated
481 /// for-loops (from outer to inner).
482 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
483 /// Check if the specified variable is a loop control variable for
485 /// \return The index of the loop control variable in the list of associated
486 /// for-loops (from outer to inner).
487 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
488 /// Check if the specified variable is a loop control variable for
490 /// \return The index of the loop control variable in the list of associated
491 /// for-loops (from outer to inner).
492 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
493 unsigned Level) const;
494 /// Get the loop control variable for the I-th loop (or nullptr) in
495 /// parent directive.
496 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
498 /// Marks the specified decl \p D as used in scan directive.
499 void markDeclAsUsedInScanDirective(ValueDecl *D) {
500 if (SharingMapTy *Stack = getSecondOnStackOrNull())
501 Stack->UsedInScanDirective.insert(D);
504 /// Checks if the specified declaration was used in the inner scan directive.
505 bool isUsedInScanDirective(ValueDecl *D) const {
506 if (const SharingMapTy *Stack = getTopOfStackOrNull())
507 return Stack->UsedInScanDirective.count(D) > 0;
511 /// Adds explicit data sharing attribute to the specified declaration.
512 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
513 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0);
515 /// Adds additional information for the reduction items with the reduction id
516 /// represented as an operator.
517 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
518 BinaryOperatorKind BOK);
519 /// Adds additional information for the reduction items with the reduction id
520 /// represented as reduction identifier.
521 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
522 const Expr *ReductionRef);
523 /// Returns the location and reduction operation from the innermost parent
524 /// region for the given \p D.
526 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
527 BinaryOperatorKind &BOK,
528 Expr *&TaskgroupDescriptor) const;
529 /// Returns the location and reduction operation from the innermost parent
530 /// region for the given \p D.
532 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
533 const Expr *&ReductionRef,
534 Expr *&TaskgroupDescriptor) const;
535 /// Return reduction reference expression for the current taskgroup or
536 /// parallel/worksharing directives with task reductions.
537 Expr *getTaskgroupReductionRef() const {
538 assert((getTopOfStack().Directive == OMPD_taskgroup ||
539 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
540 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
541 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
542 "taskgroup reference expression requested for non taskgroup or "
543 "parallel/worksharing directive.");
544 return getTopOfStack().TaskgroupReductionRef;
546 /// Checks if the given \p VD declaration is actually a taskgroup reduction
547 /// descriptor variable at the \p Level of OpenMP regions.
548 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
549 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
550 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
554 /// Returns data sharing attributes from top of the stack for the
555 /// specified declaration.
556 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
557 /// Returns data-sharing attributes for the specified declaration.
558 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
559 /// Returns data-sharing attributes for the specified declaration.
560 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
561 /// Checks if the specified variables has data-sharing attributes which
562 /// match specified \a CPred predicate in any directive which matches \a DPred
565 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
566 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
567 bool FromParent) const;
568 /// Checks if the specified variables has data-sharing attributes which
569 /// match specified \a CPred predicate in any innermost directive which
570 /// matches \a DPred predicate.
572 hasInnermostDSA(ValueDecl *D,
573 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
575 bool FromParent) const;
576 /// Checks if the specified variables has explicit data-sharing
577 /// attributes which match specified \a CPred predicate at the specified
579 bool hasExplicitDSA(const ValueDecl *D,
580 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
581 unsigned Level, bool NotLastprivate = false) const;
583 /// Returns true if the directive at level \Level matches in the
584 /// specified \a DPred predicate.
585 bool hasExplicitDirective(
586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
587 unsigned Level) const;
589 /// Finds a directive which matches specified \a DPred predicate.
591 const llvm::function_ref<bool(
592 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
594 bool FromParent) const;
596 /// Returns currently analyzed directive.
597 OpenMPDirectiveKind getCurrentDirective() const {
598 const SharingMapTy *Top = getTopOfStackOrNull();
599 return Top ? Top->Directive : OMPD_unknown;
601 /// Returns directive kind at specified level.
602 OpenMPDirectiveKind getDirective(unsigned Level) const {
603 assert(!isStackEmpty() && "No directive at specified level.");
604 return getStackElemAtLevel(Level).Directive;
606 /// Returns the capture region at the specified level.
607 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
608 unsigned OpenMPCaptureLevel) const {
609 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
610 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
611 return CaptureRegions[OpenMPCaptureLevel];
613 /// Returns parent directive.
614 OpenMPDirectiveKind getParentDirective() const {
615 const SharingMapTy *Parent = getSecondOnStackOrNull();
616 return Parent ? Parent->Directive : OMPD_unknown;
619 /// Add requires decl to internal vector
620 void addRequiresDecl(OMPRequiresDecl *RD) {
621 RequiresDecls.push_back(RD);
624 /// Checks if the defined 'requires' directive has specified type of clause.
625 template <typename ClauseType>
626 bool hasRequiresDeclWithClause() const {
627 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
628 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
629 return isa<ClauseType>(C);
634 /// Checks for a duplicate clause amongst previously declared requires
636 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
637 bool IsDuplicate = false;
638 for (OMPClause *CNew : ClauseList) {
639 for (const OMPRequiresDecl *D : RequiresDecls) {
640 for (const OMPClause *CPrev : D->clauselists()) {
641 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
642 SemaRef.Diag(CNew->getBeginLoc(),
643 diag::err_omp_requires_clause_redeclaration)
644 << getOpenMPClauseName(CNew->getClauseKind());
645 SemaRef.Diag(CPrev->getBeginLoc(),
646 diag::note_omp_requires_previous_clause)
647 << getOpenMPClauseName(CPrev->getClauseKind());
656 /// Add location of previously encountered target to internal vector
657 void addTargetDirLocation(SourceLocation LocStart) {
658 TargetLocations.push_back(LocStart);
661 /// Add location for the first encountered atomicc directive.
662 void addAtomicDirectiveLoc(SourceLocation Loc) {
663 if (AtomicLocation.isInvalid())
664 AtomicLocation = Loc;
667 /// Returns the location of the first encountered atomic directive in the
669 SourceLocation getAtomicDirectiveLoc() const {
670 return AtomicLocation;
673 // Return previously encountered target region locations.
674 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
675 return TargetLocations;
678 /// Set default data sharing attribute to none.
679 void setDefaultDSANone(SourceLocation Loc) {
680 getTopOfStack().DefaultAttr = DSA_none;
681 getTopOfStack().DefaultAttrLoc = Loc;
683 /// Set default data sharing attribute to shared.
684 void setDefaultDSAShared(SourceLocation Loc) {
685 getTopOfStack().DefaultAttr = DSA_shared;
686 getTopOfStack().DefaultAttrLoc = Loc;
688 /// Set default data sharing attribute to firstprivate.
689 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
690 getTopOfStack().DefaultAttr = DSA_firstprivate;
691 getTopOfStack().DefaultAttrLoc = Loc;
693 /// Set default data mapping attribute to Modifier:Kind
694 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
695 OpenMPDefaultmapClauseKind Kind,
696 SourceLocation Loc) {
697 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
698 DMI.ImplicitBehavior = M;
701 /// Check whether the implicit-behavior has been set in defaultmap
702 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
703 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
704 return getTopOfStack()
705 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
706 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
708 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
709 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
711 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
712 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
713 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
714 OMPC_DEFAULTMAP_MODIFIER_unknown;
717 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
718 return getStackSize() <= Level ? DSA_unspecified
719 : getStackElemAtLevel(Level).DefaultAttr;
721 DefaultDataSharingAttributes getDefaultDSA() const {
722 return isStackEmpty() ? DSA_unspecified
723 : getTopOfStack().DefaultAttr;
725 SourceLocation getDefaultDSALocation() const {
726 return isStackEmpty() ? SourceLocation()
727 : getTopOfStack().DefaultAttrLoc;
729 OpenMPDefaultmapClauseModifier
730 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
731 return isStackEmpty()
732 ? OMPC_DEFAULTMAP_MODIFIER_unknown
733 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
735 OpenMPDefaultmapClauseModifier
736 getDefaultmapModifierAtLevel(unsigned Level,
737 OpenMPDefaultmapClauseKind Kind) const {
738 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
740 bool isDefaultmapCapturedByRef(unsigned Level,
741 OpenMPDefaultmapClauseKind Kind) const {
742 OpenMPDefaultmapClauseModifier M =
743 getDefaultmapModifierAtLevel(Level, Kind);
744 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
745 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
746 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
747 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
748 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
752 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
753 OpenMPDefaultmapClauseKind Kind) {
755 case OMPC_DEFAULTMAP_scalar:
756 case OMPC_DEFAULTMAP_pointer:
757 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_default);
760 case OMPC_DEFAULTMAP_aggregate:
761 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
765 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
767 bool mustBeFirstprivateAtLevel(unsigned Level,
768 OpenMPDefaultmapClauseKind Kind) const {
769 OpenMPDefaultmapClauseModifier M =
770 getDefaultmapModifierAtLevel(Level, Kind);
771 return mustBeFirstprivateBase(M, Kind);
773 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
774 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
775 return mustBeFirstprivateBase(M, Kind);
778 /// Checks if the specified variable is a threadprivate.
779 bool isThreadPrivate(VarDecl *D) {
780 const DSAVarData DVar = getTopDSA(D, false);
781 return isOpenMPThreadPrivate(DVar.CKind);
784 /// Marks current region as ordered (it has an 'ordered' clause).
785 void setOrderedRegion(bool IsOrdered, const Expr *Param,
786 OMPOrderedClause *Clause) {
788 getTopOfStack().OrderedRegion.emplace(Param, Clause);
790 getTopOfStack().OrderedRegion.reset();
792 /// Returns true, if region is ordered (has associated 'ordered' clause),
793 /// false - otherwise.
794 bool isOrderedRegion() const {
795 if (const SharingMapTy *Top = getTopOfStackOrNull())
796 return Top->OrderedRegion.hasValue();
799 /// Returns optional parameter for the ordered region.
800 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
801 if (const SharingMapTy *Top = getTopOfStackOrNull())
802 if (Top->OrderedRegion.hasValue())
803 return Top->OrderedRegion.getValue();
804 return std::make_pair(nullptr, nullptr);
806 /// Returns true, if parent region is ordered (has associated
807 /// 'ordered' clause), false - otherwise.
808 bool isParentOrderedRegion() const {
809 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
810 return Parent->OrderedRegion.hasValue();
813 /// Returns optional parameter for the ordered region.
814 std::pair<const Expr *, OMPOrderedClause *>
815 getParentOrderedRegionParam() const {
816 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
817 if (Parent->OrderedRegion.hasValue())
818 return Parent->OrderedRegion.getValue();
819 return std::make_pair(nullptr, nullptr);
821 /// Marks current region as nowait (it has a 'nowait' clause).
822 void setNowaitRegion(bool IsNowait = true) {
823 getTopOfStack().NowaitRegion = IsNowait;
825 /// Returns true, if parent region is nowait (has associated
826 /// 'nowait' clause), false - otherwise.
827 bool isParentNowaitRegion() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 return Parent->NowaitRegion;
832 /// Marks parent region as cancel region.
833 void setParentCancelRegion(bool Cancel = true) {
834 if (SharingMapTy *Parent = getSecondOnStackOrNull())
835 Parent->CancelRegion |= Cancel;
837 /// Return true if current region has inner cancel construct.
838 bool isCancelRegion() const {
839 const SharingMapTy *Top = getTopOfStackOrNull();
840 return Top ? Top->CancelRegion : false;
843 /// Mark that parent region already has scan directive.
844 void setParentHasScanDirective(SourceLocation Loc) {
845 if (SharingMapTy *Parent = getSecondOnStackOrNull())
846 Parent->PrevScanLocation = Loc;
848 /// Return true if current region has inner cancel construct.
849 bool doesParentHasScanDirective() const {
850 const SharingMapTy *Top = getSecondOnStackOrNull();
851 return Top ? Top->PrevScanLocation.isValid() : false;
853 /// Return true if current region has inner cancel construct.
854 SourceLocation getParentScanDirectiveLoc() const {
855 const SharingMapTy *Top = getSecondOnStackOrNull();
856 return Top ? Top->PrevScanLocation : SourceLocation();
858 /// Mark that parent region already has ordered directive.
859 void setParentHasOrderedDirective(SourceLocation Loc) {
860 if (SharingMapTy *Parent = getSecondOnStackOrNull())
861 Parent->PrevOrderedLocation = Loc;
863 /// Return true if current region has inner ordered construct.
864 bool doesParentHasOrderedDirective() const {
865 const SharingMapTy *Top = getSecondOnStackOrNull();
866 return Top ? Top->PrevOrderedLocation.isValid() : false;
868 /// Returns the location of the previously specified ordered directive.
869 SourceLocation getParentOrderedDirectiveLoc() const {
870 const SharingMapTy *Top = getSecondOnStackOrNull();
871 return Top ? Top->PrevOrderedLocation : SourceLocation();
874 /// Set collapse value for the region.
875 void setAssociatedLoops(unsigned Val) {
876 getTopOfStack().AssociatedLoops = Val;
878 getTopOfStack().HasMutipleLoops = true;
880 /// Return collapse value for region.
881 unsigned getAssociatedLoops() const {
882 const SharingMapTy *Top = getTopOfStackOrNull();
883 return Top ? Top->AssociatedLoops : 0;
885 /// Returns true if the construct is associated with multiple loops.
886 bool hasMutipleLoops() const {
887 const SharingMapTy *Top = getTopOfStackOrNull();
888 return Top ? Top->HasMutipleLoops : false;
891 /// Marks current target region as one with closely nested teams
893 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
894 if (SharingMapTy *Parent = getSecondOnStackOrNull())
895 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
897 /// Returns true, if current region has closely nested teams region.
898 bool hasInnerTeamsRegion() const {
899 return getInnerTeamsRegionLoc().isValid();
901 /// Returns location of the nested teams region (if any).
902 SourceLocation getInnerTeamsRegionLoc() const {
903 const SharingMapTy *Top = getTopOfStackOrNull();
904 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
907 Scope *getCurScope() const {
908 const SharingMapTy *Top = getTopOfStackOrNull();
909 return Top ? Top->CurScope : nullptr;
911 SourceLocation getConstructLoc() const {
912 const SharingMapTy *Top = getTopOfStackOrNull();
913 return Top ? Top->ConstructLoc : SourceLocation();
916 /// Do the check specified in \a Check to all component lists and return true
917 /// if any issue is found.
918 bool checkMappableExprComponentListsForDecl(
919 const ValueDecl *VD, bool CurrentRegionOnly,
920 const llvm::function_ref<
921 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
932 if (CurrentRegionOnly)
937 for (; SI != SE; ++SI) {
938 auto MI = SI->MappedExprComponents.find(VD);
939 if (MI != SI->MappedExprComponents.end())
940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
941 MI->second.Components)
942 if (Check(L, MI->second.Kind))
948 /// Do the check specified in \a Check to all component lists at a given level
949 /// and return true if any issue is found.
950 bool checkMappableExprComponentListsForDeclAtLevel(
951 const ValueDecl *VD, unsigned Level,
952 const llvm::function_ref<
953 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
956 if (getStackSize() <= Level)
959 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
960 auto MI = StackElem.MappedExprComponents.find(VD);
961 if (MI != StackElem.MappedExprComponents.end())
962 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
963 MI->second.Components)
964 if (Check(L, MI->second.Kind))
969 /// Create a new mappable expression component list associated with a given
970 /// declaration and initialize it with the provided list of components.
971 void addMappableExpressionComponents(
973 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
974 OpenMPClauseKind WhereFoundClauseKind) {
975 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
976 // Create new entry and append the new components there.
977 MEC.Components.resize(MEC.Components.size() + 1);
978 MEC.Components.back().append(Components.begin(), Components.end());
979 MEC.Kind = WhereFoundClauseKind;
982 unsigned getNestingLevel() const {
983 assert(!isStackEmpty());
984 return getStackSize() - 1;
986 void addDoacrossDependClause(OMPDependClause *C,
987 const OperatorOffsetTy &OpsOffs) {
988 SharingMapTy *Parent = getSecondOnStackOrNull();
989 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
990 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
992 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
993 getDoacrossDependClauses() const {
994 const SharingMapTy &StackElem = getTopOfStack();
995 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
996 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
997 return llvm::make_range(Ref.begin(), Ref.end());
999 return llvm::make_range(StackElem.DoacrossDepends.end(),
1000 StackElem.DoacrossDepends.end());
1003 // Store types of classes which have been explicitly mapped
1004 void addMappedClassesQualTypes(QualType QT) {
1005 SharingMapTy &StackElem = getTopOfStack();
1006 StackElem.MappedClassesQualTypes.insert(QT);
1009 // Return set of mapped classes types
1010 bool isClassPreviouslyMapped(QualType QT) const {
1011 const SharingMapTy &StackElem = getTopOfStack();
1012 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1015 /// Adds global declare target to the parent target region.
1016 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1017 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1018 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1019 "Expected declare target link global.");
1020 for (auto &Elem : *this) {
1021 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1022 Elem.DeclareTargetLinkVarDecls.push_back(E);
1028 /// Returns the list of globals with declare target link if current directive
1030 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1031 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1032 "Expected target executable directive.");
1033 return getTopOfStack().DeclareTargetLinkVarDecls;
1036 /// Adds list of allocators expressions.
1037 void addInnerAllocatorExpr(Expr *E) {
1038 getTopOfStack().InnerUsedAllocators.push_back(E);
1040 /// Return list of used allocators.
1041 ArrayRef<Expr *> getInnerAllocators() const {
1042 return getTopOfStack().InnerUsedAllocators;
1044 /// Marks the declaration as implicitly firstprivate nin the task-based
1046 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1047 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1049 /// Checks if the decl is implicitly firstprivate in the task-based region.
1050 bool isImplicitTaskFirstprivate(Decl *D) const {
1051 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1054 /// Marks decl as used in uses_allocators clause as the allocator.
1055 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1056 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1058 /// Checks if specified decl is used in uses allocator clause as the
1060 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1061 const Decl *D) const {
1062 const SharingMapTy &StackElem = getTopOfStack();
1063 auto I = StackElem.UsesAllocatorsDecls.find(D);
1064 if (I == StackElem.UsesAllocatorsDecls.end())
1066 return I->getSecond();
1068 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1069 const SharingMapTy &StackElem = getTopOfStack();
1070 auto I = StackElem.UsesAllocatorsDecls.find(D);
1071 if (I == StackElem.UsesAllocatorsDecls.end())
1073 return I->getSecond();
1077 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1078 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1081 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1082 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1083 DKind == OMPD_unknown;
1088 static const Expr *getExprAsWritten(const Expr *E) {
1089 if (const auto *FE = dyn_cast<FullExpr>(E))
1090 E = FE->getSubExpr();
1092 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1093 E = MTE->getSubExpr();
1095 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1096 E = Binder->getSubExpr();
1098 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1099 E = ICE->getSubExprAsWritten();
1100 return E->IgnoreParens();
1103 static Expr *getExprAsWritten(Expr *E) {
1104 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1107 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1108 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1109 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1110 D = ME->getMemberDecl();
1111 const auto *VD = dyn_cast<VarDecl>(D);
1112 const auto *FD = dyn_cast<FieldDecl>(D);
1113 if (VD != nullptr) {
1114 VD = VD->getCanonicalDecl();
1118 FD = FD->getCanonicalDecl();
1124 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1125 return const_cast<ValueDecl *>(
1126 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1129 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1130 ValueDecl *D) const {
1131 D = getCanonicalDecl(D);
1132 auto *VD = dyn_cast<VarDecl>(D);
1133 const auto *FD = dyn_cast<FieldDecl>(D);
1135 if (Iter == end()) {
1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1137 // in a region but not in construct]
1138 // File-scope or namespace-scope variables referenced in called routines
1139 // in the region are shared unless they appear in a threadprivate
1141 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1142 DVar.CKind = OMPC_shared;
1144 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1145 // in a region but not in construct]
1146 // Variables with static storage duration that are declared in called
1147 // routines in the region are shared.
1148 if (VD && VD->hasGlobalStorage())
1149 DVar.CKind = OMPC_shared;
1151 // Non-static data members are shared by default.
1153 DVar.CKind = OMPC_shared;
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a Construct, C/C++, predetermined, p.1]
1160 // Variables with automatic storage duration that are declared in a scope
1161 // inside the construct are private.
1162 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1163 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1164 DVar.CKind = OMPC_private;
1168 DVar.DKind = Iter->Directive;
1169 // Explicitly specified attributes and local variables with predetermined
1171 if (Iter->SharingMap.count(D)) {
1172 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1173 DVar.RefExpr = Data.RefExpr.getPointer();
1174 DVar.PrivateCopy = Data.PrivateCopy;
1175 DVar.CKind = Data.Attributes;
1176 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1177 DVar.Modifier = Data.Modifier;
1181 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1182 // in a Construct, C/C++, implicitly determined, p.1]
1183 // In a parallel or task construct, the data-sharing attributes of these
1184 // variables are determined by the default clause, if present.
1185 switch (Iter->DefaultAttr) {
1187 DVar.CKind = OMPC_shared;
1188 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1192 case DSA_firstprivate:
1193 if (VD->getStorageDuration() == SD_Static &&
1194 VD->getDeclContext()->isFileContext()) {
1195 DVar.CKind = OMPC_unknown;
1197 DVar.CKind = OMPC_firstprivate;
1199 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1201 case DSA_unspecified:
1202 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1203 // in a Construct, implicitly determined, p.2]
1204 // In a parallel construct, if no default clause is present, these
1205 // variables are shared.
1206 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1207 if ((isOpenMPParallelDirective(DVar.DKind) &&
1208 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1209 isOpenMPTeamsDirective(DVar.DKind)) {
1210 DVar.CKind = OMPC_shared;
1214 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1215 // in a Construct, implicitly determined, p.4]
1216 // In a task construct, if no default clause is present, a variable that in
1217 // the enclosing context is determined to be shared by all implicit tasks
1218 // bound to the current team is shared.
1219 if (isOpenMPTaskingDirective(DVar.DKind)) {
1220 DSAVarData DVarTemp;
1221 const_iterator I = Iter, E = end();
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1225 // Referenced in a Construct, implicitly determined, p.6]
1226 // In a task construct, if no default clause is present, a variable
1227 // whose data-sharing attribute is not determined by the rules above is
1229 DVarTemp = getDSA(I, D);
1230 if (DVarTemp.CKind != OMPC_shared) {
1231 DVar.RefExpr = nullptr;
1232 DVar.CKind = OMPC_firstprivate;
1235 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1237 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1241 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1242 // in a Construct, implicitly determined, p.3]
1243 // For constructs other than task, if no default clause is present, these
1244 // variables inherit their data-sharing attributes from the enclosing
1246 return getDSA(++Iter, D);
1249 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1250 const Expr *NewDE) {
1251 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1252 D = getCanonicalDecl(D);
1253 SharingMapTy &StackElem = getTopOfStack();
1254 auto It = StackElem.AlignedMap.find(D);
1255 if (It == StackElem.AlignedMap.end()) {
1256 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1257 StackElem.AlignedMap[D] = NewDE;
1260 assert(It->second && "Unexpected nullptr expr in the aligned map");
1264 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1265 const Expr *NewDE) {
1266 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1267 D = getCanonicalDecl(D);
1268 SharingMapTy &StackElem = getTopOfStack();
1269 auto It = StackElem.NontemporalMap.find(D);
1270 if (It == StackElem.NontemporalMap.end()) {
1271 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1272 StackElem.NontemporalMap[D] = NewDE;
1275 assert(It->second && "Unexpected nullptr expr in the aligned map");
1279 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1280 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1281 D = getCanonicalDecl(D);
1282 SharingMapTy &StackElem = getTopOfStack();
1283 StackElem.LCVMap.try_emplace(
1284 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1287 const DSAStackTy::LCDeclInfo
1288 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1289 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1290 D = getCanonicalDecl(D);
1291 const SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.LCVMap.find(D);
1293 if (It != StackElem.LCVMap.end())
1295 return {0, nullptr};
1298 const DSAStackTy::LCDeclInfo
1299 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1300 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1301 D = getCanonicalDecl(D);
1302 for (unsigned I = Level + 1; I > 0; --I) {
1303 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1304 auto It = StackElem.LCVMap.find(D);
1305 if (It != StackElem.LCVMap.end())
1308 return {0, nullptr};
1311 const DSAStackTy::LCDeclInfo
1312 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1313 const SharingMapTy *Parent = getSecondOnStackOrNull();
1314 assert(Parent && "Data-sharing attributes stack is empty");
1315 D = getCanonicalDecl(D);
1316 auto It = Parent->LCVMap.find(D);
1317 if (It != Parent->LCVMap.end())
1319 return {0, nullptr};
1322 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1323 const SharingMapTy *Parent = getSecondOnStackOrNull();
1324 assert(Parent && "Data-sharing attributes stack is empty");
1325 if (Parent->LCVMap.size() < I)
1327 for (const auto &Pair : Parent->LCVMap)
1328 if (Pair.second.first == I)
1333 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1334 DeclRefExpr *PrivateCopy, unsigned Modifier) {
1335 D = getCanonicalDecl(D);
1336 if (A == OMPC_threadprivate) {
1337 DSAInfo &Data = Threadprivates[D];
1338 Data.Attributes = A;
1339 Data.RefExpr.setPointer(E);
1340 Data.PrivateCopy = nullptr;
1341 Data.Modifier = Modifier;
1343 DSAInfo &Data = getTopOfStack().SharingMap[D];
1344 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1345 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1346 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1347 (isLoopControlVariable(D).first && A == OMPC_private));
1348 Data.Modifier = Modifier;
1349 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1350 Data.RefExpr.setInt(/*IntVal=*/true);
1353 const bool IsLastprivate =
1354 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1355 Data.Attributes = A;
1356 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1357 Data.PrivateCopy = PrivateCopy;
1359 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1360 Data.Modifier = Modifier;
1361 Data.Attributes = A;
1362 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1363 Data.PrivateCopy = nullptr;
1368 /// Build a variable declaration for OpenMP loop iteration variable.
1369 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1370 StringRef Name, const AttrVec *Attrs = nullptr,
1371 DeclRefExpr *OrigRef = nullptr) {
1372 DeclContext *DC = SemaRef.CurContext;
1373 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1374 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1376 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1378 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1382 Decl->setImplicit();
1385 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1390 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1392 bool RefersToCapture = false) {
1394 D->markUsed(S.Context);
1395 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1396 SourceLocation(), D, RefersToCapture, Loc, Ty,
1400 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1401 BinaryOperatorKind BOK) {
1402 D = getCanonicalDecl(D);
1403 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1405 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1406 "Additional reduction info may be specified only for reduction items.");
1407 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1408 assert(ReductionData.ReductionRange.isInvalid() &&
1409 (getTopOfStack().Directive == OMPD_taskgroup ||
1410 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1411 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1412 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1413 "Additional reduction info may be specified only once for reduction "
1415 ReductionData.set(BOK, SR);
1416 Expr *&TaskgroupReductionRef =
1417 getTopOfStack().TaskgroupReductionRef;
1418 if (!TaskgroupReductionRef) {
1419 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1420 SemaRef.Context.VoidPtrTy, ".task_red.");
1421 TaskgroupReductionRef =
1422 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 const Expr *ReductionRef) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1432 "Additional reduction info may be specified only for reduction items.");
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&
1435 (getTopOfStack().Directive == OMPD_taskgroup ||
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1439 "Additional reduction info may be specified only once for reduction "
1441 ReductionData.set(ReductionRef, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1452 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1453 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1454 Expr *&TaskgroupDescriptor) const {
1455 D = getCanonicalDecl(D);
1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1457 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1458 const DSAInfo &Data = I->SharingMap.lookup(D);
1459 if (Data.Attributes != OMPC_reduction ||
1460 Data.Modifier != OMPC_REDUCTION_task)
1462 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1463 if (!ReductionData.ReductionOp ||
1464 ReductionData.ReductionOp.is<const Expr *>())
1465 return DSAVarData();
1466 SR = ReductionData.ReductionRange;
1467 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1468 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1469 "expression for the descriptor is not "
1471 TaskgroupDescriptor = I->TaskgroupReductionRef;
1472 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1473 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1475 return DSAVarData();
1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 !ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1495 "expression for the descriptor is not "
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1501 return DSAVarData();
1504 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1505 D = D->getCanonicalDecl();
1506 for (const_iterator E = end(); I != E; ++I) {
1507 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1508 isOpenMPTargetExecutionDirective(I->Directive)) {
1509 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1510 Scope *CurScope = getCurScope();
1511 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1512 CurScope = CurScope->getParent();
1513 return CurScope != TopScope;
1519 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1520 bool AcceptIfMutable = true,
1521 bool *IsClassType = nullptr) {
1522 ASTContext &Context = SemaRef.getASTContext();
1523 Type = Type.getNonReferenceType().getCanonicalType();
1524 bool IsConstant = Type.isConstant(Context);
1525 Type = Context.getBaseElementType(Type);
1526 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1527 ? Type->getAsCXXRecordDecl()
1529 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1530 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1531 RD = CTD->getTemplatedDecl();
1534 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1535 RD->hasDefinition() && RD->hasMutableFields());
1538 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1539 QualType Type, OpenMPClauseKind CKind,
1540 SourceLocation ELoc,
1541 bool AcceptIfMutable = true,
1542 bool ListItemNotVar = false) {
1543 ASTContext &Context = SemaRef.getASTContext();
1545 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1546 unsigned Diag = ListItemNotVar
1547 ? diag::err_omp_const_list_item
1548 : IsClassType ? diag::err_omp_const_not_mutable_variable
1549 : diag::err_omp_const_variable;
1550 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1551 if (!ListItemNotVar && D) {
1552 const VarDecl *VD = dyn_cast<VarDecl>(D);
1553 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1554 VarDecl::DeclarationOnly;
1555 SemaRef.Diag(D->getLocation(),
1556 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1564 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1566 D = getCanonicalDecl(D);
1569 auto *VD = dyn_cast<VarDecl>(D);
1570 auto TI = Threadprivates.find(D);
1571 if (TI != Threadprivates.end()) {
1572 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1573 DVar.CKind = OMPC_threadprivate;
1574 DVar.Modifier = TI->getSecond().Modifier;
1577 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1578 DVar.RefExpr = buildDeclRefExpr(
1579 SemaRef, VD, D->getType().getNonReferenceType(),
1580 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1581 DVar.CKind = OMPC_threadprivate;
1582 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1585 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1586 // in a Construct, C/C++, predetermined, p.1]
1587 // Variables appearing in threadprivate directives are threadprivate.
1588 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1589 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1590 SemaRef.getLangOpts().OpenMPUseTLS &&
1591 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1592 (VD && VD->getStorageClass() == SC_Register &&
1593 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1594 DVar.RefExpr = buildDeclRefExpr(
1595 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1596 DVar.CKind = OMPC_threadprivate;
1597 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1600 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1601 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1602 !isLoopControlVariable(D).first) {
1603 const_iterator IterTarget =
1604 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1605 return isOpenMPTargetExecutionDirective(Data.Directive);
1607 if (IterTarget != end()) {
1608 const_iterator ParentIterTarget = IterTarget + 1;
1609 for (const_iterator Iter = begin();
1610 Iter != ParentIterTarget; ++Iter) {
1611 if (isOpenMPLocal(VD, Iter)) {
1613 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1615 DVar.CKind = OMPC_threadprivate;
1619 if (!isClauseParsingMode() || IterTarget != begin()) {
1620 auto DSAIter = IterTarget->SharingMap.find(D);
1621 if (DSAIter != IterTarget->SharingMap.end() &&
1622 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1623 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1624 DVar.CKind = OMPC_threadprivate;
1627 const_iterator End = end();
1628 if (!SemaRef.isOpenMPCapturedByRef(
1629 D, std::distance(ParentIterTarget, End),
1630 /*OpenMPCaptureLevel=*/0)) {
1632 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1633 IterTarget->ConstructLoc);
1634 DVar.CKind = OMPC_threadprivate;
1642 // Not in OpenMP execution region and top scope was already checked.
1645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1646 // in a Construct, C/C++, predetermined, p.4]
1647 // Static data members are shared.
1648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1649 // in a Construct, C/C++, predetermined, p.7]
1650 // Variables with static storage duration that are declared in a scope
1651 // inside the construct are shared.
1652 if (VD && VD->isStaticDataMember()) {
1653 // Check for explicitly specified attributes.
1654 const_iterator I = begin();
1655 const_iterator EndI = end();
1656 if (FromParent && I != EndI)
1659 auto It = I->SharingMap.find(D);
1660 if (It != I->SharingMap.end()) {
1661 const DSAInfo &Data = It->getSecond();
1662 DVar.RefExpr = Data.RefExpr.getPointer();
1663 DVar.PrivateCopy = Data.PrivateCopy;
1664 DVar.CKind = Data.Attributes;
1665 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1666 DVar.DKind = I->Directive;
1667 DVar.Modifier = Data.Modifier;
1672 DVar.CKind = OMPC_shared;
1676 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1677 // The predetermined shared attribute for const-qualified types having no
1678 // mutable members was removed after OpenMP 3.1.
1679 if (SemaRef.LangOpts.OpenMP <= 31) {
1680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1681 // in a Construct, C/C++, predetermined, p.6]
1682 // Variables with const qualified type having no mutable member are
1684 if (isConstNotMutableType(SemaRef, D->getType())) {
1685 // Variables with const-qualified type having no mutable member may be
1686 // listed in a firstprivate clause, even if they are static data members.
1687 DSAVarData DVarTemp = hasInnermostDSA(
1689 [](OpenMPClauseKind C) {
1690 return C == OMPC_firstprivate || C == OMPC_shared;
1692 MatchesAlways, FromParent);
1693 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1696 DVar.CKind = OMPC_shared;
1701 // Explicitly specified attributes and local variables with predetermined
1703 const_iterator I = begin();
1704 const_iterator EndI = end();
1705 if (FromParent && I != EndI)
1709 auto It = I->SharingMap.find(D);
1710 if (It != I->SharingMap.end()) {
1711 const DSAInfo &Data = It->getSecond();
1712 DVar.RefExpr = Data.RefExpr.getPointer();
1713 DVar.PrivateCopy = Data.PrivateCopy;
1714 DVar.CKind = Data.Attributes;
1715 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716 DVar.DKind = I->Directive;
1717 DVar.Modifier = Data.Modifier;
1723 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1724 bool FromParent) const {
1725 if (isStackEmpty()) {
1727 return getDSA(I, D);
1729 D = getCanonicalDecl(D);
1730 const_iterator StartI = begin();
1731 const_iterator EndI = end();
1732 if (FromParent && StartI != EndI)
1734 return getDSA(StartI, D);
1737 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1738 unsigned Level) const {
1739 if (getStackSize() <= Level)
1740 return DSAVarData();
1741 D = getCanonicalDecl(D);
1742 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1743 return getDSA(StartI, D);
1746 const DSAStackTy::DSAVarData
1747 DSAStackTy::hasDSA(ValueDecl *D,
1748 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1749 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1750 bool FromParent) const {
1753 D = getCanonicalDecl(D);
1754 const_iterator I = begin();
1755 const_iterator EndI = end();
1756 if (FromParent && I != EndI)
1758 for (; I != EndI; ++I) {
1759 if (!DPred(I->Directive) &&
1760 !isImplicitOrExplicitTaskingRegion(I->Directive))
1762 const_iterator NewI = I;
1763 DSAVarData DVar = getDSA(NewI, D);
1764 if (I == NewI && CPred(DVar.CKind))
1770 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1771 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1772 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1773 bool FromParent) const {
1776 D = getCanonicalDecl(D);
1777 const_iterator StartI = begin();
1778 const_iterator EndI = end();
1779 if (FromParent && StartI != EndI)
1781 if (StartI == EndI || !DPred(StartI->Directive))
1783 const_iterator NewI = StartI;
1784 DSAVarData DVar = getDSA(NewI, D);
1785 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1788 bool DSAStackTy::hasExplicitDSA(
1789 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1790 unsigned Level, bool NotLastprivate) const {
1791 if (getStackSize() <= Level)
1793 D = getCanonicalDecl(D);
1794 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1795 auto I = StackElem.SharingMap.find(D);
1796 if (I != StackElem.SharingMap.end() &&
1797 I->getSecond().RefExpr.getPointer() &&
1798 CPred(I->getSecond().Attributes) &&
1799 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1801 // Check predetermined rules for the loop control variables.
1802 auto LI = StackElem.LCVMap.find(D);
1803 if (LI != StackElem.LCVMap.end())
1804 return CPred(OMPC_private);
1808 bool DSAStackTy::hasExplicitDirective(
1809 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1810 unsigned Level) const {
1811 if (getStackSize() <= Level)
1813 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1814 return DPred(StackElem.Directive);
1817 bool DSAStackTy::hasDirective(
1818 const llvm::function_ref<bool(OpenMPDirectiveKind,
1819 const DeclarationNameInfo &, SourceLocation)>
1821 bool FromParent) const {
1822 // We look only in the enclosing region.
1823 size_t Skip = FromParent ? 2 : 1;
1824 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1826 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1832 void Sema::InitDataSharingAttributesStack() {
1833 VarDataSharingAttributesStack = new DSAStackTy(*this);
1836 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1838 void Sema::pushOpenMPFunctionRegion() {
1839 DSAStack->pushFunction();
1842 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1843 DSAStack->popFunction(OldFSI);
1846 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1847 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1848 "Expected OpenMP device compilation.");
1849 return !S.isInOpenMPTargetExecutionDirective() &&
1850 !S.isInOpenMPDeclareTargetContext();
1854 /// Status of the function emission on the host/device.
1855 enum class FunctionEmissionStatus {
1860 } // anonymous namespace
1862 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1864 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1865 "Expected OpenMP device compilation.");
1867 FunctionDecl *FD = getCurFunctionDecl();
1868 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1870 FunctionEmissionStatus FES = getEmissionStatus(FD);
1872 case FunctionEmissionStatus::Emitted:
1873 Kind = DeviceDiagBuilder::K_Immediate;
1875 case FunctionEmissionStatus::Unknown:
1876 Kind = isOpenMPDeviceDelayedContext(*this)
1877 ? DeviceDiagBuilder::K_Deferred
1878 : DeviceDiagBuilder::K_Immediate;
1880 case FunctionEmissionStatus::TemplateDiscarded:
1881 case FunctionEmissionStatus::OMPDiscarded:
1882 Kind = DeviceDiagBuilder::K_Nop;
1884 case FunctionEmissionStatus::CUDADiscarded:
1885 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1890 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1893 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1895 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1896 "Expected OpenMP host compilation.");
1897 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1898 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1900 case FunctionEmissionStatus::Emitted:
1901 Kind = DeviceDiagBuilder::K_Immediate;
1903 case FunctionEmissionStatus::Unknown:
1904 Kind = DeviceDiagBuilder::K_Deferred;
1906 case FunctionEmissionStatus::TemplateDiscarded:
1907 case FunctionEmissionStatus::OMPDiscarded:
1908 case FunctionEmissionStatus::CUDADiscarded:
1909 Kind = DeviceDiagBuilder::K_Nop;
1913 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1916 static OpenMPDefaultmapClauseKind
1917 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1918 if (LO.OpenMP <= 45) {
1919 if (VD->getType().getNonReferenceType()->isScalarType())
1920 return OMPC_DEFAULTMAP_scalar;
1921 return OMPC_DEFAULTMAP_aggregate;
1923 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1924 return OMPC_DEFAULTMAP_pointer;
1925 if (VD->getType().getNonReferenceType()->isScalarType())
1926 return OMPC_DEFAULTMAP_scalar;
1927 return OMPC_DEFAULTMAP_aggregate;
1930 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1931 unsigned OpenMPCaptureLevel) const {
1932 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1934 ASTContext &Ctx = getASTContext();
1935 bool IsByRef = true;
1937 // Find the directive that is associated with the provided scope.
1938 D = cast<ValueDecl>(D->getCanonicalDecl());
1939 QualType Ty = D->getType();
1941 bool IsVariableUsedInMapClause = false;
1942 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1943 // This table summarizes how a given variable should be passed to the device
1944 // given its type and the clauses where it appears. This table is based on
1945 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1946 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1948 // =========================================================================
1949 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1950 // | |(tofrom:scalar)| | pvt | | | |
1951 // =========================================================================
1952 // | scl | | | | - | | bycopy|
1953 // | scl | | - | x | - | - | bycopy|
1954 // | scl | | x | - | - | - | null |
1955 // | scl | x | | | - | | byref |
1956 // | scl | x | - | x | - | - | bycopy|
1957 // | scl | x | x | - | - | - | null |
1958 // | scl | | - | - | - | x | byref |
1959 // | scl | x | - | - | - | x | byref |
1961 // | agg | n.a. | | | - | | byref |
1962 // | agg | n.a. | - | x | - | - | byref |
1963 // | agg | n.a. | x | - | - | - | null |
1964 // | agg | n.a. | - | - | - | x | byref |
1965 // | agg | n.a. | - | - | - | x[] | byref |
1967 // | ptr | n.a. | | | - | | bycopy|
1968 // | ptr | n.a. | - | x | - | - | bycopy|
1969 // | ptr | n.a. | x | - | - | - | null |
1970 // | ptr | n.a. | - | - | - | x | byref |
1971 // | ptr | n.a. | - | - | - | x[] | bycopy|
1972 // | ptr | n.a. | - | - | x | | bycopy|
1973 // | ptr | n.a. | - | - | x | x | bycopy|
1974 // | ptr | n.a. | - | - | x | x[] | bycopy|
1975 // =========================================================================
1981 // - - invalid in this combination
1982 // [] - mapped with an array section
1983 // byref - should be mapped by reference
1984 // byval - should be mapped by value
1985 // null - initialize a local variable to null on the device
1988 // - All scalar declarations that show up in a map clause have to be passed
1989 // by reference, because they may have been mapped in the enclosing data
1991 // - If the scalar value does not fit the size of uintptr, it has to be
1992 // passed by reference, regardless the result in the table above.
1993 // - For pointers mapped by value that have either an implicit map or an
1994 // array section, the runtime library may pass the NULL value to the
1995 // device instead of the value passed to it by the compiler.
1997 if (Ty->isReferenceType())
1998 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2000 // Locate map clauses and see if the variable being captured is referred to
2001 // in any of those clauses. Here we only care about variables, not fields,
2002 // because fields are part of aggregates.
2003 bool IsVariableAssociatedWithSection = false;
2005 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2007 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2008 OMPClauseMappableExprCommon::MappableExprComponentListRef
2010 OpenMPClauseKind WhereFoundClauseKind) {
2011 // Only the map clause information influences how a variable is
2012 // captured. E.g. is_device_ptr does not require changing the default
2014 if (WhereFoundClauseKind != OMPC_map)
2017 auto EI = MapExprComponents.rbegin();
2018 auto EE = MapExprComponents.rend();
2020 assert(EI != EE && "Invalid map expression!");
2022 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2023 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2029 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2030 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2031 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2032 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2033 IsVariableAssociatedWithSection = true;
2034 // There is nothing more we need to know about this variable.
2038 // Keep looking for more map info.
2042 if (IsVariableUsedInMapClause) {
2043 // If variable is identified in a map clause it is always captured by
2044 // reference except if it is a pointer that is dereferenced somehow.
2045 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2047 // By default, all the data that has a scalar type is mapped by copy
2048 // (except for reduction variables).
2049 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2051 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2052 !Ty->isAnyPointerType()) ||
2053 !Ty->isScalarType() ||
2054 DSAStack->isDefaultmapCapturedByRef(
2055 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2056 DSAStack->hasExplicitDSA(
2057 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
2061 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2063 ((IsVariableUsedInMapClause &&
2064 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2066 !(DSAStack->hasExplicitDSA(
2068 [](OpenMPClauseKind K) -> bool {
2069 return K == OMPC_firstprivate;
2071 Level, /*NotLastprivate=*/true) ||
2072 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2073 // If the variable is artificial and must be captured by value - try to
2074 // capture by value.
2075 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2076 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2077 // If the variable is implicitly firstprivate and scalar - capture by
2079 !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2080 !DSAStack->hasExplicitDSA(
2081 D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) &&
2082 !DSAStack->isLoopControlVariable(D, Level).first);
2085 // When passing data by copy, we need to make sure it fits the uintptr size
2086 // and alignment, because the runtime library only deals with uintptr types.
2087 // If it does not fit the uintptr size, we need to pass the data by reference
2090 (Ctx.getTypeSizeInChars(Ty) >
2091 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2092 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2099 unsigned Sema::getOpenMPNestingLevel() const {
2100 assert(getLangOpts().OpenMP);
2101 return DSAStack->getNestingLevel();
2104 bool Sema::isInOpenMPTargetExecutionDirective() const {
2105 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2106 !DSAStack->isClauseParsingMode()) ||
2107 DSAStack->hasDirective(
2108 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2109 SourceLocation) -> bool {
2110 return isOpenMPTargetExecutionDirective(K);
2115 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2117 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2118 D = getCanonicalDecl(D);
2120 auto *VD = dyn_cast<VarDecl>(D);
2121 // Do not capture constexpr variables.
2122 if (VD && VD->isConstexpr())
2125 // If we want to determine whether the variable should be captured from the
2126 // perspective of the current capturing scope, and we've already left all the
2127 // capturing scopes of the top directive on the stack, check from the
2128 // perspective of its parent directive (if any) instead.
2129 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2130 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2132 // If we are attempting to capture a global variable in a directive with
2133 // 'target' we return true so that this global is also mapped to the device.
2135 if (VD && !VD->hasLocalStorage() &&
2136 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2137 if (isInOpenMPDeclareTargetContext()) {
2138 // Try to mark variable as declare target if it is used in capturing
2140 if (LangOpts.OpenMP <= 45 &&
2141 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2142 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2144 } else if (isInOpenMPTargetExecutionDirective()) {
2145 // If the declaration is enclosed in a 'declare target' directive,
2146 // then it should not be captured.
2148 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2150 CapturedRegionScopeInfo *CSI = nullptr;
2151 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2152 llvm::reverse(FunctionScopes),
2153 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2154 if (!isa<CapturingScopeInfo>(FSI))
2156 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2157 if (RSI->CapRegionKind == CR_OpenMP) {
2162 SmallVector<OpenMPDirectiveKind, 4> Regions;
2163 getOpenMPCaptureRegions(Regions,
2164 DSAStack->getDirective(CSI->OpenMPLevel));
2165 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2170 if (CheckScopeInfo) {
2171 bool OpenMPFound = false;
2172 for (unsigned I = StopAt + 1; I > 0; --I) {
2173 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2174 if(!isa<CapturingScopeInfo>(FSI))
2176 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2177 if (RSI->CapRegionKind == CR_OpenMP) {
2186 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2187 (!DSAStack->isClauseParsingMode() ||
2188 DSAStack->getParentDirective() != OMPD_unknown)) {
2189 auto &&Info = DSAStack->isLoopControlVariable(D);
2191 (VD && VD->hasLocalStorage() &&
2192 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2193 (VD && DSAStack->isForceVarCapturing()))
2194 return VD ? VD : Info.second;
2195 DSAStackTy::DSAVarData DVarTop =
2196 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2197 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind))
2198 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2199 // Threadprivate variables must not be captured.
2200 if (isOpenMPThreadPrivate(DVarTop.CKind))
2202 // The variable is not private or it is the variable in the directive with
2203 // default(none) clause and not used in any clause.
2204 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2205 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
2206 DSAStack->isClauseParsingMode());
2207 // Global shared must not be captured.
2208 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2209 ((DSAStack->getDefaultDSA() != DSA_none &&
2210 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2211 DVarTop.CKind == OMPC_shared))
2213 if (DVarPrivate.CKind != OMPC_unknown ||
2214 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2215 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2216 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2221 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2222 unsigned Level) const {
2223 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2226 void Sema::startOpenMPLoop() {
2227 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2228 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2229 DSAStack->loopInit();
2232 void Sema::startOpenMPCXXRangeFor() {
2233 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2234 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2235 DSAStack->resetPossibleLoopCounter();
2236 DSAStack->loopStart();
2240 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2241 unsigned CapLevel) const {
2242 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2243 if (DSAStack->hasExplicitDirective(
2244 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2246 bool IsTriviallyCopyable =
2247 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2249 .getNonReferenceType()
2251 ->getAsCXXRecordDecl();
2252 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2253 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2254 getOpenMPCaptureRegions(CaptureRegions, DKind);
2255 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2256 (IsTriviallyCopyable ||
2257 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2258 if (DSAStack->hasExplicitDSA(
2259 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; },
2260 Level, /*NotLastprivate=*/true))
2261 return OMPC_firstprivate;
2262 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2263 if (DVar.CKind != OMPC_shared &&
2264 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2265 DSAStack->addImplicitTaskFirstprivate(Level, D);
2266 return OMPC_firstprivate;
2270 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2271 if (DSAStack->getAssociatedLoops() > 0 &&
2272 !DSAStack->isLoopStarted()) {
2273 DSAStack->resetPossibleLoopCounter(D);
2274 DSAStack->loopStart();
2275 return OMPC_private;
2277 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2278 DSAStack->isLoopControlVariable(D).first) &&
2279 !DSAStack->hasExplicitDSA(
2280 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2281 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2282 return OMPC_private;
2284 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2285 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2286 DSAStack->isForceVarCapturing() &&
2287 !DSAStack->hasExplicitDSA(
2288 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2289 return OMPC_private;
2291 // User-defined allocators are private since they must be defined in the
2292 // context of target region.
2293 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2294 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2295 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2296 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2297 return OMPC_private;
2298 return (DSAStack->hasExplicitDSA(
2299 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2300 (DSAStack->isClauseParsingMode() &&
2301 DSAStack->getClauseParsingMode() == OMPC_private) ||
2302 // Consider taskgroup reduction descriptor variable a private
2303 // to avoid possible capture in the region.
2304 (DSAStack->hasExplicitDirective(
2305 [](OpenMPDirectiveKind K) {
2306 return K == OMPD_taskgroup ||
2307 ((isOpenMPParallelDirective(K) ||
2308 isOpenMPWorksharingDirective(K)) &&
2309 !isOpenMPSimdDirective(K));
2312 DSAStack->isTaskgroupReductionRef(D, Level)))
2317 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2319 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2320 D = getCanonicalDecl(D);
2321 OpenMPClauseKind OMPC = OMPC_unknown;
2322 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2323 const unsigned NewLevel = I - 1;
2324 if (DSAStack->hasExplicitDSA(D,
2325 [&OMPC](const OpenMPClauseKind K) {
2326 if (isOpenMPPrivate(K)) {
2334 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2336 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2337 OpenMPClauseKind) { return true; })) {
2341 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2344 if (DSAStack->mustBeFirstprivateAtLevel(
2345 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2346 OMPC = OMPC_firstprivate;
2350 if (OMPC != OMPC_unknown)
2351 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2354 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2355 unsigned CaptureLevel) const {
2356 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2357 // Return true if the current level is no longer enclosed in a target region.
2359 SmallVector<OpenMPDirectiveKind, 4> Regions;
2360 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2361 const auto *VD = dyn_cast<VarDecl>(D);
2362 return VD && !VD->hasLocalStorage() &&
2363 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2365 Regions[CaptureLevel] != OMPD_task;
2368 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2369 unsigned CaptureLevel) const {
2370 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2371 // Return true if the current level is no longer enclosed in a target region.
2373 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2374 if (!VD->hasLocalStorage()) {
2375 DSAStackTy::DSAVarData TopDVar =
2376 DSAStack->getTopDSA(D, /*FromParent=*/false);
2377 unsigned NumLevels =
2378 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2380 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2381 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1);
2382 return DVar.CKind != OMPC_shared ||
2383 isOpenMPGlobalCapturedDecl(
2385 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1);
2391 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2393 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2395 if (!OMPDeclareVariantScopes.empty()) {
2396 Diag(Loc, diag::warn_nested_declare_variant);
2399 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2402 void Sema::ActOnOpenMPEndDeclareVariant() {
2403 assert(isInOpenMPDeclareVariantScope() &&
2404 "Not in OpenMP declare variant scope!");
2406 OMPDeclareVariantScopes.pop_back();
2409 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2410 const FunctionDecl *Callee,
2411 SourceLocation Loc) {
2412 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2413 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2414 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2415 // Ignore host functions during device analyzis.
2416 if (LangOpts.OpenMPIsDevice && DevTy &&
2417 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2419 // Ignore nohost functions during host analyzis.
2420 if (!LangOpts.OpenMPIsDevice && DevTy &&
2421 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2423 const FunctionDecl *FD = Callee->getMostRecentDecl();
2424 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2425 if (LangOpts.OpenMPIsDevice && DevTy &&
2426 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2427 // Diagnose host function called during device codegen.
2428 StringRef HostDevTy =
2429 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2430 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2431 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2432 diag::note_omp_marked_device_type_here)
2436 if (!LangOpts.OpenMPIsDevice && DevTy &&
2437 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2438 // Diagnose nohost function called during host codegen.
2439 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2440 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2441 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2442 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2443 diag::note_omp_marked_device_type_here)
2448 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2449 const DeclarationNameInfo &DirName,
2450 Scope *CurScope, SourceLocation Loc) {
2451 DSAStack->push(DKind, DirName, CurScope, Loc);
2452 PushExpressionEvaluationContext(
2453 ExpressionEvaluationContext::PotentiallyEvaluated);
2456 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2457 DSAStack->setClauseParsingMode(K);
2460 void Sema::EndOpenMPClause() {
2461 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2464 static std::pair<ValueDecl *, bool>
2465 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2466 SourceRange &ERange, bool AllowArraySection = false);
2468 /// Check consistency of the reduction clauses.
2469 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2470 ArrayRef<OMPClause *> Clauses) {
2471 bool InscanFound = false;
2472 SourceLocation InscanLoc;
2473 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2474 // A reduction clause without the inscan reduction-modifier may not appear on
2475 // a construct on which a reduction clause with the inscan reduction-modifier
2477 for (OMPClause *C : Clauses) {
2478 if (C->getClauseKind() != OMPC_reduction)
2480 auto *RC = cast<OMPReductionClause>(C);
2481 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2483 InscanLoc = RC->getModifierLoc();
2486 if (RC->getModifier() == OMPC_REDUCTION_task) {
2487 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2488 // A reduction clause with the task reduction-modifier may only appear on
2489 // a parallel construct, a worksharing construct or a combined or
2490 // composite construct for which any of the aforementioned constructs is a
2491 // constituent construct and simd or loop are not constituent constructs.
2492 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2493 if (!(isOpenMPParallelDirective(CurDir) ||
2494 isOpenMPWorksharingDirective(CurDir)) ||
2495 isOpenMPSimdDirective(CurDir))
2496 S.Diag(RC->getModifierLoc(),
2497 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2502 for (OMPClause *C : Clauses) {
2503 if (C->getClauseKind() != OMPC_reduction)
2505 auto *RC = cast<OMPReductionClause>(C);
2506 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2507 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2509 : RC->getModifierLoc(),
2510 diag::err_omp_inscan_reduction_expected);
2511 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2514 for (Expr *Ref : RC->varlists()) {
2515 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2516 SourceLocation ELoc;
2518 Expr *SimpleRefExpr = Ref;
2519 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2520 /*AllowArraySection=*/true);
2521 ValueDecl *D = Res.first;
2524 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2525 S.Diag(Ref->getExprLoc(),
2526 diag::err_omp_reduction_not_inclusive_exclusive)
2527 << Ref->getSourceRange();
2534 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2535 ArrayRef<OMPClause *> Clauses);
2536 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2539 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2541 const DSAStackTy::DSAVarData &DVar,
2542 bool IsLoopIterVar = false);
2544 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2545 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2546 // A variable of class type (or array thereof) that appears in a lastprivate
2547 // clause requires an accessible, unambiguous default constructor for the
2548 // class type, unless the list item is also specified in a firstprivate
2550 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2551 for (OMPClause *C : D->clauses()) {
2552 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2553 SmallVector<Expr *, 8> PrivateCopies;
2554 for (Expr *DE : Clause->varlists()) {
2555 if (DE->isValueDependent() || DE->isTypeDependent()) {
2556 PrivateCopies.push_back(nullptr);
2559 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2560 auto *VD = cast<VarDecl>(DRE->getDecl());
2561 QualType Type = VD->getType().getNonReferenceType();
2562 const DSAStackTy::DSAVarData DVar =
2563 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2564 if (DVar.CKind == OMPC_lastprivate) {
2565 // Generate helper private variable and initialize it with the
2566 // default value. The address of the original variable is replaced
2567 // by the address of the new private variable in CodeGen. This new
2568 // variable is not added to IdResolver, so the code in the OpenMP
2569 // region uses original variable for proper diagnostics.
2570 VarDecl *VDPrivate = buildVarDecl(
2571 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2572 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2573 ActOnUninitializedDecl(VDPrivate);
2574 if (VDPrivate->isInvalidDecl()) {
2575 PrivateCopies.push_back(nullptr);
2578 PrivateCopies.push_back(buildDeclRefExpr(
2579 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2581 // The variable is also a firstprivate, so initialization sequence
2582 // for private copy is generated already.
2583 PrivateCopies.push_back(nullptr);
2586 Clause->setPrivateCopies(PrivateCopies);
2589 // Finalize nontemporal clause by handling private copies, if any.
2590 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2591 SmallVector<Expr *, 8> PrivateRefs;
2592 for (Expr *RefExpr : Clause->varlists()) {
2593 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2594 SourceLocation ELoc;
2596 Expr *SimpleRefExpr = RefExpr;
2597 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2599 // It will be analyzed later.
2600 PrivateRefs.push_back(RefExpr);
2601 ValueDecl *D = Res.first;
2605 const DSAStackTy::DSAVarData DVar =
2606 DSAStack->getTopDSA(D, /*FromParent=*/false);
2607 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2610 Clause->setPrivateRefs(PrivateRefs);
2613 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2614 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2615 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2616 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2619 ValueDecl *VD = DRE->getDecl();
2620 if (!VD || !isa<VarDecl>(VD))
2622 DSAStackTy::DSAVarData DVar =
2623 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2624 // OpenMP [2.12.5, target Construct]
2625 // Memory allocators that appear in a uses_allocators clause cannot
2626 // appear in other data-sharing attribute clauses or data-mapping
2627 // attribute clauses in the same construct.
2628 Expr *MapExpr = nullptr;
2630 DSAStack->checkMappableExprComponentListsForDecl(
2631 VD, /*CurrentRegionOnly=*/true,
2633 OMPClauseMappableExprCommon::MappableExprComponentListRef
2635 OpenMPClauseKind C) {
2636 auto MI = MapExprComponents.rbegin();
2637 auto ME = MapExprComponents.rend();
2639 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2640 VD->getCanonicalDecl()) {
2641 MapExpr = MI->getAssociatedExpression();
2646 Diag(D.Allocator->getExprLoc(),
2647 diag::err_omp_allocator_used_in_clauses)
2648 << D.Allocator->getSourceRange();
2650 reportOriginalDsa(*this, DSAStack, VD, DVar);
2652 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2653 << MapExpr->getSourceRange();
2659 // Check allocate clauses.
2660 if (!CurContext->isDependentContext())
2661 checkAllocateClauses(*this, DSAStack, D->clauses());
2662 checkReductionClauses(*this, DSAStack, D->clauses());
2666 DiscardCleanupsInEvaluationContext();
2667 PopExpressionEvaluationContext();
2670 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2671 Expr *NumIterations, Sema &SemaRef,
2672 Scope *S, DSAStackTy *Stack);
2676 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2681 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2682 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2683 NamedDecl *ND = Candidate.getCorrectionDecl();
2684 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2685 return VD->hasGlobalStorage() &&
2686 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2687 SemaRef.getCurScope());
2692 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2693 return std::make_unique<VarDeclFilterCCC>(*this);
2698 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2703 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2704 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2705 NamedDecl *ND = Candidate.getCorrectionDecl();
2706 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2707 isa<FunctionDecl>(ND))) {
2708 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2709 SemaRef.getCurScope());
2714 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2715 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2721 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2722 CXXScopeSpec &ScopeSpec,
2723 const DeclarationNameInfo &Id,
2724 OpenMPDirectiveKind Kind) {
2725 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2726 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2728 if (Lookup.isAmbiguous())
2732 if (!Lookup.isSingleResult()) {
2733 VarDeclFilterCCC CCC(*this);
2734 if (TypoCorrection Corrected =
2735 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2736 CTK_ErrorRecovery)) {
2737 diagnoseTypo(Corrected,
2738 PDiag(Lookup.empty()
2739 ? diag::err_undeclared_var_use_suggest
2740 : diag::err_omp_expected_var_arg_suggest)
2742 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2744 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2745 : diag::err_omp_expected_var_arg)
2749 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2750 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2751 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2754 Lookup.suppressDiagnostics();
2756 // OpenMP [2.9.2, Syntax, C/C++]
2757 // Variables must be file-scope, namespace-scope, or static block-scope.
2758 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2759 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2760 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2762 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2763 Diag(VD->getLocation(),
2764 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2769 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2770 NamedDecl *ND = CanonicalVD;
2771 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2772 // A threadprivate directive for file-scope variables must appear outside
2773 // any definition or declaration.
2774 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2775 !getCurLexicalContext()->isTranslationUnit()) {
2776 Diag(Id.getLoc(), diag::err_omp_var_scope)
2777 << getOpenMPDirectiveName(Kind) << VD;
2779 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2780 Diag(VD->getLocation(),
2781 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2785 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2786 // A threadprivate directive for static class member variables must appear
2787 // in the class definition, in the same scope in which the member
2788 // variables are declared.
2789 if (CanonicalVD->isStaticDataMember() &&
2790 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2791 Diag(Id.getLoc(), diag::err_omp_var_scope)
2792 << getOpenMPDirectiveName(Kind) << VD;
2794 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2795 Diag(VD->getLocation(),
2796 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2800 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2801 // A threadprivate directive for namespace-scope variables must appear
2802 // outside any definition or declaration other than the namespace
2803 // definition itself.
2804 if (CanonicalVD->getDeclContext()->isNamespace() &&
2805 (!getCurLexicalContext()->isFileContext() ||
2806 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2807 Diag(Id.getLoc(), diag::err_omp_var_scope)
2808 << getOpenMPDirectiveName(Kind) << VD;
2810 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2811 Diag(VD->getLocation(),
2812 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2816 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2817 // A threadprivate directive for static block-scope variables must appear
2818 // in the scope of the variable and not in a nested scope.
2819 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2820 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2821 Diag(Id.getLoc(), diag::err_omp_var_scope)
2822 << getOpenMPDirectiveName(Kind) << VD;
2824 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2825 Diag(VD->getLocation(),
2826 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2831 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2832 // A threadprivate directive must lexically precede all references to any
2833 // of the variables in its list.
2834 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2835 !DSAStack->isThreadPrivate(VD)) {
2836 Diag(Id.getLoc(), diag::err_omp_var_used)
2837 << getOpenMPDirectiveName(Kind) << VD;
2841 QualType ExprType = VD->getType().getNonReferenceType();
2842 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2843 SourceLocation(), VD,
2844 /*RefersToEnclosingVariableOrCapture=*/false,
2845 Id.getLoc(), ExprType, VK_LValue);
2848 Sema::DeclGroupPtrTy
2849 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2850 ArrayRef<Expr *> VarList) {
2851 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2852 CurContext->addDecl(D);
2853 return DeclGroupPtrTy::make(DeclGroupRef(D));
2859 class LocalVarRefChecker final
2860 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2864 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2865 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2866 if (VD->hasLocalStorage()) {
2867 SemaRef.Diag(E->getBeginLoc(),
2868 diag::err_omp_local_var_in_threadprivate_init)
2869 << E->getSourceRange();
2870 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2871 << VD << VD->getSourceRange();
2877 bool VisitStmt(const Stmt *S) {
2878 for (const Stmt *Child : S->children()) {
2879 if (Child && Visit(Child))
2884 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2888 OMPThreadPrivateDecl *
2889 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2890 SmallVector<Expr *, 8> Vars;
2891 for (Expr *RefExpr : VarList) {
2892 auto *DE = cast<DeclRefExpr>(RefExpr);
2893 auto *VD = cast<VarDecl>(DE->getDecl());
2894 SourceLocation ILoc = DE->getExprLoc();
2896 // Mark variable as used.
2897 VD->setReferenced();
2898 VD->markUsed(Context);
2900 QualType QType = VD->getType();
2901 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2902 // It will be analyzed later.
2907 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2908 // A threadprivate variable must not have an incomplete type.
2909 if (RequireCompleteType(ILoc, VD->getType(),
2910 diag::err_omp_threadprivate_incomplete_type)) {
2914 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2915 // A threadprivate variable must not have a reference type.
2916 if (VD->getType()->isReferenceType()) {
2917 Diag(ILoc, diag::err_omp_ref_type_arg)
2918 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2920 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2921 Diag(VD->getLocation(),
2922 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2927 // Check if this is a TLS variable. If TLS is not being supported, produce
2928 // the corresponding diagnostic.
2929 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2930 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2931 getLangOpts().OpenMPUseTLS &&
2932 getASTContext().getTargetInfo().isTLSSupported())) ||
2933 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2934 !VD->isLocalVarDecl())) {
2935 Diag(ILoc, diag::err_omp_var_thread_local)
2936 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2938 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2939 Diag(VD->getLocation(),
2940 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2945 // Check if initial value of threadprivate variable reference variable with
2946 // local storage (it is not supported by runtime).
2947 if (const Expr *Init = VD->getAnyInitializer()) {
2948 LocalVarRefChecker Checker(*this);
2949 if (Checker.Visit(Init))
2953 Vars.push_back(RefExpr);
2954 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2955 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2956 Context, SourceRange(Loc, Loc)));
2957 if (ASTMutationListener *ML = Context.getASTMutationListener())
2958 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2960 OMPThreadPrivateDecl *D = nullptr;
2961 if (!Vars.empty()) {
2962 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2964 D->setAccess(AS_public);
2969 static OMPAllocateDeclAttr::AllocatorTypeTy
2970 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2972 return OMPAllocateDeclAttr::OMPNullMemAlloc;
2973 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2974 Allocator->isInstantiationDependent() ||
2975 Allocator->containsUnexpandedParameterPack())
2976 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2977 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2978 const Expr *AE = Allocator->IgnoreParenImpCasts();
2979 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2980 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2981 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2982 llvm::FoldingSetNodeID AEId, DAEId;
2983 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2984 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2985 if (AEId == DAEId) {
2986 AllocatorKindRes = AllocatorKind;
2990 return AllocatorKindRes;
2993 static bool checkPreviousOMPAllocateAttribute(
2994 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2995 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2996 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2998 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2999 Expr *PrevAllocator = A->getAllocator();
3000 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3001 getAllocatorKind(S, Stack, PrevAllocator);
3002 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3003 if (AllocatorsMatch &&
3004 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3005 Allocator && PrevAllocator) {
3006 const Expr *AE = Allocator->IgnoreParenImpCasts();
3007 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3008 llvm::FoldingSetNodeID AEId, PAEId;
3009 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3010 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3011 AllocatorsMatch = AEId == PAEId;
3013 if (!AllocatorsMatch) {
3014 SmallString<256> AllocatorBuffer;
3015 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3017 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3018 SmallString<256> PrevAllocatorBuffer;
3019 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3021 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3022 S.getPrintingPolicy());
3024 SourceLocation AllocatorLoc =
3025 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3026 SourceRange AllocatorRange =
3027 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3028 SourceLocation PrevAllocatorLoc =
3029 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3030 SourceRange PrevAllocatorRange =
3031 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3032 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3033 << (Allocator ? 1 : 0) << AllocatorStream.str()
3034 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3036 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3037 << PrevAllocatorRange;
3044 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3045 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3046 Expr *Allocator, SourceRange SR) {
3047 if (VD->hasAttr<OMPAllocateDeclAttr>())
3050 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3051 Allocator->isInstantiationDependent() ||
3052 Allocator->containsUnexpandedParameterPack()))
3054 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3057 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3058 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3061 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3062 SourceLocation Loc, ArrayRef<Expr *> VarList,
3063 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3064 assert(Clauses.size() <= 1 && "Expected at most one clause.");
3065 Expr *Allocator = nullptr;
3066 if (Clauses.empty()) {
3067 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3068 // allocate directives that appear in a target region must specify an
3069 // allocator clause unless a requires directive with the dynamic_allocators
3070 // clause is present in the same compilation unit.
3071 if (LangOpts.OpenMPIsDevice &&
3072 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3073 targetDiag(Loc, diag::err_expected_allocator_clause);
3075 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3077 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3078 getAllocatorKind(*this, DSAStack, Allocator);
3079 SmallVector<Expr *, 8> Vars;
3080 for (Expr *RefExpr : VarList) {
3081 auto *DE = cast<DeclRefExpr>(RefExpr);
3082 auto *VD = cast<VarDecl>(DE->getDecl());
3084 // Check if this is a TLS variable or global register.
3085 if (VD->getTLSKind() != VarDecl::TLS_None ||
3086 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3087 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3088 !VD->isLocalVarDecl()))
3091 // If the used several times in the allocate directive, the same allocator
3093 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3094 AllocatorKind, Allocator))
3097 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3098 // If a list item has a static storage type, the allocator expression in the
3099 // allocator clause must be a constant expression that evaluates to one of
3100 // the predefined memory allocator values.
3101 if (Allocator && VD->hasGlobalStorage()) {
3102 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3103 Diag(Allocator->getExprLoc(),
3104 diag::err_omp_expected_predefined_allocator)
3105 << Allocator->getSourceRange();
3106 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3107 VarDecl::DeclarationOnly;
3108 Diag(VD->getLocation(),
3109 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3115 Vars.push_back(RefExpr);
3116 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3117 DE->getSourceRange());
3122 Owner = getCurLexicalContext();
3123 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3124 D->setAccess(AS_public);
3126 return DeclGroupPtrTy::make(DeclGroupRef(D));
3129 Sema::DeclGroupPtrTy
3130 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3131 ArrayRef<OMPClause *> ClauseList) {
3132 OMPRequiresDecl *D = nullptr;
3133 if (!CurContext->isFileContext()) {
3134 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3136 D = CheckOMPRequiresDecl(Loc, ClauseList);
3138 CurContext->addDecl(D);
3139 DSAStack->addRequiresDecl(D);
3142 return DeclGroupPtrTy::make(DeclGroupRef(D));
3145 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3146 ArrayRef<OMPClause *> ClauseList) {
3147 /// For target specific clauses, the requires directive cannot be
3148 /// specified after the handling of any of the target regions in the
3149 /// current compilation unit.
3150 ArrayRef<SourceLocation> TargetLocations =
3151 DSAStack->getEncounteredTargetLocs();
3152 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3153 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3154 for (const OMPClause *CNew : ClauseList) {
3155 // Check if any of the requires clauses affect target regions.
3156 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3157 isa<OMPUnifiedAddressClause>(CNew) ||
3158 isa<OMPReverseOffloadClause>(CNew) ||
3159 isa<OMPDynamicAllocatorsClause>(CNew)) {
3160 Diag(Loc, diag::err_omp_directive_before_requires)
3161 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3162 for (SourceLocation TargetLoc : TargetLocations) {
3163 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3166 } else if (!AtomicLoc.isInvalid() &&
3167 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3168 Diag(Loc, diag::err_omp_directive_before_requires)
3169 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3170 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3176 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3177 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3182 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3184 const DSAStackTy::DSAVarData &DVar,
3185 bool IsLoopIterVar) {
3187 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3188 << getOpenMPClauseName(DVar.CKind);
3192 PDSA_StaticMemberShared,
3193 PDSA_StaticLocalVarShared,
3194 PDSA_LoopIterVarPrivate,
3195 PDSA_LoopIterVarLinear,
3196 PDSA_LoopIterVarLastprivate,
3197 PDSA_ConstVarShared,
3198 PDSA_GlobalVarShared,
3199 PDSA_TaskVarFirstprivate,
3200 PDSA_LocalVarPrivate,
3202 } Reason = PDSA_Implicit;
3203 bool ReportHint = false;
3204 auto ReportLoc = D->getLocation();
3205 auto *VD = dyn_cast<VarDecl>(D);
3206 if (IsLoopIterVar) {
3207 if (DVar.CKind == OMPC_private)
3208 Reason = PDSA_LoopIterVarPrivate;
3209 else if (DVar.CKind == OMPC_lastprivate)
3210 Reason = PDSA_LoopIterVarLastprivate;
3212 Reason = PDSA_LoopIterVarLinear;
3213 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3214 DVar.CKind == OMPC_firstprivate) {
3215 Reason = PDSA_TaskVarFirstprivate;
3216 ReportLoc = DVar.ImplicitDSALoc;
3217 } else if (VD && VD->isStaticLocal())
3218 Reason = PDSA_StaticLocalVarShared;
3219 else if (VD && VD->isStaticDataMember())
3220 Reason = PDSA_StaticMemberShared;
3221 else if (VD && VD->isFileVarDecl())
3222 Reason = PDSA_GlobalVarShared;
3223 else if (D->getType().isConstant(SemaRef.getASTContext()))
3224 Reason = PDSA_ConstVarShared;
3225 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3227 Reason = PDSA_LocalVarPrivate;
3229 if (Reason != PDSA_Implicit) {
3230 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3231 << Reason << ReportHint
3232 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3233 } else if (DVar.ImplicitDSALoc.isValid()) {
3234 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3235 << getOpenMPClauseName(DVar.CKind);
3239 static OpenMPMapClauseKind
3240 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3241 bool IsAggregateOrDeclareTarget) {
3242 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3244 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3245 Kind = OMPC_MAP_alloc;
3247 case OMPC_DEFAULTMAP_MODIFIER_to:
3250 case OMPC_DEFAULTMAP_MODIFIER_from:
3251 Kind = OMPC_MAP_from;
3253 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3254 Kind = OMPC_MAP_tofrom;
3256 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3257 case OMPC_DEFAULTMAP_MODIFIER_last:
3258 llvm_unreachable("Unexpected defaultmap implicit behavior");
3259 case OMPC_DEFAULTMAP_MODIFIER_none:
3260 case OMPC_DEFAULTMAP_MODIFIER_default:
3261 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3262 // IsAggregateOrDeclareTarget could be true if:
3263 // 1. the implicit behavior for aggregate is tofrom
3264 // 2. it's a declare target link
3265 if (IsAggregateOrDeclareTarget) {
3266 Kind = OMPC_MAP_tofrom;
3269 llvm_unreachable("Unexpected defaultmap implicit behavior");
3271 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3276 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3279 bool ErrorFound = false;
3280 bool TryCaptureCXXThisMembers = false;
3281 CapturedStmt *CS = nullptr;
3282 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3283 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3284 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3285 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3287 void VisitSubCaptures(OMPExecutableDirective *S) {
3288 // Check implicitly captured variables.
3289 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3291 visitSubCaptures(S->getInnermostCapturedStmt());
3292 // Try to capture inner this->member references to generate correct mappings
3294 if (TryCaptureCXXThisMembers ||
3295 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3296 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3297 [](const CapturedStmt::Capture &C) {
3298 return C.capturesThis();
3300 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3301 TryCaptureCXXThisMembers = true;
3302 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3303 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3305 // In tasks firstprivates are not captured anymore, need to analyze them
3307 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3308 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3309 for (OMPClause *C : S->clauses())
3310 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3311 for (Expr *Ref : FC->varlists())
3318 void VisitDeclRefExpr(DeclRefExpr *E) {
3319 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3320 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3321 E->isInstantiationDependent())
3323 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3324 // Check the datasharing rules for the expressions in the clauses.
3326 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3327 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3328 Visit(CED->getInit());
3331 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3332 // Do not analyze internal variables and do not enclose them into
3333 // implicit clauses.
3335 VD = VD->getCanonicalDecl();
3336 // Skip internally declared variables.
3337 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3338 !Stack->isImplicitTaskFirstprivate(VD))
3340 // Skip allocators in uses_allocators clauses.
3341 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3344 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3345 // Check if the variable has explicit DSA set and stop analysis if it so.
3346 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3349 // Skip internally declared static variables.
3350 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3351 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3352 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3353 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3354 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3355 !Stack->isImplicitTaskFirstprivate(VD))
3358 SourceLocation ELoc = E->getExprLoc();
3359 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3360 // The default(none) clause requires that each variable that is referenced
3361 // in the construct, and does not have a predetermined data-sharing
3362 // attribute, must have its data-sharing attribute explicitly determined
3363 // by being listed in a data-sharing attribute clause.
3364 if (DVar.CKind == OMPC_unknown &&
3365 (Stack->getDefaultDSA() == DSA_none ||
3366 Stack->getDefaultDSA() == DSA_firstprivate) &&
3367 isImplicitOrExplicitTaskingRegion(DKind) &&
3368 VarsWithInheritedDSA.count(VD) == 0) {
3369 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3370 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3371 DSAStackTy::DSAVarData DVar =
3372 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3373 InheritedDSA = DVar.CKind == OMPC_unknown;
3376 VarsWithInheritedDSA[VD] = E;
3380 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3381 // If implicit-behavior is none, each variable referenced in the
3382 // construct that does not have a predetermined data-sharing attribute
3383 // and does not appear in a to or link clause on a declare target
3384 // directive must be listed in a data-mapping attribute clause, a
3385 // data-haring attribute clause (including a data-sharing attribute
3386 // clause on a combined construct where target. is one of the
3387 // constituent constructs), or an is_device_ptr clause.
3388 OpenMPDefaultmapClauseKind ClauseKind =
3389 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3390 if (SemaRef.getLangOpts().OpenMP >= 50) {
3391 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3392 OMPC_DEFAULTMAP_MODIFIER_none;
3393 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3394 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3395 // Only check for data-mapping attribute and is_device_ptr here
3396 // since we have already make sure that the declaration does not
3397 // have a data-sharing attribute above
3398 if (!Stack->checkMappableExprComponentListsForDecl(
3399 VD, /*CurrentRegionOnly=*/true,
3400 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3403 auto MI = MapExprComponents.rbegin();
3404 auto ME = MapExprComponents.rend();
3405 return MI != ME && MI->getAssociatedDeclaration() == VD;
3407 VarsWithInheritedDSA[VD] = E;
3413 if (isOpenMPTargetExecutionDirective(DKind) &&
3414 !Stack->isLoopControlVariable(VD).first) {
3415 if (!Stack->checkMappableExprComponentListsForDecl(
3416 VD, /*CurrentRegionOnly=*/true,
3417 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3420 // Variable is used if it has been marked as an array, array
3421 // section, array shaping or the variable iself.
3422 return StackComponents.size() == 1 ||
3424 std::next(StackComponents.rbegin()),
3425 StackComponents.rend(),
3426 [](const OMPClauseMappableExprCommon::
3427 MappableComponent &MC) {
3428 return MC.getAssociatedDeclaration() ==
3430 (isa<OMPArraySectionExpr>(
3431 MC.getAssociatedExpression()) ||
3432 isa<OMPArrayShapingExpr>(
3433 MC.getAssociatedExpression()) ||
3434 isa<ArraySubscriptExpr>(
3435 MC.getAssociatedExpression()));
3438 bool IsFirstprivate = false;
3439 // By default lambdas are captured as firstprivates.
3440 if (const auto *RD =
3441 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3442 IsFirstprivate = RD->isLambda();
3444 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3445 if (IsFirstprivate) {
3446 ImplicitFirstprivate.emplace_back(E);
3448 OpenMPDefaultmapClauseModifier M =
3449 Stack->getDefaultmapModifier(ClauseKind);
3450 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3451 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3452 ImplicitMap[Kind].emplace_back(E);
3458 // OpenMP [2.9.3.6, Restrictions, p.2]
3459 // A list item that appears in a reduction clause of the innermost
3460 // enclosing worksharing or parallel construct may not be accessed in an
3462 DVar = Stack->hasInnermostDSA(
3463 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3464 [](OpenMPDirectiveKind K) {
3465 return isOpenMPParallelDirective(K) ||
3466 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3468 /*FromParent=*/true);
3469 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3471 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3472 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3476 // Define implicit data-sharing attributes for task.
3477 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3478 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3479 (Stack->getDefaultDSA() == DSA_firstprivate &&
3480 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3481 !Stack->isLoopControlVariable(VD).first) {
3482 ImplicitFirstprivate.push_back(E);
3486 // Store implicitly used globals with declare target link for parent
3488 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3489 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3490 Stack->addToParentTargetRegionLinkGlobals(E);
3495 void VisitMemberExpr(MemberExpr *E) {
3496 if (E->isTypeDependent() || E->isValueDependent() ||
3497 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3499 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3500 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3501 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3504 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3505 // Check if the variable has explicit DSA set and stop analysis if it
3507 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3510 if (isOpenMPTargetExecutionDirective(DKind) &&
3511 !Stack->isLoopControlVariable(FD).first &&
3512 !Stack->checkMappableExprComponentListsForDecl(
3513 FD, /*CurrentRegionOnly=*/true,
3514 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3517 return isa<CXXThisExpr>(
3519 StackComponents.back().getAssociatedExpression())
3523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3524 // A bit-field cannot appear in a map clause.
3526 if (FD->isBitField())
3529 // Check to see if the member expression is referencing a class that
3530 // has already been explicitly mapped
3531 if (Stack->isClassPreviouslyMapped(TE->getType()))
3534 OpenMPDefaultmapClauseModifier Modifier =
3535 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3536 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3537 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3538 ImplicitMap[Kind].emplace_back(E);
3542 SourceLocation ELoc = E->getExprLoc();
3543 // OpenMP [2.9.3.6, Restrictions, p.2]
3544 // A list item that appears in a reduction clause of the innermost
3545 // enclosing worksharing or parallel construct may not be accessed in
3546 // an explicit task.
3547 DVar = Stack->hasInnermostDSA(
3548 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3549 [](OpenMPDirectiveKind K) {
3550 return isOpenMPParallelDirective(K) ||
3551 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3553 /*FromParent=*/true);
3554 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3556 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3557 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3561 // Define implicit data-sharing attributes for task.
3562 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3563 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3564 !Stack->isLoopControlVariable(FD).first) {
3565 // Check if there is a captured expression for the current field in the
3566 // region. Do not mark it as firstprivate unless there is no captured
3568 // TODO: try to make it firstprivate.
3569 if (DVar.CKind != OMPC_unknown)
3570 ImplicitFirstprivate.push_back(E);
3574 if (isOpenMPTargetExecutionDirective(DKind)) {
3575 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3576 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3577 /*NoDiagnose=*/true))
3579 const auto *VD = cast<ValueDecl>(
3580 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3581 if (!Stack->checkMappableExprComponentListsForDecl(
3582 VD, /*CurrentRegionOnly=*/true,
3584 OMPClauseMappableExprCommon::MappableExprComponentListRef
3587 auto CCI = CurComponents.rbegin();
3588 auto CCE = CurComponents.rend();
3589 for (const auto &SC : llvm::reverse(StackComponents)) {
3590 // Do both expressions have the same kind?
3591 if (CCI->getAssociatedExpression()->getStmtClass() !=
3592 SC.getAssociatedExpression()->getStmtClass())
3593 if (!((isa<OMPArraySectionExpr>(
3594 SC.getAssociatedExpression()) ||
3595 isa<OMPArrayShapingExpr>(
3596 SC.getAssociatedExpression())) &&
3597 isa<ArraySubscriptExpr>(
3598 CCI->getAssociatedExpression())))
3601 const Decl *CCD = CCI->getAssociatedDeclaration();
3602 const Decl *SCD = SC.getAssociatedDeclaration();
3603 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3604 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3607 std::advance(CCI, 1);
3613 Visit(E->getBase());
3615 } else if (!TryCaptureCXXThisMembers) {
3616 Visit(E->getBase());
3619 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3620 for (OMPClause *C : S->clauses()) {
3621 // Skip analysis of arguments of implicitly defined firstprivate clause
3622 // for task|target directives.
3623 // Skip analysis of arguments of implicitly defined map clause for target
3625 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3627 for (Stmt *CC : C->children()) {
3633 // Check implicitly captured variables.
3634 VisitSubCaptures(S);
3636 void VisitStmt(Stmt *S) {
3637 for (Stmt *C : S->children()) {
3639 // Check implicitly captured variables in the task-based directives to
3640 // check if they must be firstprivatized.
3646 void visitSubCaptures(CapturedStmt *S) {
3647 for (const CapturedStmt::Capture &Cap : S->captures()) {
3648 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3650 VarDecl *VD = Cap.getCapturedVar();
3651 // Do not try to map the variable if it or its sub-component was mapped
3653 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3654 Stack->checkMappableExprComponentListsForDecl(
3655 VD, /*CurrentRegionOnly=*/true,
3656 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3657 OpenMPClauseKind) { return true; }))
3659 DeclRefExpr *DRE = buildDeclRefExpr(
3660 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3661 Cap.getLocation(), /*RefersToCapture=*/true);
3665 bool isErrorFound() const { return ErrorFound; }
3666 ArrayRef<Expr *> getImplicitFirstprivate() const {
3667 return ImplicitFirstprivate;
3669 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3670 return ImplicitMap[Kind];
3672 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3673 return VarsWithInheritedDSA;
3676 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3677 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3678 // Process declare target link variables for the target directives.
3679 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3680 for (DeclRefExpr *E : Stack->getLinkGlobals())
3687 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3690 case OMPD_parallel_for:
3691 case OMPD_parallel_for_simd:
3692 case OMPD_parallel_sections:
3693 case OMPD_parallel_master:
3695 case OMPD_teams_distribute:
3696 case OMPD_teams_distribute_simd: {
3697 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3698 QualType KmpInt32PtrTy =
3699 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3700 Sema::CapturedParamNameType Params[] = {
3701 std::make_pair(".global_tid.", KmpInt32PtrTy),
3702 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3703 std::make_pair(StringRef(), QualType()) // __context with shared vars
3705 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3709 case OMPD_target_teams:
3710 case OMPD_target_parallel:
3711 case OMPD_target_parallel_for:
3712 case OMPD_target_parallel_for_simd:
3713 case OMPD_target_teams_distribute:
3714 case OMPD_target_teams_distribute_simd: {
3715 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3716 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3717 QualType KmpInt32PtrTy =
3718 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3719 QualType Args[] = {VoidPtrTy};
3720 FunctionProtoType::ExtProtoInfo EPI;
3721 EPI.Variadic = true;
3722 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3723 Sema::CapturedParamNameType Params[] = {
3724 std::make_pair(".global_tid.", KmpInt32Ty),
3725 std::make_pair(".part_id.", KmpInt32PtrTy),
3726 std::make_pair(".privates.", VoidPtrTy),
3729 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3730 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3731 std::make_pair(StringRef(), QualType()) // __context with shared vars
3733 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3734 Params, /*OpenMPCaptureLevel=*/0);
3735 // Mark this captured region as inlined, because we don't use outlined
3736 // function directly.
3737 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3738 AlwaysInlineAttr::CreateImplicit(
3739 Context, {}, AttributeCommonInfo::AS_Keyword,
3740 AlwaysInlineAttr::Keyword_forceinline));
3741 Sema::CapturedParamNameType ParamsTarget[] = {
3742 std::make_pair(StringRef(), QualType()) // __context with shared vars
3744 // Start a captured region for 'target' with no implicit parameters.
3745 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3746 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3747 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3748 std::make_pair(".global_tid.", KmpInt32PtrTy),
3749 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3750 std::make_pair(StringRef(), QualType()) // __context with shared vars
3752 // Start a captured region for 'teams' or 'parallel'. Both regions have
3753 // the same implicit parameters.
3754 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3755 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3759 case OMPD_target_simd: {
3760 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3761 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3762 QualType KmpInt32PtrTy =
3763 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3764 QualType Args[] = {VoidPtrTy};
3765 FunctionProtoType::ExtProtoInfo EPI;
3766 EPI.Variadic = true;
3767 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3768 Sema::CapturedParamNameType Params[] = {
3769 std::make_pair(".global_tid.", KmpInt32Ty),
3770 std::make_pair(".part_id.", KmpInt32PtrTy),
3771 std::make_pair(".privates.", VoidPtrTy),
3774 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3775 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3776 std::make_pair(StringRef(), QualType()) // __context with shared vars
3778 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3779 Params, /*OpenMPCaptureLevel=*/0);
3780 // Mark this captured region as inlined, because we don't use outlined
3781 // function directly.
3782 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3783 AlwaysInlineAttr::CreateImplicit(
3784 Context, {}, AttributeCommonInfo::AS_Keyword,
3785 AlwaysInlineAttr::Keyword_forceinline));
3786 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3787 std::make_pair(StringRef(), QualType()),
3788 /*OpenMPCaptureLevel=*/1);
3799 case OMPD_taskgroup:
3800 case OMPD_distribute:
3801 case OMPD_distribute_simd:
3804 case OMPD_target_data: {
3805 Sema::CapturedParamNameType Params[] = {
3806 std::make_pair(StringRef(), QualType()) // __context with shared vars
3808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3813 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3814 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3815 QualType KmpInt32PtrTy =
3816 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3817 QualType Args[] = {VoidPtrTy};
3818 FunctionProtoType::ExtProtoInfo EPI;
3819 EPI.Variadic = true;
3820 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3821 Sema::CapturedParamNameType Params[] = {
3822 std::make_pair(".global_tid.", KmpInt32Ty),
3823 std::make_pair(".part_id.", KmpInt32PtrTy),
3824 std::make_pair(".privates.", VoidPtrTy),
3827 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3828 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3829 std::make_pair(StringRef(), QualType()) // __context with shared vars
3831 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3833 // Mark this captured region as inlined, because we don't use outlined
3834 // function directly.
3835 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3836 AlwaysInlineAttr::CreateImplicit(
3837 Context, {}, AttributeCommonInfo::AS_Keyword,
3838 AlwaysInlineAttr::Keyword_forceinline));
3842 case OMPD_taskloop_simd:
3843 case OMPD_master_taskloop:
3844 case OMPD_master_taskloop_simd: {
3845 QualType KmpInt32Ty =
3846 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3848 QualType KmpUInt64Ty =
3849 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3851 QualType KmpInt64Ty =
3852 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3854 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3855 QualType KmpInt32PtrTy =
3856 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3857 QualType Args[] = {VoidPtrTy};
3858 FunctionProtoType::ExtProtoInfo EPI;
3859 EPI.Variadic = true;
3860 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3861 Sema::CapturedParamNameType Params[] = {
3862 std::make_pair(".global_tid.", KmpInt32Ty),
3863 std::make_pair(".part_id.", KmpInt32PtrTy),
3864 std::make_pair(".privates.", VoidPtrTy),
3867 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3868 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3869 std::make_pair(".lb.", KmpUInt64Ty),
3870 std::make_pair(".ub.", KmpUInt64Ty),
3871 std::make_pair(".st.", KmpInt64Ty),
3872 std::make_pair(".liter.", KmpInt32Ty),
3873 std::make_pair(".reductions.", VoidPtrTy),
3874 std::make_pair(StringRef(), QualType()) // __context with shared vars
3876 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3878 // Mark this captured region as inlined, because we don't use outlined
3879 // function directly.
3880 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3881 AlwaysInlineAttr::CreateImplicit(
3882 Context, {}, AttributeCommonInfo::AS_Keyword,
3883 AlwaysInlineAttr::Keyword_forceinline));
3886 case OMPD_parallel_master_taskloop:
3887 case OMPD_parallel_master_taskloop_simd: {
3888 QualType KmpInt32Ty =
3889 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3891 QualType KmpUInt64Ty =
3892 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3894 QualType KmpInt64Ty =
3895 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3897 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3898 QualType KmpInt32PtrTy =
3899 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3900 Sema::CapturedParamNameType ParamsParallel[] = {
3901 std::make_pair(".global_tid.", KmpInt32PtrTy),
3902 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3903 std::make_pair(StringRef(), QualType()) // __context with shared vars
3905 // Start a captured region for 'parallel'.
3906 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3907 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3908 QualType Args[] = {VoidPtrTy};
3909 FunctionProtoType::ExtProtoInfo EPI;
3910 EPI.Variadic = true;
3911 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3912 Sema::CapturedParamNameType Params[] = {
3913 std::make_pair(".global_tid.", KmpInt32Ty),
3914 std::make_pair(".part_id.", KmpInt32PtrTy),
3915 std::make_pair(".privates.", VoidPtrTy),
3918 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3919 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3920 std::make_pair(".lb.", KmpUInt64Ty),
3921 std::make_pair(".ub.", KmpUInt64Ty),
3922 std::make_pair(".st.", KmpInt64Ty),
3923 std::make_pair(".liter.", KmpInt32Ty),
3924 std::make_pair(".reductions.", VoidPtrTy),
3925 std::make_pair(StringRef(), QualType()) // __context with shared vars
3927 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3928 Params, /*OpenMPCaptureLevel=*/1);
3929 // Mark this captured region as inlined, because we don't use outlined
3930 // function directly.
3931 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3932 AlwaysInlineAttr::CreateImplicit(
3933 Context, {}, AttributeCommonInfo::AS_Keyword,
3934 AlwaysInlineAttr::Keyword_forceinline));
3937 case OMPD_distribute_parallel_for_simd:
3938 case OMPD_distribute_parallel_for: {
3939 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3940 QualType KmpInt32PtrTy =
3941 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3942 Sema::CapturedParamNameType Params[] = {
3943 std::make_pair(".global_tid.", KmpInt32PtrTy),
3944 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3945 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3946 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3947 std::make_pair(StringRef(), QualType()) // __context with shared vars
3949 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3953 case OMPD_target_teams_distribute_parallel_for:
3954 case OMPD_target_teams_distribute_parallel_for_simd: {
3955 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3956 QualType KmpInt32PtrTy =
3957 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3958 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3960 QualType Args[] = {VoidPtrTy};
3961 FunctionProtoType::ExtProtoInfo EPI;
3962 EPI.Variadic = true;
3963 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3964 Sema::CapturedParamNameType Params[] = {
3965 std::make_pair(".global_tid.", KmpInt32Ty),
3966 std::make_pair(".part_id.", KmpInt32PtrTy),
3967 std::make_pair(".privates.", VoidPtrTy),
3970 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3971 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3972 std::make_pair(StringRef(), QualType()) // __context with shared vars
3974 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3975 Params, /*OpenMPCaptureLevel=*/0);
3976 // Mark this captured region as inlined, because we don't use outlined
3977 // function directly.
3978 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3979 AlwaysInlineAttr::CreateImplicit(
3980 Context, {}, AttributeCommonInfo::AS_Keyword,
3981 AlwaysInlineAttr::Keyword_forceinline));
3982 Sema::CapturedParamNameType ParamsTarget[] = {
3983 std::make_pair(StringRef(), QualType()) // __context with shared vars
3985 // Start a captured region for 'target' with no implicit parameters.
3986 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3987 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3989 Sema::CapturedParamNameType ParamsTeams[] = {
3990 std::make_pair(".global_tid.", KmpInt32PtrTy),
3991 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3992 std::make_pair(StringRef(), QualType()) // __context with shared vars
3994 // Start a captured region for 'target' with no implicit parameters.
3995 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3996 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3998 Sema::CapturedParamNameType ParamsParallel[] = {
3999 std::make_pair(".global_tid.", KmpInt32PtrTy),
4000 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4001 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4002 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4003 std::make_pair(StringRef(), QualType()) // __context with shared vars
4005 // Start a captured region for 'teams' or 'parallel'. Both regions have
4006 // the same implicit parameters.
4007 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4008 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4012 case OMPD_teams_distribute_parallel_for:
4013 case OMPD_teams_distribute_parallel_for_simd: {
4014 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4015 QualType KmpInt32PtrTy =
4016 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4018 Sema::CapturedParamNameType ParamsTeams[] = {
4019 std::make_pair(".global_tid.", KmpInt32PtrTy),
4020 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4021 std::make_pair(StringRef(), QualType()) // __context with shared vars
4023 // Start a captured region for 'target' with no implicit parameters.
4024 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4025 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4027 Sema::CapturedParamNameType ParamsParallel[] = {
4028 std::make_pair(".global_tid.", KmpInt32PtrTy),
4029 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4030 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4031 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4032 std::make_pair(StringRef(), QualType()) // __context with shared vars
4034 // Start a captured region for 'teams' or 'parallel'. Both regions have
4035 // the same implicit parameters.
4036 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4037 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4040 case OMPD_target_update:
4041 case OMPD_target_enter_data:
4042 case OMPD_target_exit_data: {
4043 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4044 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4045 QualType KmpInt32PtrTy =
4046 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4047 QualType Args[] = {VoidPtrTy};
4048 FunctionProtoType::ExtProtoInfo EPI;
4049 EPI.Variadic = true;
4050 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4051 Sema::CapturedParamNameType Params[] = {
4052 std::make_pair(".global_tid.", KmpInt32Ty),
4053 std::make_pair(".part_id.", KmpInt32PtrTy),
4054 std::make_pair(".privates.", VoidPtrTy),
4057 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4058 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4059 std::make_pair(StringRef(), QualType()) // __context with shared vars
4061 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4063 // Mark this captured region as inlined, because we don't use outlined
4064 // function directly.
4065 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4066 AlwaysInlineAttr::CreateImplicit(
4067 Context, {}, AttributeCommonInfo::AS_Keyword,
4068 AlwaysInlineAttr::Keyword_forceinline));
4071 case OMPD_threadprivate:
4073 case OMPD_taskyield:
4076 case OMPD_cancellation_point:
4081 case OMPD_declare_reduction:
4082 case OMPD_declare_mapper:
4083 case OMPD_declare_simd:
4084 case OMPD_declare_target:
4085 case OMPD_end_declare_target:
4087 case OMPD_declare_variant:
4088 case OMPD_begin_declare_variant:
4089 case OMPD_end_declare_variant:
4090 llvm_unreachable("OpenMP Directive is not allowed");
4093 llvm_unreachable("Unknown OpenMP directive");
4097 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4098 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4101 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4102 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4103 getOpenMPCaptureRegions(CaptureRegions, DKind);
4104 return CaptureRegions.size();
4107 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4108 Expr *CaptureExpr, bool WithInit,
4109 bool AsExpression) {
4110 assert(CaptureExpr);
4111 ASTContext &C = S.getASTContext();
4112 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4113 QualType Ty = Init->getType();
4114 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4115 if (S.getLangOpts().CPlusPlus) {
4116 Ty = C.getLValueReferenceType(Ty);
4118 Ty = C.getPointerType(Ty);
4120 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4121 if (!Res.isUsable())
4127 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4128 CaptureExpr->getBeginLoc());
4130 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4131 S.CurContext->addHiddenDecl(CED);
4132 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4136 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4138 OMPCapturedExprDecl *CD;
4139 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4140 CD = cast<OMPCapturedExprDecl>(VD);
4142 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4143 /*AsExpression=*/false);
4144 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4145 CaptureExpr->getExprLoc());
4148 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4149 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4151 OMPCapturedExprDecl *CD = buildCaptureDecl(
4152 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4153 /*WithInit=*/true, /*AsExpression=*/true);
4154 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4155 CaptureExpr->getExprLoc());
4157 ExprResult Res = Ref;
4158 if (!S.getLangOpts().CPlusPlus &&
4159 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4160 Ref->getType()->isPointerType()) {
4161 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4162 if (!Res.isUsable())
4165 return S.DefaultLvalueConversion(Res.get());
4169 // OpenMP directives parsed in this section are represented as a
4170 // CapturedStatement with an associated statement. If a syntax error
4171 // is detected during the parsing of the associated statement, the
4172 // compiler must abort processing and close the CapturedStatement.
4174 // Combined directives such as 'target parallel' have more than one
4175 // nested CapturedStatements. This RAII ensures that we unwind out
4176 // of all the nested CapturedStatements when an error is found.
4177 class CaptureRegionUnwinderRAII {
4181 OpenMPDirectiveKind DKind = OMPD_unknown;
4184 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4185 OpenMPDirectiveKind DKind)
4186 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4187 ~CaptureRegionUnwinderRAII() {
4189 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4190 while (--ThisCaptureLevel >= 0)
4191 S.ActOnCapturedRegionError();
4197 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4198 // Capture variables captured by reference in lambdas for target-based
4200 if (!CurContext->isDependentContext() &&
4201 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4202 isOpenMPTargetDataManagementDirective(
4203 DSAStack->getCurrentDirective()))) {
4204 QualType Type = V->getType();
4205 if (const auto *RD = Type.getCanonicalType()
4206 .getNonReferenceType()
4207 ->getAsCXXRecordDecl()) {
4208 bool SavedForceCaptureByReferenceInTargetExecutable =
4209 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4210 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4212 if (RD->isLambda()) {
4213 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4214 FieldDecl *ThisCapture;
4215 RD->getCaptureFields(Captures, ThisCapture);
4216 for (const LambdaCapture &LC : RD->captures()) {
4217 if (LC.getCaptureKind() == LCK_ByRef) {
4218 VarDecl *VD = LC.getCapturedVar();
4219 DeclContext *VDC = VD->getDeclContext();
4220 if (!VDC->Encloses(CurContext))
4222 MarkVariableReferenced(LC.getLocation(), VD);
4223 } else if (LC.getCaptureKind() == LCK_This) {
4224 QualType ThisTy = getCurrentThisType();
4225 if (!ThisTy.isNull() &&
4226 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4227 CheckCXXThisCapture(LC.getLocation());
4231 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4232 SavedForceCaptureByReferenceInTargetExecutable);
4237 static bool checkOrderedOrderSpecified(Sema &S,
4238 const ArrayRef<OMPClause *> Clauses) {
4239 const OMPOrderedClause *Ordered = nullptr;
4240 const OMPOrderClause *Order = nullptr;
4242 for (const OMPClause *Clause : Clauses) {
4243 if (Clause->getClauseKind() == OMPC_ordered)
4244 Ordered = cast<OMPOrderedClause>(Clause);
4245 else if (Clause->getClauseKind() == OMPC_order) {
4246 Order = cast<OMPOrderClause>(Clause);
4247 if (Order->getKind() != OMPC_ORDER_concurrent)
4250 if (Ordered && Order)
4254 if (Ordered && Order) {
4255 S.Diag(Order->getKindKwLoc(),
4256 diag::err_omp_simple_clause_incompatible_with_ordered)
4257 << getOpenMPClauseName(OMPC_order)
4258 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4259 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4260 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4261 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4267 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4268 ArrayRef<OMPClause *> Clauses) {
4269 bool ErrorFound = false;
4270 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4271 *this, ErrorFound, DSAStack->getCurrentDirective());
4272 if (!S.isUsable()) {
4277 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4278 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4279 OMPOrderedClause *OC = nullptr;
4280 OMPScheduleClause *SC = nullptr;
4281 SmallVector<const OMPLinearClause *, 4> LCs;
4282 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4283 // This is required for proper codegen.
4284 for (OMPClause *Clause : Clauses) {
4285 if (!LangOpts.OpenMPSimd &&
4286 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4287 Clause->getClauseKind() == OMPC_in_reduction) {
4288 // Capture taskgroup task_reduction descriptors inside the tasking regions
4289 // with the corresponding in_reduction items.
4290 auto *IRC = cast<OMPInReductionClause>(Clause);
4291 for (Expr *E : IRC->taskgroup_descriptors())
4293 MarkDeclarationsReferencedInExpr(E);
4295 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4296 Clause->getClauseKind() == OMPC_copyprivate ||
4297 (getLangOpts().OpenMPUseTLS &&
4298 getASTContext().getTargetInfo().isTLSSupported() &&
4299 Clause->getClauseKind() == OMPC_copyin)) {
4300 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4301 // Mark all variables in private list clauses as used in inner region.
4302 for (Stmt *VarRef : Clause->children()) {
4303 if (auto *E = cast_or_null<Expr>(VarRef)) {
4304 MarkDeclarationsReferencedInExpr(E);
4307 DSAStack->setForceVarCapturing(/*V=*/false);
4308 } else if (CaptureRegions.size() > 1 ||
4309 CaptureRegions.back() != OMPD_unknown) {
4310 if (auto *C = OMPClauseWithPreInit::get(Clause))
4312 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4313 if (Expr *E = C->getPostUpdateExpr())
4314 MarkDeclarationsReferencedInExpr(E);
4317 if (Clause->getClauseKind() == OMPC_schedule)
4318 SC = cast<OMPScheduleClause>(Clause);
4319 else if (Clause->getClauseKind() == OMPC_ordered)
4320 OC = cast<OMPOrderedClause>(Clause);
4321 else if (Clause->getClauseKind() == OMPC_linear)
4322 LCs.push_back(cast<OMPLinearClause>(Clause));
4324 // Capture allocator expressions if used.
4325 for (Expr *E : DSAStack->getInnerAllocators())
4326 MarkDeclarationsReferencedInExpr(E);
4327 // OpenMP, 2.7.1 Loop Construct, Restrictions
4328 // The nonmonotonic modifier cannot be specified if an ordered clause is
4331 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4332 SC->getSecondScheduleModifier() ==
4333 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4335 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4336 ? SC->getFirstScheduleModifierLoc()
4337 : SC->getSecondScheduleModifierLoc(),
4338 diag::err_omp_simple_clause_incompatible_with_ordered)
4339 << getOpenMPClauseName(OMPC_schedule)
4340 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4341 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4342 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4345 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4346 // If an order(concurrent) clause is present, an ordered clause may not appear
4347 // on the same directive.
4348 if (checkOrderedOrderSpecified(*this, Clauses))
4350 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4351 for (const OMPLinearClause *C : LCs) {
4352 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4353 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4357 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4358 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4359 OC->getNumForLoops()) {
4360 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4361 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4368 unsigned CompletedRegions = 0;
4369 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4370 // Mark all variables in private list clauses as used in inner region.
4371 // Required for proper codegen of combined directives.
4372 // TODO: add processing for other clauses.
4373 if (ThisCaptureRegion != OMPD_unknown) {
4374 for (const clang::OMPClauseWithPreInit *C : PICs) {
4375 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4376 // Find the particular capture region for the clause if the
4377 // directive is a combined one with multiple capture regions.
4378 // If the directive is not a combined one, the capture region
4379 // associated with the clause is OMPD_unknown and is generated
4381 if (CaptureRegion == ThisCaptureRegion ||
4382 CaptureRegion == OMPD_unknown) {
4383 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4384 for (Decl *D : DS->decls())
4385 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4390 if (ThisCaptureRegion == OMPD_target) {
4391 // Capture allocator traits in the target region. They are used implicitly
4392 // and, thus, are not captured by default.
4393 for (OMPClause *C : Clauses) {
4394 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4395 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4397 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4398 if (Expr *E = D.AllocatorTraits)
4399 MarkDeclarationsReferencedInExpr(E);
4405 if (++CompletedRegions == CaptureRegions.size())
4406 DSAStack->setBodyComplete();
4407 SR = ActOnCapturedRegionEnd(SR.get());
4412 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4413 OpenMPDirectiveKind CancelRegion,
4414 SourceLocation StartLoc) {
4415 // CancelRegion is only needed for cancel and cancellation_point.
4416 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4419 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4420 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4423 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4424 << getOpenMPDirectiveName(CancelRegion);
4428 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4429 OpenMPDirectiveKind CurrentRegion,
4430 const DeclarationNameInfo &CurrentName,
4431 OpenMPDirectiveKind CancelRegion,
4432 SourceLocation StartLoc) {
4433 if (Stack->getCurScope()) {
4434 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4435 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4436 bool NestingProhibited = false;
4437 bool CloseNesting = true;
4438 bool OrphanSeen = false;
4441 ShouldBeInParallelRegion,
4442 ShouldBeInOrderedRegion,
4443 ShouldBeInTargetRegion,
4444 ShouldBeInTeamsRegion,
4445 ShouldBeInLoopSimdRegion,
4446 } Recommend = NoRecommend;
4447 if (isOpenMPSimdDirective(ParentRegion) &&
4448 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4449 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4450 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4451 CurrentRegion != OMPD_scan))) {
4452 // OpenMP [2.16, Nesting of Regions]
4453 // OpenMP constructs may not be nested inside a simd region.
4454 // OpenMP [2.8.1,simd Construct, Restrictions]
4455 // An ordered construct with the simd clause is the only OpenMP
4456 // construct that can appear in the simd region.
4457 // Allowing a SIMD construct nested in another SIMD construct is an
4458 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4460 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4461 // The only OpenMP constructs that can be encountered during execution of
4462 // a simd region are the atomic construct, the loop construct, the simd
4463 // construct and the ordered construct with the simd clause.
4464 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4465 ? diag::err_omp_prohibited_region_simd
4466 : diag::warn_omp_nesting_simd)
4467 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4468 return CurrentRegion != OMPD_simd;
4470 if (ParentRegion == OMPD_atomic) {
4471 // OpenMP [2.16, Nesting of Regions]
4472 // OpenMP constructs may not be nested inside an atomic region.
4473 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4476 if (CurrentRegion == OMPD_section) {
4477 // OpenMP [2.7.2, sections Construct, Restrictions]
4478 // Orphaned section directives are prohibited. That is, the section
4479 // directives must appear within the sections construct and must not be
4480 // encountered elsewhere in the sections region.
4481 if (ParentRegion != OMPD_sections &&
4482 ParentRegion != OMPD_parallel_sections) {
4483 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4484 << (ParentRegion != OMPD_unknown)
4485 << getOpenMPDirectiveName(ParentRegion);
4490 // Allow some constructs (except teams and cancellation constructs) to be
4491 // orphaned (they could be used in functions, called from OpenMP regions
4492 // with the required preconditions).
4493 if (ParentRegion == OMPD_unknown &&
4494 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4495 CurrentRegion != OMPD_cancellation_point &&
4496 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4498 if (CurrentRegion == OMPD_cancellation_point ||
4499 CurrentRegion == OMPD_cancel) {
4500 // OpenMP [2.16, Nesting of Regions]
4501 // A cancellation point construct for which construct-type-clause is
4502 // taskgroup must be nested inside a task construct. A cancellation
4503 // point construct for which construct-type-clause is not taskgroup must
4504 // be closely nested inside an OpenMP construct that matches the type
4505 // specified in construct-type-clause.
4506 // A cancel construct for which construct-type-clause is taskgroup must be
4507 // nested inside a task construct. A cancel construct for which
4508 // construct-type-clause is not taskgroup must be closely nested inside an
4509 // OpenMP construct that matches the type specified in
4510 // construct-type-clause.
4512 !((CancelRegion == OMPD_parallel &&
4513 (ParentRegion == OMPD_parallel ||
4514 ParentRegion == OMPD_target_parallel)) ||
4515 (CancelRegion == OMPD_for &&
4516 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4517 ParentRegion == OMPD_target_parallel_for ||
4518 ParentRegion == OMPD_distribute_parallel_for ||
4519 ParentRegion == OMPD_teams_distribute_parallel_for ||
4520 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4521 (CancelRegion == OMPD_taskgroup &&
4522 (ParentRegion == OMPD_task ||
4523 (SemaRef.getLangOpts().OpenMP >= 50 &&
4524 (ParentRegion == OMPD_taskloop ||
4525 ParentRegion == OMPD_master_taskloop ||
4526 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4527 (CancelRegion == OMPD_sections &&
4528 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4529 ParentRegion == OMPD_parallel_sections)));
4530 OrphanSeen = ParentRegion == OMPD_unknown;
4531 } else if (CurrentRegion == OMPD_master) {
4532 // OpenMP [2.16, Nesting of Regions]
4533 // A master region may not be closely nested inside a worksharing,
4534 // atomic, or explicit task region.
4535 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4536 isOpenMPTaskingDirective(ParentRegion);
4537 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4538 // OpenMP [2.16, Nesting of Regions]
4539 // A critical region may not be nested (closely or otherwise) inside a
4540 // critical region with the same name. Note that this restriction is not
4541 // sufficient to prevent deadlock.
4542 SourceLocation PreviousCriticalLoc;
4543 bool DeadLock = Stack->hasDirective(
4544 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4545 const DeclarationNameInfo &DNI,
4546 SourceLocation Loc) {
4547 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4548 PreviousCriticalLoc = Loc;
4553 false /* skip top directive */);
4555 SemaRef.Diag(StartLoc,
4556 diag::err_omp_prohibited_region_critical_same_name)
4557 << CurrentName.getName();
4558 if (PreviousCriticalLoc.isValid())
4559 SemaRef.Diag(PreviousCriticalLoc,
4560 diag::note_omp_previous_critical_region);
4563 } else if (CurrentRegion == OMPD_barrier) {
4564 // OpenMP [2.16, Nesting of Regions]
4565 // A barrier region may not be closely nested inside a worksharing,
4566 // explicit task, critical, ordered, atomic, or master region.
4567 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4568 isOpenMPTaskingDirective(ParentRegion) ||
4569 ParentRegion == OMPD_master ||
4570 ParentRegion == OMPD_parallel_master ||
4571 ParentRegion == OMPD_critical ||
4572 ParentRegion == OMPD_ordered;
4573 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4574 !isOpenMPParallelDirective(CurrentRegion) &&
4575 !isOpenMPTeamsDirective(CurrentRegion)) {
4576 // OpenMP [2.16, Nesting of Regions]
4577 // A worksharing region may not be closely nested inside a worksharing,
4578 // explicit task, critical, ordered, atomic, or master region.
4579 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4580 isOpenMPTaskingDirective(ParentRegion) ||
4581 ParentRegion == OMPD_master ||
4582 ParentRegion == OMPD_parallel_master ||
4583 ParentRegion == OMPD_critical ||
4584 ParentRegion == OMPD_ordered;
4585 Recommend = ShouldBeInParallelRegion;
4586 } else if (CurrentRegion == OMPD_ordered) {
4587 // OpenMP [2.16, Nesting of Regions]
4588 // An ordered region may not be closely nested inside a critical,
4589 // atomic, or explicit task region.
4590 // An ordered region must be closely nested inside a loop region (or
4591 // parallel loop region) with an ordered clause.
4592 // OpenMP [2.8.1,simd Construct, Restrictions]
4593 // An ordered construct with the simd clause is the only OpenMP construct
4594 // that can appear in the simd region.
4595 NestingProhibited = ParentRegion == OMPD_critical ||
4596 isOpenMPTaskingDirective(ParentRegion) ||
4597 !(isOpenMPSimdDirective(ParentRegion) ||
4598 Stack->isParentOrderedRegion());
4599 Recommend = ShouldBeInOrderedRegion;
4600 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4601 // OpenMP [2.16, Nesting of Regions]
4602 // If specified, a teams construct must be contained within a target
4605 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4606 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4607 ParentRegion != OMPD_target);
4608 OrphanSeen = ParentRegion == OMPD_unknown;
4609 Recommend = ShouldBeInTargetRegion;
4610 } else if (CurrentRegion == OMPD_scan) {
4611 // OpenMP [2.16, Nesting of Regions]
4612 // If specified, a teams construct must be contained within a target
4615 SemaRef.LangOpts.OpenMP < 50 ||
4616 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4617 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4618 ParentRegion != OMPD_parallel_for_simd);
4619 OrphanSeen = ParentRegion == OMPD_unknown;
4620 Recommend = ShouldBeInLoopSimdRegion;
4622 if (!NestingProhibited &&
4623 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4624 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4625 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4626 // OpenMP [2.16, Nesting of Regions]
4627 // distribute, parallel, parallel sections, parallel workshare, and the
4628 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4629 // constructs that can be closely nested in the teams region.
4630 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4631 !isOpenMPDistributeDirective(CurrentRegion);
4632 Recommend = ShouldBeInParallelRegion;
4634 if (!NestingProhibited &&
4635 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4636 // OpenMP 4.5 [2.17 Nesting of Regions]
4637 // The region associated with the distribute construct must be strictly
4638 // nested inside a teams region
4640 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4641 Recommend = ShouldBeInTeamsRegion;
4643 if (!NestingProhibited &&
4644 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4645 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4646 // OpenMP 4.5 [2.17 Nesting of Regions]
4647 // If a target, target update, target data, target enter data, or
4648 // target exit data construct is encountered during execution of a
4649 // target region, the behavior is unspecified.
4650 NestingProhibited = Stack->hasDirective(
4651 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4653 if (isOpenMPTargetExecutionDirective(K)) {
4654 OffendingRegion = K;
4659 false /* don't skip top directive */);
4660 CloseNesting = false;
4662 if (NestingProhibited) {
4664 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4665 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4667 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4668 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4669 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4677 struct Kind2Unsigned {
4678 using argument_type = OpenMPDirectiveKind;
4679 unsigned operator()(argument_type DK) { return unsigned(DK); }
4681 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4682 ArrayRef<OMPClause *> Clauses,
4683 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4684 bool ErrorFound = false;
4685 unsigned NamedModifiersNumber = 0;
4686 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4687 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4688 SmallVector<SourceLocation, 4> NameModifierLoc;
4689 for (const OMPClause *C : Clauses) {
4690 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4691 // At most one if clause without a directive-name-modifier can appear on
4693 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4694 if (FoundNameModifiers[CurNM]) {
4695 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4696 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4697 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4699 } else if (CurNM != OMPD_unknown) {
4700 NameModifierLoc.push_back(IC->getNameModifierLoc());
4701 ++NamedModifiersNumber;
4703 FoundNameModifiers[CurNM] = IC;
4704 if (CurNM == OMPD_unknown)
4706 // Check if the specified name modifier is allowed for the current
4708 // At most one if clause with the particular directive-name-modifier can
4709 // appear on the directive.
4710 bool MatchFound = false;
4711 for (auto NM : AllowedNameModifiers) {
4718 S.Diag(IC->getNameModifierLoc(),
4719 diag::err_omp_wrong_if_directive_name_modifier)
4720 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4725 // If any if clause on the directive includes a directive-name-modifier then
4726 // all if clauses on the directive must include a directive-name-modifier.
4727 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4728 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4729 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4730 diag::err_omp_no_more_if_clause);
4733 std::string Sep(", ");
4734 unsigned AllowedCnt = 0;
4735 unsigned TotalAllowedNum =
4736 AllowedNameModifiers.size() - NamedModifiersNumber;
4737 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4739 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4740 if (!FoundNameModifiers[NM]) {
4742 Values += getOpenMPDirectiveName(NM);
4744 if (AllowedCnt + 2 == TotalAllowedNum)
4746 else if (AllowedCnt + 1 != TotalAllowedNum)
4751 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4752 diag::err_omp_unnamed_if_clause)
4753 << (TotalAllowedNum > 1) << Values;
4755 for (SourceLocation Loc : NameModifierLoc) {
4756 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4763 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4764 SourceLocation &ELoc,
4765 SourceRange &ERange,
4766 bool AllowArraySection) {
4767 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4768 RefExpr->containsUnexpandedParameterPack())
4769 return std::make_pair(nullptr, true);
4771 // OpenMP [3.1, C/C++]
4772 // A list item is a variable name.
4773 // OpenMP [2.9.3.3, Restrictions, p.1]
4774 // A variable that is part of another variable (as an array or
4775 // structure element) cannot appear in a private clause.
4776 RefExpr = RefExpr->IgnoreParens();
4781 } IsArrayExpr = NoArrayExpr;
4782 if (AllowArraySection) {
4783 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4784 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4785 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4786 Base = TempASE->getBase()->IgnoreParenImpCasts();
4788 IsArrayExpr = ArraySubscript;
4789 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4790 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4791 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4792 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4793 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4794 Base = TempASE->getBase()->IgnoreParenImpCasts();
4796 IsArrayExpr = OMPArraySection;
4799 ELoc = RefExpr->getExprLoc();
4800 ERange = RefExpr->getSourceRange();
4801 RefExpr = RefExpr->IgnoreParenImpCasts();
4802 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4803 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4804 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4805 (S.getCurrentThisType().isNull() || !ME ||
4806 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4807 !isa<FieldDecl>(ME->getMemberDecl()))) {
4808 if (IsArrayExpr != NoArrayExpr) {
4809 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4814 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4815 : diag::err_omp_expected_var_name_member_expr)
4816 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4818 return std::make_pair(nullptr, false);
4820 return std::make_pair(
4821 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4825 /// Checks if the allocator is used in uses_allocators clause to be allowed in
4827 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4828 DSAStackTy *S = nullptr;
4831 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4832 return S->isUsesAllocatorsDecl(E->getDecl())
4834 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4835 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4837 bool VisitStmt(const Stmt *S) {
4838 for (const Stmt *Child : S->children()) {
4839 if (Child && Visit(Child))
4844 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4848 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4849 ArrayRef<OMPClause *> Clauses) {
4850 assert(!S.CurContext->isDependentContext() &&
4851 "Expected non-dependent context.");
4852 auto AllocateRange =
4853 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4854 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4856 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4857 return isOpenMPPrivate(C->getClauseKind());
4859 for (OMPClause *Cl : PrivateRange) {
4860 MutableArrayRef<Expr *>::iterator I, It, Et;
4861 if (Cl->getClauseKind() == OMPC_private) {
4862 auto *PC = cast<OMPPrivateClause>(Cl);
4863 I = PC->private_copies().begin();
4864 It = PC->varlist_begin();
4865 Et = PC->varlist_end();
4866 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4867 auto *PC = cast<OMPFirstprivateClause>(Cl);
4868 I = PC->private_copies().begin();
4869 It = PC->varlist_begin();
4870 Et = PC->varlist_end();
4871 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4872 auto *PC = cast<OMPLastprivateClause>(Cl);
4873 I = PC->private_copies().begin();
4874 It = PC->varlist_begin();
4875 Et = PC->varlist_end();
4876 } else if (Cl->getClauseKind() == OMPC_linear) {
4877 auto *PC = cast<OMPLinearClause>(Cl);
4878 I = PC->privates().begin();
4879 It = PC->varlist_begin();
4880 Et = PC->varlist_end();
4881 } else if (Cl->getClauseKind() == OMPC_reduction) {
4882 auto *PC = cast<OMPReductionClause>(Cl);
4883 I = PC->privates().begin();
4884 It = PC->varlist_begin();
4885 Et = PC->varlist_end();
4886 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4887 auto *PC = cast<OMPTaskReductionClause>(Cl);
4888 I = PC->privates().begin();
4889 It = PC->varlist_begin();
4890 Et = PC->varlist_end();
4891 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4892 auto *PC = cast<OMPInReductionClause>(Cl);
4893 I = PC->privates().begin();
4894 It = PC->varlist_begin();
4895 Et = PC->varlist_end();
4897 llvm_unreachable("Expected private clause.");
4899 for (Expr *E : llvm::make_range(It, Et)) {
4904 SourceLocation ELoc;
4906 Expr *SimpleRefExpr = E;
4907 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4908 /*AllowArraySection=*/true);
4909 DeclToCopy.try_emplace(Res.first,
4910 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4914 for (OMPClause *C : AllocateRange) {
4915 auto *AC = cast<OMPAllocateClause>(C);
4916 if (S.getLangOpts().OpenMP >= 50 &&
4917 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4918 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4919 AC->getAllocator()) {
4920 Expr *Allocator = AC->getAllocator();
4921 // OpenMP, 2.12.5 target Construct
4922 // Memory allocators that do not appear in a uses_allocators clause cannot
4923 // appear as an allocator in an allocate clause or be used in the target
4924 // region unless a requires directive with the dynamic_allocators clause
4925 // is present in the same compilation unit.
4926 AllocatorChecker Checker(Stack);
4927 if (Checker.Visit(Allocator))
4928 S.Diag(Allocator->getExprLoc(),
4929 diag::err_omp_allocator_not_in_uses_allocators)
4930 << Allocator->getSourceRange();
4932 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4933 getAllocatorKind(S, Stack, AC->getAllocator());
4934 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4935 // For task, taskloop or target directives, allocation requests to memory
4936 // allocators with the trait access set to thread result in unspecified
4938 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4939 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4940 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4941 S.Diag(AC->getAllocator()->getExprLoc(),
4942 diag::warn_omp_allocate_thread_on_task_target_directive)
4943 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4945 for (Expr *E : AC->varlists()) {
4946 SourceLocation ELoc;
4948 Expr *SimpleRefExpr = E;
4949 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4950 ValueDecl *VD = Res.first;
4951 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4952 if (!isOpenMPPrivate(Data.CKind)) {
4953 S.Diag(E->getExprLoc(),
4954 diag::err_omp_expected_private_copy_for_allocate);
4957 VarDecl *PrivateVD = DeclToCopy[VD];
4958 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4959 AllocatorKind, AC->getAllocator()))
4961 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4962 E->getSourceRange());
4967 StmtResult Sema::ActOnOpenMPExecutableDirective(
4968 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4969 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4970 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4971 StmtResult Res = StmtError();
4972 // First check CancelRegion which is then used in checkNestingOfRegions.
4973 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4974 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
4978 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4979 VarsWithInheritedDSAType VarsWithInheritedDSA;
4980 bool ErrorFound = false;
4981 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4982 if (AStmt && !CurContext->isDependentContext()) {
4983 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4985 // Check default data sharing attributes for referenced variables.
4986 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
4987 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4989 while (--ThisCaptureLevel >= 0)
4990 S = cast<CapturedStmt>(S)->getCapturedStmt();
4991 DSAChecker.Visit(S);
4992 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4993 !isOpenMPTaskingDirective(Kind)) {
4994 // Visit subcaptures to generate implicit clauses for captured vars.
4995 auto *CS = cast<CapturedStmt>(AStmt);
4996 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4997 getOpenMPCaptureRegions(CaptureRegions, Kind);
4998 // Ignore outer tasking regions for target directives.
4999 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5000 CS = cast<CapturedStmt>(CS->getCapturedStmt());
5001 DSAChecker.visitSubCaptures(CS);
5003 if (DSAChecker.isErrorFound())
5005 // Generate list of implicitly defined firstprivate variables.
5006 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5008 SmallVector<Expr *, 4> ImplicitFirstprivates(
5009 DSAChecker.getImplicitFirstprivate().begin(),
5010 DSAChecker.getImplicitFirstprivate().end());
5011 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5012 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5013 ArrayRef<Expr *> ImplicitMap =
5014 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5015 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5017 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5018 for (OMPClause *C : Clauses) {
5019 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5020 for (Expr *E : IRC->taskgroup_descriptors())
5022 ImplicitFirstprivates.emplace_back(E);
5024 // OpenMP 5.0, 2.10.1 task Construct
5025 // [detach clause]... The event-handle will be considered as if it was
5026 // specified on a firstprivate clause.
5027 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5028 ImplicitFirstprivates.push_back(DC->getEventHandler());
5030 if (!ImplicitFirstprivates.empty()) {
5031 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5032 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5033 SourceLocation())) {
5034 ClausesWithImplicit.push_back(Implicit);
5035 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5036 ImplicitFirstprivates.size();
5041 int ClauseKindCnt = -1;
5042 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5044 if (ImplicitMap.empty())
5046 CXXScopeSpec MapperIdScopeSpec;
5047 DeclarationNameInfo MapperId;
5048 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5049 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5050 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5051 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5052 ImplicitMap, OMPVarListLocTy())) {
5053 ClausesWithImplicit.emplace_back(Implicit);
5055 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5062 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5065 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5067 AllowedNameModifiers.push_back(OMPD_parallel);
5070 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5071 VarsWithInheritedDSA);
5072 if (LangOpts.OpenMP >= 50)
5073 AllowedNameModifiers.push_back(OMPD_simd);
5076 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5077 VarsWithInheritedDSA);
5080 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5081 EndLoc, VarsWithInheritedDSA);
5082 if (LangOpts.OpenMP >= 50)
5083 AllowedNameModifiers.push_back(OMPD_simd);
5086 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5090 assert(ClausesWithImplicit.empty() &&
5091 "No clauses are allowed for 'omp section' directive");
5092 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5095 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5099 assert(ClausesWithImplicit.empty() &&
5100 "No clauses are allowed for 'omp master' directive");
5101 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5104 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5107 case OMPD_parallel_for:
5108 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5109 EndLoc, VarsWithInheritedDSA);
5110 AllowedNameModifiers.push_back(OMPD_parallel);
5112 case OMPD_parallel_for_simd:
5113 Res = ActOnOpenMPParallelForSimdDirective(
5114 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5115 AllowedNameModifiers.push_back(OMPD_parallel);
5116 if (LangOpts.OpenMP >= 50)
5117 AllowedNameModifiers.push_back(OMPD_simd);
5119 case OMPD_parallel_master:
5120 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5122 AllowedNameModifiers.push_back(OMPD_parallel);
5124 case OMPD_parallel_sections:
5125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5127 AllowedNameModifiers.push_back(OMPD_parallel);
5131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5132 AllowedNameModifiers.push_back(OMPD_task);
5134 case OMPD_taskyield:
5135 assert(ClausesWithImplicit.empty() &&
5136 "No clauses are allowed for 'omp taskyield' directive");
5137 assert(AStmt == nullptr &&
5138 "No associated statement allowed for 'omp taskyield' directive");
5139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5142 assert(ClausesWithImplicit.empty() &&
5143 "No clauses are allowed for 'omp barrier' directive");
5144 assert(AStmt == nullptr &&
5145 "No associated statement allowed for 'omp barrier' directive");
5146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5149 assert(ClausesWithImplicit.empty() &&
5150 "No clauses are allowed for 'omp taskwait' directive");
5151 assert(AStmt == nullptr &&
5152 "No associated statement allowed for 'omp taskwait' directive");
5153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5155 case OMPD_taskgroup:
5156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5160 assert(AStmt == nullptr &&
5161 "No associated statement allowed for 'omp flush' directive");
5162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5165 assert(AStmt == nullptr &&
5166 "No associated statement allowed for 'omp depobj' directive");
5167 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5170 assert(AStmt == nullptr &&
5171 "No associated statement allowed for 'omp scan' directive");
5172 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5175 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5179 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5184 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5187 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5189 AllowedNameModifiers.push_back(OMPD_target);
5191 case OMPD_target_parallel:
5192 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5194 AllowedNameModifiers.push_back(OMPD_target);
5195 AllowedNameModifiers.push_back(OMPD_parallel);
5197 case OMPD_target_parallel_for:
5198 Res = ActOnOpenMPTargetParallelForDirective(
5199 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5200 AllowedNameModifiers.push_back(OMPD_target);
5201 AllowedNameModifiers.push_back(OMPD_parallel);
5203 case OMPD_cancellation_point:
5204 assert(ClausesWithImplicit.empty() &&
5205 "No clauses are allowed for 'omp cancellation point' directive");
5206 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5207 "cancellation point' directive");
5208 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5211 assert(AStmt == nullptr &&
5212 "No associated statement allowed for 'omp cancel' directive");
5213 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5215 AllowedNameModifiers.push_back(OMPD_cancel);
5217 case OMPD_target_data:
5218 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5220 AllowedNameModifiers.push_back(OMPD_target_data);
5222 case OMPD_target_enter_data:
5223 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5225 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5227 case OMPD_target_exit_data:
5228 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5230 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5233 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5234 EndLoc, VarsWithInheritedDSA);
5235 AllowedNameModifiers.push_back(OMPD_taskloop);
5237 case OMPD_taskloop_simd:
5238 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5239 EndLoc, VarsWithInheritedDSA);
5240 AllowedNameModifiers.push_back(OMPD_taskloop);
5241 if (LangOpts.OpenMP >= 50)
5242 AllowedNameModifiers.push_back(OMPD_simd);
5244 case OMPD_master_taskloop:
5245 Res = ActOnOpenMPMasterTaskLoopDirective(
5246 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5247 AllowedNameModifiers.push_back(OMPD_taskloop);
5249 case OMPD_master_taskloop_simd:
5250 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5252 AllowedNameModifiers.push_back(OMPD_taskloop);
5253 if (LangOpts.OpenMP >= 50)
5254 AllowedNameModifiers.push_back(OMPD_simd);
5256 case OMPD_parallel_master_taskloop:
5257 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5259 AllowedNameModifiers.push_back(OMPD_taskloop);
5260 AllowedNameModifiers.push_back(OMPD_parallel);
5262 case OMPD_parallel_master_taskloop_simd:
5263 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5264 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5265 AllowedNameModifiers.push_back(OMPD_taskloop);
5266 AllowedNameModifiers.push_back(OMPD_parallel);
5267 if (LangOpts.OpenMP >= 50)
5268 AllowedNameModifiers.push_back(OMPD_simd);
5270 case OMPD_distribute:
5271 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5272 EndLoc, VarsWithInheritedDSA);
5274 case OMPD_target_update:
5275 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5277 AllowedNameModifiers.push_back(OMPD_target_update);
5279 case OMPD_distribute_parallel_for:
5280 Res = ActOnOpenMPDistributeParallelForDirective(
5281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5282 AllowedNameModifiers.push_back(OMPD_parallel);
5284 case OMPD_distribute_parallel_for_simd:
5285 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5286 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5287 AllowedNameModifiers.push_back(OMPD_parallel);
5288 if (LangOpts.OpenMP >= 50)
5289 AllowedNameModifiers.push_back(OMPD_simd);
5291 case OMPD_distribute_simd:
5292 Res = ActOnOpenMPDistributeSimdDirective(
5293 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5294 if (LangOpts.OpenMP >= 50)
5295 AllowedNameModifiers.push_back(OMPD_simd);
5297 case OMPD_target_parallel_for_simd:
5298 Res = ActOnOpenMPTargetParallelForSimdDirective(
5299 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5300 AllowedNameModifiers.push_back(OMPD_target);
5301 AllowedNameModifiers.push_back(OMPD_parallel);
5302 if (LangOpts.OpenMP >= 50)
5303 AllowedNameModifiers.push_back(OMPD_simd);
5305 case OMPD_target_simd:
5306 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5307 EndLoc, VarsWithInheritedDSA);
5308 AllowedNameModifiers.push_back(OMPD_target);
5309 if (LangOpts.OpenMP >= 50)
5310 AllowedNameModifiers.push_back(OMPD_simd);
5312 case OMPD_teams_distribute:
5313 Res = ActOnOpenMPTeamsDistributeDirective(
5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5316 case OMPD_teams_distribute_simd:
5317 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5318 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5319 if (LangOpts.OpenMP >= 50)
5320 AllowedNameModifiers.push_back(OMPD_simd);
5322 case OMPD_teams_distribute_parallel_for_simd:
5323 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5324 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5325 AllowedNameModifiers.push_back(OMPD_parallel);
5326 if (LangOpts.OpenMP >= 50)
5327 AllowedNameModifiers.push_back(OMPD_simd);
5329 case OMPD_teams_distribute_parallel_for:
5330 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5332 AllowedNameModifiers.push_back(OMPD_parallel);
5334 case OMPD_target_teams:
5335 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5337 AllowedNameModifiers.push_back(OMPD_target);
5339 case OMPD_target_teams_distribute:
5340 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5341 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5342 AllowedNameModifiers.push_back(OMPD_target);
5344 case OMPD_target_teams_distribute_parallel_for:
5345 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5346 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5347 AllowedNameModifiers.push_back(OMPD_target);
5348 AllowedNameModifiers.push_back(OMPD_parallel);
5350 case OMPD_target_teams_distribute_parallel_for_simd:
5351 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5352 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5353 AllowedNameModifiers.push_back(OMPD_target);
5354 AllowedNameModifiers.push_back(OMPD_parallel);
5355 if (LangOpts.OpenMP >= 50)
5356 AllowedNameModifiers.push_back(OMPD_simd);
5358 case OMPD_target_teams_distribute_simd:
5359 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5361 AllowedNameModifiers.push_back(OMPD_target);
5362 if (LangOpts.OpenMP >= 50)
5363 AllowedNameModifiers.push_back(OMPD_simd);
5365 case OMPD_declare_target:
5366 case OMPD_end_declare_target:
5367 case OMPD_threadprivate:
5369 case OMPD_declare_reduction:
5370 case OMPD_declare_mapper:
5371 case OMPD_declare_simd:
5373 case OMPD_declare_variant:
5374 case OMPD_begin_declare_variant:
5375 case OMPD_end_declare_variant:
5376 llvm_unreachable("OpenMP Directive is not allowed");
5379 llvm_unreachable("Unknown OpenMP directive");
5382 ErrorFound = Res.isInvalid() || ErrorFound;
5384 // Check variables in the clauses if default(none) or
5385 // default(firstprivate) was specified.
5386 if (DSAStack->getDefaultDSA() == DSA_none ||
5387 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5388 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5389 for (OMPClause *C : Clauses) {
5390 switch (C->getClauseKind()) {
5391 case OMPC_num_threads:
5392 case OMPC_dist_schedule:
5393 // Do not analyse if no parent teams directive.
5394 if (isOpenMPTeamsDirective(Kind))
5398 if (isOpenMPTeamsDirective(Kind) &&
5399 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5401 if (isOpenMPParallelDirective(Kind) &&
5402 isOpenMPTaskLoopDirective(Kind) &&
5403 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5409 case OMPC_grainsize:
5410 case OMPC_num_tasks:
5413 // Do not analyze if no parent parallel directive.
5414 if (isOpenMPParallelDirective(Kind))
5419 case OMPC_num_teams:
5420 case OMPC_thread_limit:
5426 case OMPC_proc_bind:
5428 case OMPC_firstprivate:
5429 case OMPC_lastprivate:
5431 case OMPC_reduction:
5432 case OMPC_task_reduction:
5433 case OMPC_in_reduction:
5437 case OMPC_copyprivate:
5440 case OMPC_mergeable:
5456 case OMPC_defaultmap:
5459 case OMPC_use_device_ptr:
5460 case OMPC_use_device_addr:
5461 case OMPC_is_device_ptr:
5462 case OMPC_nontemporal:
5465 case OMPC_inclusive:
5466 case OMPC_exclusive:
5467 case OMPC_uses_allocators:
5470 case OMPC_allocator:
5473 case OMPC_threadprivate:
5476 case OMPC_unified_address:
5477 case OMPC_unified_shared_memory:
5478 case OMPC_reverse_offload:
5479 case OMPC_dynamic_allocators:
5480 case OMPC_atomic_default_mem_order:
5481 case OMPC_device_type:
5484 llvm_unreachable("Unexpected clause");
5486 for (Stmt *CC : C->children()) {
5488 DSAChecker.Visit(CC);
5491 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5492 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5494 for (const auto &P : VarsWithInheritedDSA) {
5495 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5498 if (DSAStack->getDefaultDSA() == DSA_none ||
5499 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5500 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5501 << P.first << P.second->getSourceRange();
5502 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5503 } else if (getLangOpts().OpenMP >= 50) {
5504 Diag(P.second->getExprLoc(),
5505 diag::err_omp_defaultmap_no_attr_for_variable)
5506 << P.first << P.second->getSourceRange();
5507 Diag(DSAStack->getDefaultDSALocation(),
5508 diag::note_omp_defaultmap_attr_none);
5512 if (!AllowedNameModifiers.empty())
5513 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5519 if (!CurContext->isDependentContext() &&
5520 isOpenMPTargetExecutionDirective(Kind) &&
5521 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5522 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5523 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5524 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5525 // Register target to DSA Stack.
5526 DSAStack->addTargetDirLocation(StartLoc);
5532 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5533 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5534 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5535 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5536 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5537 assert(Aligneds.size() == Alignments.size());
5538 assert(Linears.size() == LinModifiers.size());
5539 assert(Linears.size() == Steps.size());
5540 if (!DG || DG.get().isNull())
5541 return DeclGroupPtrTy();
5543 const int SimdId = 0;
5544 if (!DG.get().isSingleDecl()) {
5545 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5549 Decl *ADecl = DG.get().getSingleDecl();
5550 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5551 ADecl = FTD->getTemplatedDecl();
5553 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5555 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5556 return DeclGroupPtrTy();
5559 // OpenMP [2.8.2, declare simd construct, Description]
5560 // The parameter of the simdlen clause must be a constant positive integer
5564 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5565 // OpenMP [2.8.2, declare simd construct, Description]
5566 // The special this pointer can be used as if was one of the arguments to the
5567 // function in any of the linear, aligned, or uniform clauses.
5568 // The uniform clause declares one or more arguments to have an invariant
5569 // value for all concurrent invocations of the function in the execution of a
5570 // single SIMD loop.
5571 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5572 const Expr *UniformedLinearThis = nullptr;
5573 for (const Expr *E : Uniforms) {
5574 E = E->IgnoreParenImpCasts();
5575 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5576 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5577 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5578 FD->getParamDecl(PVD->getFunctionScopeIndex())
5579 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5580 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5583 if (isa<CXXThisExpr>(E)) {
5584 UniformedLinearThis = E;
5587 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5588 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5590 // OpenMP [2.8.2, declare simd construct, Description]
5591 // The aligned clause declares that the object to which each list item points
5592 // is aligned to the number of bytes expressed in the optional parameter of
5593 // the aligned clause.
5594 // The special this pointer can be used as if was one of the arguments to the
5595 // function in any of the linear, aligned, or uniform clauses.
5596 // The type of list items appearing in the aligned clause must be array,
5597 // pointer, reference to array, or reference to pointer.
5598 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5599 const Expr *AlignedThis = nullptr;
5600 for (const Expr *E : Aligneds) {
5601 E = E->IgnoreParenImpCasts();
5602 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5603 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5604 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5605 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5606 FD->getParamDecl(PVD->getFunctionScopeIndex())
5607 ->getCanonicalDecl() == CanonPVD) {
5608 // OpenMP [2.8.1, simd construct, Restrictions]
5609 // A list-item cannot appear in more than one aligned clause.
5610 if (AlignedArgs.count(CanonPVD) > 0) {
5611 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5612 << 1 << getOpenMPClauseName(OMPC_aligned)
5613 << E->getSourceRange();
5614 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5615 diag::note_omp_explicit_dsa)
5616 << getOpenMPClauseName(OMPC_aligned);
5619 AlignedArgs[CanonPVD] = E;
5620 QualType QTy = PVD->getType()
5621 .getNonReferenceType()
5622 .getUnqualifiedType()
5623 .getCanonicalType();
5624 const Type *Ty = QTy.getTypePtrOrNull();
5625 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5626 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5627 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5628 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5633 if (isa<CXXThisExpr>(E)) {
5635 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5636 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5637 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5638 << getOpenMPClauseName(OMPC_aligned);
5643 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5644 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5646 // The optional parameter of the aligned clause, alignment, must be a constant
5647 // positive integer expression. If no optional parameter is specified,
5648 // implementation-defined default alignments for SIMD instructions on the
5649 // target platforms are assumed.
5650 SmallVector<const Expr *, 4> NewAligns;
5651 for (Expr *E : Alignments) {
5654 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5655 NewAligns.push_back(Align.get());
5657 // OpenMP [2.8.2, declare simd construct, Description]
5658 // The linear clause declares one or more list items to be private to a SIMD
5659 // lane and to have a linear relationship with respect to the iteration space
5661 // The special this pointer can be used as if was one of the arguments to the
5662 // function in any of the linear, aligned, or uniform clauses.
5663 // When a linear-step expression is specified in a linear clause it must be
5664 // either a constant integer expression or an integer-typed parameter that is
5665 // specified in a uniform clause on the directive.
5666 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5667 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5668 auto MI = LinModifiers.begin();
5669 for (const Expr *E : Linears) {
5670 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5672 E = E->IgnoreParenImpCasts();
5673 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5674 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5675 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5676 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5677 FD->getParamDecl(PVD->getFunctionScopeIndex())
5678 ->getCanonicalDecl() == CanonPVD) {
5679 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5680 // A list-item cannot appear in more than one linear clause.
5681 if (LinearArgs.count(CanonPVD) > 0) {
5682 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5683 << getOpenMPClauseName(OMPC_linear)
5684 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5685 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5686 diag::note_omp_explicit_dsa)
5687 << getOpenMPClauseName(OMPC_linear);
5690 // Each argument can appear in at most one uniform or linear clause.
5691 if (UniformedArgs.count(CanonPVD) > 0) {
5692 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5693 << getOpenMPClauseName(OMPC_linear)
5694 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5695 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5696 diag::note_omp_explicit_dsa)
5697 << getOpenMPClauseName(OMPC_uniform);
5700 LinearArgs[CanonPVD] = E;
5701 if (E->isValueDependent() || E->isTypeDependent() ||
5702 E->isInstantiationDependent() ||
5703 E->containsUnexpandedParameterPack())
5705 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5706 PVD->getOriginalType(),
5707 /*IsDeclareSimd=*/true);
5711 if (isa<CXXThisExpr>(E)) {
5712 if (UniformedLinearThis) {
5713 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5714 << getOpenMPClauseName(OMPC_linear)
5715 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5716 << E->getSourceRange();
5717 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5718 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5722 UniformedLinearThis = E;
5723 if (E->isValueDependent() || E->isTypeDependent() ||
5724 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5726 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5727 E->getType(), /*IsDeclareSimd=*/true);
5730 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5731 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5733 Expr *Step = nullptr;
5734 Expr *NewStep = nullptr;
5735 SmallVector<Expr *, 4> NewSteps;
5736 for (Expr *E : Steps) {
5737 // Skip the same step expression, it was checked already.
5738 if (Step == E || !E) {
5739 NewSteps.push_back(E ? NewStep : nullptr);
5743 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5744 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5745 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5746 if (UniformedArgs.count(CanonPVD) == 0) {
5747 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5748 << Step->getSourceRange();
5749 } else if (E->isValueDependent() || E->isTypeDependent() ||
5750 E->isInstantiationDependent() ||
5751 E->containsUnexpandedParameterPack() ||
5752 CanonPVD->getType()->hasIntegerRepresentation()) {
5753 NewSteps.push_back(Step);
5755 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5756 << Step->getSourceRange();
5761 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5762 !Step->isInstantiationDependent() &&
5763 !Step->containsUnexpandedParameterPack()) {
5764 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5767 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5769 NewSteps.push_back(NewStep);
5771 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5772 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5773 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5774 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5775 const_cast<Expr **>(Linears.data()), Linears.size(),
5776 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5777 NewSteps.data(), NewSteps.size(), SR);
5778 ADecl->addAttr(NewAttr);
5782 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5784 assert(NewType->isFunctionProtoType() &&
5785 "Expected function type with prototype.");
5786 assert(FD->getType()->isFunctionNoProtoType() &&
5787 "Expected function with type with no prototype.");
5788 assert(FDWithProto->getType()->isFunctionProtoType() &&
5789 "Expected function with prototype.");
5790 // Synthesize parameters with the same types.
5791 FD->setType(NewType);
5792 SmallVector<ParmVarDecl *, 16> Params;
5793 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5794 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5795 SourceLocation(), nullptr, P->getType(),
5796 /*TInfo=*/nullptr, SC_None, nullptr);
5797 Param->setScopeInfo(0, Params.size());
5798 Param->setImplicit();
5799 Params.push_back(Param);
5802 FD->setParams(Params);
5805 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5806 : TI(&TI), NameSuffix(TI.getMangledName()) {}
5809 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
5811 IdentifierInfo *BaseII = D.getIdentifier();
5812 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5813 LookupOrdinaryName);
5814 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5816 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5817 QualType FType = TInfo->getType();
5819 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr;
5820 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval;
5822 FunctionDecl *BaseFD = nullptr;
5823 for (auto *Candidate : Lookup) {
5824 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl());
5828 // Don't specialize constexpr/consteval functions with
5829 // non-constexpr/consteval functions.
5830 if (UDecl->isConstexpr() && !IsConstexpr)
5832 if (UDecl->isConsteval() && !IsConsteval)
5835 QualType NewType = Context.mergeFunctionTypes(
5836 FType, UDecl->getType(), /* OfBlockPointer */ false,
5837 /* Unqualified */ false, /* AllowCXX */ true);
5838 if (NewType.isNull())
5846 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D));
5847 BaseFD->setImplicit(true);
5850 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5851 std::string MangledName;
5852 MangledName += D.getIdentifier()->getName();
5853 MangledName += getOpenMPVariantManglingSeparatorStr();
5854 MangledName += DVScope.NameSuffix;
5855 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5857 VariantII.setMangledOpenMPVariantName(true);
5858 D.SetIdentifier(&VariantII, D.getBeginLoc());
5862 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5863 FunctionDecl *FD, FunctionDecl *BaseFD) {
5864 // Do not mark function as is used to prevent its emission if this is the
5865 // only place where it is used.
5866 EnterExpressionEvaluationContext Unevaluated(
5867 *this, Sema::ExpressionEvaluationContext::Unevaluated);
5869 Expr *VariantFuncRef = DeclRefExpr::Create(
5870 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5871 /* RefersToEnclosingVariableOrCapture */ false,
5872 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5874 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5875 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5876 Context, VariantFuncRef, DVScope.TI);
5877 BaseFD->addAttr(OMPDeclareVariantA);
5880 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5881 SourceLocation LParenLoc,
5882 MultiExprArg ArgExprs,
5883 SourceLocation RParenLoc, Expr *ExecConfig) {
5884 // The common case is a regular call we do not want to specialize at all. Try
5885 // to make that case fast by bailing early.
5886 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
5890 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
5894 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
5897 ASTContext &Context = getASTContext();
5898 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice,
5899 Context.getTargetInfo().getTriple());
5901 SmallVector<Expr *, 4> Exprs;
5902 SmallVector<VariantMatchInfo, 4> VMIs;
5903 while (CalleeFnDecl) {
5904 for (OMPDeclareVariantAttr *A :
5905 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
5906 Expr *VariantRef = A->getVariantFuncRef();
5908 VariantMatchInfo VMI;
5909 OMPTraitInfo &TI = A->getTraitInfo();
5910 TI.getAsVariantMatchInfo(Context, VMI);
5911 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false))
5914 VMIs.push_back(VMI);
5915 Exprs.push_back(VariantRef);
5918 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
5923 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
5926 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
5927 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
5930 // Try to build a (member) call expression for the current best applicable
5931 // variant expression. We allow this to fail in which case we continue
5932 // with the next best variant expression. The fail case is part of the
5933 // implementation defined behavior in the OpenMP standard when it talks
5934 // about what differences in the function prototypes: "Any differences
5935 // that the specific OpenMP context requires in the prototype of the
5936 // variant from the base function prototype are implementation defined."
5937 // This wording is there to allow the specialized variant to have a
5938 // different type than the base function. This is intended and OK but if
5939 // we cannot create a call the difference is not in the "implementation
5940 // defined range" we allow.
5941 Sema::TentativeAnalysisScope Trap(*this);
5943 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
5944 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
5945 BestExpr = MemberExpr::CreateImplicit(
5946 Context, MemberCall->getImplicitObjectArgument(),
5947 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
5948 MemberCall->getValueKind(), MemberCall->getObjectKind());
5950 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
5952 if (NewCall.isUsable())
5956 VMIs.erase(VMIs.begin() + BestIdx);
5957 Exprs.erase(Exprs.begin() + BestIdx);
5958 } while (!VMIs.empty());
5960 if (!NewCall.isUsable())
5962 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
5965 Optional<std::pair<FunctionDecl *, Expr *>>
5966 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
5967 Expr *VariantRef, OMPTraitInfo &TI,
5969 if (!DG || DG.get().isNull())
5972 const int VariantId = 1;
5973 // Must be applied only to single decl.
5974 if (!DG.get().isSingleDecl()) {
5975 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5979 Decl *ADecl = DG.get().getSingleDecl();
5980 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5981 ADecl = FTD->getTemplatedDecl();
5983 // Decl must be a function.
5984 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5986 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5991 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
5992 return FD->hasAttrs() &&
5993 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5994 FD->hasAttr<TargetAttr>());
5996 // OpenMP is not compatible with CPU-specific attributes.
5997 if (HasMultiVersionAttributes(FD)) {
5998 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6003 // Allow #pragma omp declare variant only if the function is not used.
6004 if (FD->isUsed(false))
6005 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6006 << FD->getLocation();
6008 // Check if the function was emitted already.
6009 const FunctionDecl *Definition;
6010 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6011 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6012 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6013 << FD->getLocation();
6015 // The VariantRef must point to function.
6017 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6021 auto ShouldDelayChecks = [](Expr *&E, bool) {
6022 return E && (E->isTypeDependent() || E->isValueDependent() ||
6023 E->containsUnexpandedParameterPack() ||
6024 E->isInstantiationDependent());
6026 // Do not check templates, wait until instantiation.
6027 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6028 TI.anyScoreOrCondition(ShouldDelayChecks))
6029 return std::make_pair(FD, VariantRef);
6031 // Deal with non-constant score and user condition expressions.
6032 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6033 bool IsScore) -> bool {
6034 llvm::APSInt Result;
6035 if (!E || E->isIntegerConstantExpr(Result, Context))
6039 // We warn on non-constant scores and pretend they were not present.
6040 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6044 // We could replace a non-constant user condition with "false" but we
6045 // will soon need to handle these anyway for the dynamic version of
6046 // OpenMP context selectors.
6047 Diag(E->getExprLoc(),
6048 diag::err_omp_declare_variant_user_condition_not_constant)
6053 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6056 // Convert VariantRef expression to the type of the original function to
6057 // resolve possible conflicts.
6058 ExprResult VariantRefCast;
6059 if (LangOpts.CPlusPlus) {
6061 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6062 if (Method && !Method->isStatic()) {
6063 const Type *ClassType =
6064 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6065 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6068 // Build adrr_of unary op to correctly handle type checks for member
6070 Sema::TentativeAnalysisScope Trap(*this);
6071 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6074 if (!ER.isUsable()) {
6075 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6076 << VariantId << VariantRef->getSourceRange();
6079 VariantRef = ER.get();
6081 FnPtrType = Context.getPointerType(FD->getType());
6083 ImplicitConversionSequence ICS =
6084 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
6085 /*SuppressUserConversions=*/false,
6086 AllowedExplicit::None,
6087 /*InOverloadResolution=*/false,
6089 /*AllowObjCWritebackConversion=*/false);
6090 if (ICS.isFailure()) {
6091 Diag(VariantRef->getExprLoc(),
6092 diag::err_omp_declare_variant_incompat_types)
6093 << VariantRef->getType()
6094 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6095 << VariantRef->getSourceRange();
6098 VariantRefCast = PerformImplicitConversion(
6099 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6100 if (!VariantRefCast.isUsable())
6102 // Drop previously built artificial addr_of unary op for member functions.
6103 if (Method && !Method->isStatic()) {
6104 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6105 if (auto *UO = dyn_cast<UnaryOperator>(
6106 PossibleAddrOfVariantRef->IgnoreImplicit()))
6107 VariantRefCast = UO->getSubExpr();
6110 VariantRefCast = VariantRef;
6113 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6114 if (!ER.isUsable() ||
6115 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6116 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6117 << VariantId << VariantRef->getSourceRange();
6121 // The VariantRef must point to function.
6122 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6124 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6125 << VariantId << VariantRef->getSourceRange();
6128 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6130 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6131 << VariantId << VariantRef->getSourceRange();
6135 // Check if function types are compatible in C.
6136 if (!LangOpts.CPlusPlus) {
6138 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6139 if (NewType.isNull()) {
6140 Diag(VariantRef->getExprLoc(),
6141 diag::err_omp_declare_variant_incompat_types)
6142 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6145 if (NewType->isFunctionProtoType()) {
6146 if (FD->getType()->isFunctionNoProtoType())
6147 setPrototype(*this, FD, NewFD, NewType);
6148 else if (NewFD->getType()->isFunctionNoProtoType())
6149 setPrototype(*this, NewFD, FD, NewType);
6153 // Check if variant function is not marked with declare variant directive.
6154 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6155 Diag(VariantRef->getExprLoc(),
6156 diag::warn_omp_declare_variant_marked_as_declare_variant)
6157 << VariantRef->getSourceRange();
6159 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6160 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6164 enum DoesntSupport {
6173 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6174 if (CXXFD->isVirtual()) {
6175 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6180 if (isa<CXXConstructorDecl>(FD)) {
6181 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6186 if (isa<CXXDestructorDecl>(FD)) {
6187 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6193 if (FD->isDeleted()) {
6194 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6199 if (FD->isDefaulted()) {
6200 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6205 if (FD->isConstexpr()) {
6206 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6207 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6211 // Check general compatibility.
6212 if (areMultiversionVariantFunctionsCompatible(
6213 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6214 PartialDiagnosticAt(SourceLocation(),
6215 PartialDiagnostic::NullDiagnostic()),
6216 PartialDiagnosticAt(
6217 VariantRef->getExprLoc(),
6218 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6219 PartialDiagnosticAt(VariantRef->getExprLoc(),
6220 PDiag(diag::err_omp_declare_variant_diff)
6221 << FD->getLocation()),
6222 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6223 /*CLinkageMayDiffer=*/true))
6225 return std::make_pair(FD, cast<Expr>(DRE));
6228 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6233 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6234 FD->addAttr(NewAttr);
6237 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6239 SourceLocation StartLoc,
6240 SourceLocation EndLoc) {
6244 auto *CS = cast<CapturedStmt>(AStmt);
6245 // 1.2.2 OpenMP Language Terminology
6246 // Structured block - An executable statement with a single entry at the
6247 // top and a single exit at the bottom.
6248 // The point of exit cannot be a branch out of the structured block.
6249 // longjmp() and throw() must not violate the entry/exit criteria.
6250 CS->getCapturedDecl()->setNothrow();
6252 setFunctionHasBranchProtectedScope();
6254 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6255 DSAStack->getTaskgroupReductionRef(),
6256 DSAStack->isCancelRegion());
6260 /// Iteration space of a single for loop.
6261 struct LoopIterationSpace final {
6262 /// True if the condition operator is the strict compare operator (<, > or
6264 bool IsStrictCompare = false;
6265 /// Condition of the loop.
6266 Expr *PreCond = nullptr;
6267 /// This expression calculates the number of iterations in the loop.
6268 /// It is always possible to calculate it before starting the loop.
6269 Expr *NumIterations = nullptr;
6270 /// The loop counter variable.
6271 Expr *CounterVar = nullptr;
6272 /// Private loop counter variable.
6273 Expr *PrivateCounterVar = nullptr;
6274 /// This is initializer for the initial value of #CounterVar.
6275 Expr *CounterInit = nullptr;
6276 /// This is step for the #CounterVar used to generate its update:
6277 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6278 Expr *CounterStep = nullptr;
6279 /// Should step be subtracted?
6280 bool Subtract = false;
6281 /// Source range of the loop init.
6282 SourceRange InitSrcRange;
6283 /// Source range of the loop condition.
6284 SourceRange CondSrcRange;
6285 /// Source range of the loop increment.
6286 SourceRange IncSrcRange;
6287 /// Minimum value that can have the loop control variable. Used to support
6288 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6289 /// since only such variables can be used in non-loop invariant expressions.
6290 Expr *MinValue = nullptr;
6291 /// Maximum value that can have the loop control variable. Used to support
6292 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6293 /// since only such variables can be used in non-loop invariant expressions.
6294 Expr *MaxValue = nullptr;
6295 /// true, if the lower bound depends on the outer loop control var.
6296 bool IsNonRectangularLB = false;
6297 /// true, if the upper bound depends on the outer loop control var.
6298 bool IsNonRectangularUB = false;
6299 /// Index of the loop this loop depends on and forms non-rectangular loop
6301 unsigned LoopDependentIdx = 0;
6302 /// Final condition for the non-rectangular loop nest support. It is used to
6303 /// check that the number of iterations for this particular counter must be
6305 Expr *FinalCondition = nullptr;
6308 /// Helper class for checking canonical form of the OpenMP loops and
6309 /// extracting iteration space of each loop in the loop nest, that will be used
6310 /// for IR generation.
6311 class OpenMPIterationSpaceChecker {
6312 /// Reference to Sema.
6314 /// Data-sharing stack.
6316 /// A location for diagnostics (when there is no some better location).
6317 SourceLocation DefaultLoc;
6318 /// A location for diagnostics (when increment is not compatible).
6319 SourceLocation ConditionLoc;
6320 /// A source location for referring to loop init later.
6321 SourceRange InitSrcRange;
6322 /// A source location for referring to condition later.
6323 SourceRange ConditionSrcRange;
6324 /// A source location for referring to increment later.
6325 SourceRange IncrementSrcRange;
6327 ValueDecl *LCDecl = nullptr;
6328 /// Reference to loop variable.
6329 Expr *LCRef = nullptr;
6330 /// Lower bound (initializer for the var).
6334 /// Loop step (increment).
6335 Expr *Step = nullptr;
6336 /// This flag is true when condition is one of:
6341 /// This will have no value when the condition is !=
6342 llvm::Optional<bool> TestIsLessOp;
6343 /// This flag is true when condition is strict ( < or > ).
6344 bool TestIsStrictOp = false;
6345 /// This flag is true when step is subtracted on each iteration.
6346 bool SubtractStep = false;
6347 /// The outer loop counter this loop depends on (if any).
6348 const ValueDecl *DepDecl = nullptr;
6349 /// Contains number of loop (starts from 1) on which loop counter init
6350 /// expression of this loop depends on.
6351 Optional<unsigned> InitDependOnLC;
6352 /// Contains number of loop (starts from 1) on which loop counter condition
6353 /// expression of this loop depends on.
6354 Optional<unsigned> CondDependOnLC;
6355 /// Checks if the provide statement depends on the loop counter.
6356 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6357 /// Original condition required for checking of the exit condition for
6358 /// non-rectangular loop.
6359 Expr *Condition = nullptr;
6362 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6363 SourceLocation DefaultLoc)
6364 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6365 ConditionLoc(DefaultLoc) {}
6366 /// Check init-expr for canonical loop form and save loop counter
6367 /// variable - #Var and its initialization value - #LB.
6368 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6369 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6370 /// for less/greater and for strict/non-strict comparison.
6371 bool checkAndSetCond(Expr *S);
6372 /// Check incr-expr for canonical loop form and return true if it
6373 /// does not conform, otherwise save loop step (#Step).
6374 bool checkAndSetInc(Expr *S);
6375 /// Return the loop counter variable.
6376 ValueDecl *getLoopDecl() const { return LCDecl; }
6377 /// Return the reference expression to loop counter variable.
6378 Expr *getLoopDeclRefExpr() const { return LCRef; }
6379 /// Source range of the loop init.
6380 SourceRange getInitSrcRange() const { return InitSrcRange; }
6381 /// Source range of the loop condition.
6382 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6383 /// Source range of the loop increment.
6384 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6385 /// True if the step should be subtracted.
6386 bool shouldSubtractStep() const { return SubtractStep; }
6387 /// True, if the compare operator is strict (<, > or !=).
6388 bool isStrictTestOp() const { return TestIsStrictOp; }
6389 /// Build the expression to calculate the number of iterations.
6390 Expr *buildNumIterations(
6391 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6393 /// Build the precondition expression for the loops.
6395 buildPreCond(Scope *S, Expr *Cond,
6396 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6397 /// Build reference expression to the counter be used for codegen.
6399 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6400 DSAStackTy &DSA) const;
6401 /// Build reference expression to the private counter be used for
6403 Expr *buildPrivateCounterVar() const;
6404 /// Build initialization of the counter be used for codegen.
6405 Expr *buildCounterInit() const;
6406 /// Build step of the counter be used for codegen.
6407 Expr *buildCounterStep() const;
6408 /// Build loop data with counter value for depend clauses in ordered
6411 buildOrderedLoopData(Scope *S, Expr *Counter,
6412 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6413 SourceLocation Loc, Expr *Inc = nullptr,
6414 OverloadedOperatorKind OOK = OO_Amp);
6415 /// Builds the minimum value for the loop counter.
6416 std::pair<Expr *, Expr *> buildMinMaxValues(
6417 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6418 /// Builds final condition for the non-rectangular loops.
6419 Expr *buildFinalCondition(Scope *S) const;
6420 /// Return true if any expression is dependent.
6421 bool dependent() const;
6422 /// Returns true if the initializer forms non-rectangular loop.
6423 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6424 /// Returns true if the condition forms non-rectangular loop.
6425 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6426 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6427 unsigned getLoopDependentIdx() const {
6428 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6432 /// Check the right-hand side of an assignment in the increment
6434 bool checkAndSetIncRHS(Expr *RHS);
6435 /// Helper to set loop counter variable and its initializer.
6436 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6438 /// Helper to set upper bound.
6439 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6440 SourceRange SR, SourceLocation SL);
6441 /// Helper to set loop increment.
6442 bool setStep(Expr *NewStep, bool Subtract);
6445 bool OpenMPIterationSpaceChecker::dependent() const {
6447 assert(!LB && !UB && !Step);
6450 return LCDecl->getType()->isDependentType() ||
6451 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6452 (Step && Step->isValueDependent());
6455 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6457 Expr *NewLB, bool EmitDiags) {
6458 // State consistency checking to ensure correct usage.
6459 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6460 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6461 if (!NewLCDecl || !NewLB)
6463 LCDecl = getCanonicalDecl(NewLCDecl);
6464 LCRef = NewLCRefExpr;
6465 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6466 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6467 if ((Ctor->isCopyOrMoveConstructor() ||
6468 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6469 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6470 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6473 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6477 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6478 llvm::Optional<bool> LessOp,
6479 bool StrictOp, SourceRange SR,
6480 SourceLocation SL) {
6481 // State consistency checking to ensure correct usage.
6482 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6483 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6488 TestIsLessOp = LessOp;
6489 TestIsStrictOp = StrictOp;
6490 ConditionSrcRange = SR;
6492 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6496 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6497 // State consistency checking to ensure correct usage.
6498 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6501 if (!NewStep->isValueDependent()) {
6502 // Check that the step is integer expression.
6503 SourceLocation StepLoc = NewStep->getBeginLoc();
6504 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6505 StepLoc, getExprAsWritten(NewStep));
6506 if (Val.isInvalid())
6508 NewStep = Val.get();
6510 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6511 // If test-expr is of form var relational-op b and relational-op is < or
6512 // <= then incr-expr must cause var to increase on each iteration of the
6513 // loop. If test-expr is of form var relational-op b and relational-op is
6514 // > or >= then incr-expr must cause var to decrease on each iteration of
6516 // If test-expr is of form b relational-op var and relational-op is < or
6517 // <= then incr-expr must cause var to decrease on each iteration of the
6518 // loop. If test-expr is of form b relational-op var and relational-op is
6519 // > or >= then incr-expr must cause var to increase on each iteration of
6521 llvm::APSInt Result;
6522 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
6523 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6525 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
6527 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
6528 bool IsConstZero = IsConstant && !Result.getBoolValue();
6530 // != with increment is treated as <; != with decrement is treated as >
6531 if (!TestIsLessOp.hasValue())
6532 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6533 if (UB && (IsConstZero ||
6534 (TestIsLessOp.getValue() ?
6535 (IsConstNeg || (IsUnsigned && Subtract)) :
6536 (IsConstPos || (IsUnsigned && !Subtract))))) {
6537 SemaRef.Diag(NewStep->getExprLoc(),
6538 diag::err_omp_loop_incr_not_compatible)
6539 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6540 SemaRef.Diag(ConditionLoc,
6541 diag::note_omp_loop_cond_requres_compatible_incr)
6542 << TestIsLessOp.getValue() << ConditionSrcRange;
6545 if (TestIsLessOp.getValue() == Subtract) {
6547 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6549 Subtract = !Subtract;
6554 SubtractStep = Subtract;
6559 /// Checker for the non-rectangular loops. Checks if the initializer or
6560 /// condition expression references loop counter variable.
6561 class LoopCounterRefChecker final
6562 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6565 const ValueDecl *CurLCDecl = nullptr;
6566 const ValueDecl *DepDecl = nullptr;
6567 const ValueDecl *PrevDepDecl = nullptr;
6568 bool IsInitializer = true;
6569 unsigned BaseLoopId = 0;
6570 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6571 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6572 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6573 << (IsInitializer ? 0 : 1);
6576 const auto &&Data = Stack.isLoopControlVariable(VD);
6577 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6578 // The type of the loop iterator on which we depend may not have a random
6579 // access iterator type.
6580 if (Data.first && VD->getType()->isRecordType()) {
6581 SmallString<128> Name;
6582 llvm::raw_svector_ostream OS(Name);
6583 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6584 /*Qualified=*/true);
6585 SemaRef.Diag(E->getExprLoc(),
6586 diag::err_omp_wrong_dependency_iterator_type)
6588 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6592 (DepDecl || (PrevDepDecl &&
6593 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6594 if (!DepDecl && PrevDepDecl)
6595 DepDecl = PrevDepDecl;
6596 SmallString<128> Name;
6597 llvm::raw_svector_ostream OS(Name);
6598 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6599 /*Qualified=*/true);
6600 SemaRef.Diag(E->getExprLoc(),
6601 diag::err_omp_invariant_or_linear_dependency)
6607 BaseLoopId = Data.first;
6613 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6614 const ValueDecl *VD = E->getDecl();
6615 if (isa<VarDecl>(VD))
6616 return checkDecl(E, VD);
6619 bool VisitMemberExpr(const MemberExpr *E) {
6620 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6621 const ValueDecl *VD = E->getMemberDecl();
6622 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6623 return checkDecl(E, VD);
6627 bool VisitStmt(const Stmt *S) {
6629 for (const Stmt *Child : S->children())
6630 Res = (Child && Visit(Child)) || Res;
6633 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6634 const ValueDecl *CurLCDecl, bool IsInitializer,
6635 const ValueDecl *PrevDepDecl = nullptr)
6636 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6637 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6638 unsigned getBaseLoopId() const {
6639 assert(CurLCDecl && "Expected loop dependency.");
6642 const ValueDecl *getDepDecl() const {
6643 assert(CurLCDecl && "Expected loop dependency.");
6650 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6651 bool IsInitializer) {
6652 // Check for the non-rectangular loops.
6653 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6655 if (LoopStmtChecker.Visit(S)) {
6656 DepDecl = LoopStmtChecker.getDepDecl();
6657 return LoopStmtChecker.getBaseLoopId();
6662 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6663 // Check init-expr for canonical loop form and save loop counter
6664 // variable - #Var and its initialization value - #LB.
6665 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6667 // integer-type var = lb
6668 // random-access-iterator-type var = lb
6669 // pointer-type var = lb
6673 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6677 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6678 if (!ExprTemp->cleanupsHaveSideEffects())
6679 S = ExprTemp->getSubExpr();
6681 InitSrcRange = S->getSourceRange();
6682 if (Expr *E = dyn_cast<Expr>(S))
6683 S = E->IgnoreParens();
6684 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6685 if (BO->getOpcode() == BO_Assign) {
6686 Expr *LHS = BO->getLHS()->IgnoreParens();
6687 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6688 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6689 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6690 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6692 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6695 if (ME->isArrow() &&
6696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6697 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6701 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6702 if (DS->isSingleDecl()) {
6703 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6704 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6705 // Accept non-canonical init form here but emit ext. warning.
6706 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6707 SemaRef.Diag(S->getBeginLoc(),
6708 diag::ext_omp_loop_not_canonical_init)
6709 << S->getSourceRange();
6710 return setLCDeclAndLB(
6712 buildDeclRefExpr(SemaRef, Var,
6713 Var->getType().getNonReferenceType(),
6715 Var->getInit(), EmitDiags);
6719 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6720 if (CE->getOperator() == OO_Equal) {
6721 Expr *LHS = CE->getArg(0);
6722 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6723 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6724 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6725 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6727 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6729 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6730 if (ME->isArrow() &&
6731 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6732 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6738 if (dependent() || SemaRef.CurContext->isDependentContext())
6741 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6742 << S->getSourceRange();
6747 /// Ignore parenthesizes, implicit casts, copy constructor and return the
6748 /// variable (which may be the loop variable) if possible.
6749 static const ValueDecl *getInitLCDecl(const Expr *E) {
6752 E = getExprAsWritten(E);
6753 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6754 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6755 if ((Ctor->isCopyOrMoveConstructor() ||
6756 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6757 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6758 E = CE->getArg(0)->IgnoreParenImpCasts();
6759 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6760 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6761 return getCanonicalDecl(VD);
6763 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6764 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6765 return getCanonicalDecl(ME->getMemberDecl());
6769 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6770 // Check test-expr for canonical form, save upper-bound UB, flags for
6771 // less/greater and for strict/non-strict comparison.
6772 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6773 // var relational-op b
6774 // b relational-op var
6776 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6778 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6779 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6783 S = getExprAsWritten(S);
6784 SourceLocation CondLoc = S->getBeginLoc();
6785 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6786 if (BO->isRelationalOp()) {
6787 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6788 return setUB(BO->getRHS(),
6789 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6790 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6791 BO->getSourceRange(), BO->getOperatorLoc());
6792 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6793 return setUB(BO->getLHS(),
6794 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6795 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6796 BO->getSourceRange(), BO->getOperatorLoc());
6797 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6799 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6800 /*LessOp=*/llvm::None,
6801 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6802 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6803 if (CE->getNumArgs() == 2) {
6804 auto Op = CE->getOperator();
6807 case OO_GreaterEqual:
6810 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6811 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6812 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6813 CE->getOperatorLoc());
6814 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6815 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6816 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6817 CE->getOperatorLoc());
6819 case OO_ExclaimEqual:
6820 if (IneqCondIsCanonical)
6821 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6823 /*LessOp=*/llvm::None,
6824 /*StrictOp=*/true, CE->getSourceRange(),
6825 CE->getOperatorLoc());
6832 if (dependent() || SemaRef.CurContext->isDependentContext())
6834 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6835 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6839 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6840 // RHS of canonical loop form increment can be:
6845 RHS = RHS->IgnoreParenImpCasts();
6846 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6847 if (BO->isAdditiveOp()) {
6848 bool IsAdd = BO->getOpcode() == BO_Add;
6849 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6850 return setStep(BO->getRHS(), !IsAdd);
6851 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6852 return setStep(BO->getLHS(), /*Subtract=*/false);
6854 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6855 bool IsAdd = CE->getOperator() == OO_Plus;
6856 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6857 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6858 return setStep(CE->getArg(1), !IsAdd);
6859 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6860 return setStep(CE->getArg(0), /*Subtract=*/false);
6863 if (dependent() || SemaRef.CurContext->isDependentContext())
6865 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6866 << RHS->getSourceRange() << LCDecl;
6870 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6871 // Check incr-expr for canonical loop form and return true if it
6872 // does not conform.
6873 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6885 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6888 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6889 if (!ExprTemp->cleanupsHaveSideEffects())
6890 S = ExprTemp->getSubExpr();
6892 IncrementSrcRange = S->getSourceRange();
6893 S = S->IgnoreParens();
6894 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
6895 if (UO->isIncrementDecrementOp() &&
6896 getInitLCDecl(UO->getSubExpr()) == LCDecl)
6897 return setStep(SemaRef
6898 .ActOnIntegerConstant(UO->getBeginLoc(),
6899 (UO->isDecrementOp() ? -1 : 1))
6901 /*Subtract=*/false);
6902 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6903 switch (BO->getOpcode()) {
6906 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6907 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6910 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6911 return checkAndSetIncRHS(BO->getRHS());
6916 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6917 switch (CE->getOperator()) {
6920 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6921 return setStep(SemaRef
6922 .ActOnIntegerConstant(
6924 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6926 /*Subtract=*/false);
6930 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6931 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6934 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6935 return checkAndSetIncRHS(CE->getArg(1));
6941 if (dependent() || SemaRef.CurContext->isDependentContext())
6943 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6944 << S->getSourceRange() << LCDecl;
6949 tryBuildCapture(Sema &SemaRef, Expr *Capture,
6950 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6951 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
6953 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
6954 return SemaRef.PerformImplicitConversion(
6955 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
6956 /*AllowExplicit=*/true);
6957 auto I = Captures.find(Capture);
6958 if (I != Captures.end())
6959 return buildCapture(SemaRef, Capture, I->second);
6960 DeclRefExpr *Ref = nullptr;
6961 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
6962 Captures[Capture] = Ref;
6966 /// Calculate number of iterations, transforming to unsigned, if number of
6967 /// iterations may be larger than the original type.
6969 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
6970 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
6971 bool TestIsStrictOp, bool RoundToStep,
6972 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6973 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6974 if (!NewStep.isUsable())
6976 llvm::APSInt LRes, URes, SRes;
6977 bool IsLowerConst = Lower->isIntegerConstantExpr(LRes, SemaRef.Context);
6978 bool IsStepConst = Step->isIntegerConstantExpr(SRes, SemaRef.Context);
6979 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
6980 ((!TestIsStrictOp && LRes.isNonNegative()) ||
6981 (TestIsStrictOp && LRes.isStrictlyPositive()));
6982 bool NeedToReorganize = false;
6983 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
6984 if (!NoNeedToConvert && IsLowerConst &&
6985 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
6986 NoNeedToConvert = true;
6988 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
6989 ? LRes.getBitWidth()
6990 : SRes.getBitWidth();
6991 LRes = LRes.extend(BW + 1);
6992 LRes.setIsSigned(true);
6993 SRes = SRes.extend(BW + 1);
6994 SRes.setIsSigned(true);
6996 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
6997 LRes = LRes.trunc(BW);
6999 if (TestIsStrictOp) {
7000 unsigned BW = LRes.getBitWidth();
7001 LRes = LRes.extend(BW + 1);
7002 LRes.setIsSigned(true);
7005 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7006 // truncate to the original bitwidth.
7007 LRes = LRes.trunc(BW);
7009 NeedToReorganize = NoNeedToConvert;
7011 bool IsUpperConst = Upper->isIntegerConstantExpr(URes, SemaRef.Context);
7012 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7013 (!RoundToStep || IsStepConst)) {
7014 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7015 : URes.getBitWidth();
7016 LRes = LRes.extend(BW + 1);
7017 LRes.setIsSigned(true);
7018 URes = URes.extend(BW + 1);
7019 URes.setIsSigned(true);
7021 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7022 NeedToReorganize = NoNeedToConvert;
7024 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7025 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7027 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7028 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7029 QualType LowerTy = Lower->getType();
7030 QualType UpperTy = Upper->getType();
7031 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7032 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7033 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7034 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7035 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7036 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7039 .PerformImplicitConversion(
7040 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7041 CastType, Sema::AA_Converting)
7043 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7044 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7047 if (!Lower || !Upper || NewStep.isInvalid())
7051 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7053 if (NeedToReorganize) {
7059 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7060 if (!Diff.isUsable())
7064 // Lower - Step [+ 1]
7066 Diff = SemaRef.BuildBinOp(
7067 S, DefaultLoc, BO_Add, Diff.get(),
7068 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7069 if (!Diff.isUsable())
7072 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7073 if (!Diff.isUsable())
7076 // Upper - (Lower - Step [+ 1]).
7077 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7078 if (!Diff.isUsable())
7081 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7083 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7084 // BuildBinOp already emitted error, this one is to point user to upper
7085 // and lower bound, and to tell what is passed to 'operator-'.
7086 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7087 << Upper->getSourceRange() << Lower->getSourceRange();
7091 if (!Diff.isUsable())
7094 // Upper - Lower [- 1]
7096 Diff = SemaRef.BuildBinOp(
7097 S, DefaultLoc, BO_Sub, Diff.get(),
7098 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7099 if (!Diff.isUsable())
7103 // Upper - Lower [- 1] + Step
7105 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7106 if (!Diff.isUsable())
7111 // Parentheses (for dumping/debugging purposes only).
7112 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7113 if (!Diff.isUsable())
7116 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7117 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7118 if (!Diff.isUsable())
7124 /// Build the expression to calculate the number of iterations.
7125 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7126 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7127 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7128 QualType VarType = LCDecl->getType().getNonReferenceType();
7129 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7130 !SemaRef.getLangOpts().CPlusPlus)
7134 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7135 // max(LB(MinVal), LB(MaxVal))
7136 if (InitDependOnLC) {
7137 const LoopIterationSpace &IS =
7138 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7139 InitDependOnLC.getValueOr(
7140 CondDependOnLC.getValueOr(0))];
7141 if (!IS.MinValue || !IS.MaxValue)
7144 ExprResult MinValue =
7145 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7146 if (!MinValue.isUsable())
7149 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7150 IS.CounterVar, MinValue.get());
7151 if (!LBMinVal.isUsable())
7153 // OuterVar = Min, LBVal
7155 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7156 if (!LBMinVal.isUsable())
7158 // (OuterVar = Min, LBVal)
7159 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7160 if (!LBMinVal.isUsable())
7164 ExprResult MaxValue =
7165 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7166 if (!MaxValue.isUsable())
7169 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7170 IS.CounterVar, MaxValue.get());
7171 if (!LBMaxVal.isUsable())
7173 // OuterVar = Max, LBVal
7175 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7176 if (!LBMaxVal.isUsable())
7178 // (OuterVar = Max, LBVal)
7179 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7180 if (!LBMaxVal.isUsable())
7183 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7184 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7185 if (!LBMin || !LBMax)
7187 // LB(MinVal) < LB(MaxVal)
7188 ExprResult MinLessMaxRes =
7189 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7190 if (!MinLessMaxRes.isUsable())
7193 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7196 if (TestIsLessOp.getValue()) {
7197 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7199 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7200 MinLessMax, LBMin, LBMax);
7201 if (!MinLB.isUsable())
7203 LBVal = MinLB.get();
7205 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7207 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7208 MinLessMax, LBMax, LBMin);
7209 if (!MaxLB.isUsable())
7211 LBVal = MaxLB.get();
7214 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7215 // min(UB(MinVal), UB(MaxVal))
7216 if (CondDependOnLC) {
7217 const LoopIterationSpace &IS =
7218 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7219 InitDependOnLC.getValueOr(
7220 CondDependOnLC.getValueOr(0))];
7221 if (!IS.MinValue || !IS.MaxValue)
7224 ExprResult MinValue =
7225 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7226 if (!MinValue.isUsable())
7229 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7230 IS.CounterVar, MinValue.get());
7231 if (!UBMinVal.isUsable())
7233 // OuterVar = Min, UBVal
7235 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7236 if (!UBMinVal.isUsable())
7238 // (OuterVar = Min, UBVal)
7239 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7240 if (!UBMinVal.isUsable())
7244 ExprResult MaxValue =
7245 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7246 if (!MaxValue.isUsable())
7249 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7250 IS.CounterVar, MaxValue.get());
7251 if (!UBMaxVal.isUsable())
7253 // OuterVar = Max, UBVal
7255 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7256 if (!UBMaxVal.isUsable())
7258 // (OuterVar = Max, UBVal)
7259 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7260 if (!UBMaxVal.isUsable())
7263 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7264 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7265 if (!UBMin || !UBMax)
7267 // UB(MinVal) > UB(MaxVal)
7268 ExprResult MinGreaterMaxRes =
7269 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7270 if (!MinGreaterMaxRes.isUsable())
7272 Expr *MinGreaterMax =
7273 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7276 if (TestIsLessOp.getValue()) {
7277 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7279 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7280 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7281 if (!MaxUB.isUsable())
7283 UBVal = MaxUB.get();
7285 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7287 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7288 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7289 if (!MinUB.isUsable())
7291 UBVal = MinUB.get();
7294 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7295 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7296 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7297 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7298 if (!Upper || !Lower)
7302 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7303 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7304 if (!Diff.isUsable())
7307 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7308 QualType Type = Diff.get()->getType();
7309 ASTContext &C = SemaRef.Context;
7310 bool UseVarType = VarType->hasIntegerRepresentation() &&
7311 C.getTypeSize(Type) > C.getTypeSize(VarType);
7312 if (!Type->isIntegerType() || UseVarType) {
7314 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7315 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7316 : Type->hasSignedIntegerRepresentation();
7317 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7318 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7319 Diff = SemaRef.PerformImplicitConversion(
7320 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7321 if (!Diff.isUsable())
7326 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7327 if (NewSize != C.getTypeSize(Type)) {
7328 if (NewSize < C.getTypeSize(Type)) {
7329 assert(NewSize == 64 && "incorrect loop var size");
7330 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7331 << InitSrcRange << ConditionSrcRange;
7333 QualType NewType = C.getIntTypeForBitwidth(
7334 NewSize, Type->hasSignedIntegerRepresentation() ||
7335 C.getTypeSize(Type) < NewSize);
7336 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7337 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7338 Sema::AA_Converting, true);
7339 if (!Diff.isUsable())
7348 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7349 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7350 // Do not build for iterators, they cannot be used in non-rectangular loop
7352 if (LCDecl->getType()->isRecordType())
7353 return std::make_pair(nullptr, nullptr);
7354 // If we subtract, the min is in the condition, otherwise the min is in the
7356 Expr *MinExpr = nullptr;
7357 Expr *MaxExpr = nullptr;
7358 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7359 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7360 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7361 : CondDependOnLC.hasValue();
7362 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7363 : InitDependOnLC.hasValue();
7365 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7367 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7368 if (!Upper || !Lower)
7369 return std::make_pair(nullptr, nullptr);
7371 if (TestIsLessOp.getValue())
7376 // Build minimum/maximum value based on number of iterations.
7377 QualType VarType = LCDecl->getType().getNonReferenceType();
7380 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7381 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7382 if (!Diff.isUsable())
7383 return std::make_pair(nullptr, nullptr);
7385 // ((Upper - Lower [- 1]) / Step) * Step
7386 // Parentheses (for dumping/debugging purposes only).
7387 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7388 if (!Diff.isUsable())
7389 return std::make_pair(nullptr, nullptr);
7391 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7392 if (!NewStep.isUsable())
7393 return std::make_pair(nullptr, nullptr);
7394 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7395 if (!Diff.isUsable())
7396 return std::make_pair(nullptr, nullptr);
7398 // Parentheses (for dumping/debugging purposes only).
7399 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7400 if (!Diff.isUsable())
7401 return std::make_pair(nullptr, nullptr);
7403 // Convert to the ptrdiff_t, if original type is pointer.
7404 if (VarType->isAnyPointerType() &&
7405 !SemaRef.Context.hasSameType(
7406 Diff.get()->getType(),
7407 SemaRef.Context.getUnsignedPointerDiffType())) {
7408 Diff = SemaRef.PerformImplicitConversion(
7409 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7410 Sema::AA_Converting, /*AllowExplicit=*/true);
7412 if (!Diff.isUsable())
7413 return std::make_pair(nullptr, nullptr);
7415 if (TestIsLessOp.getValue()) {
7417 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7418 Diff = SemaRef.BuildBinOp(
7419 S, DefaultLoc, BO_Add,
7420 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7422 if (!Diff.isUsable())
7423 return std::make_pair(nullptr, nullptr);
7426 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7427 Diff = SemaRef.BuildBinOp(
7428 S, DefaultLoc, BO_Sub,
7429 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7431 if (!Diff.isUsable())
7432 return std::make_pair(nullptr, nullptr);
7435 // Convert to the original type.
7436 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7437 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7438 Sema::AA_Converting,
7439 /*AllowExplicit=*/true);
7440 if (!Diff.isUsable())
7441 return std::make_pair(nullptr, nullptr);
7443 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7444 if (!Diff.isUsable())
7445 return std::make_pair(nullptr, nullptr);
7447 if (TestIsLessOp.getValue())
7448 MaxExpr = Diff.get();
7450 MinExpr = Diff.get();
7452 return std::make_pair(MinExpr, MaxExpr);
7455 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7456 if (InitDependOnLC || CondDependOnLC)
7461 Expr *OpenMPIterationSpaceChecker::buildPreCond(
7462 Scope *S, Expr *Cond,
7463 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7464 // Do not build a precondition when the condition/initialization is dependent
7465 // to prevent pessimistic early loop exit.
7466 // TODO: this can be improved by calculating min/max values but not sure that
7467 // it will be very effective.
7468 if (CondDependOnLC || InitDependOnLC)
7469 return SemaRef.PerformImplicitConversion(
7470 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7471 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7472 /*AllowExplicit=*/true).get();
7474 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7475 Sema::TentativeAnalysisScope Trap(SemaRef);
7477 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7478 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7479 if (!NewLB.isUsable() || !NewUB.isUsable())
7482 ExprResult CondExpr =
7483 SemaRef.BuildBinOp(S, DefaultLoc,
7484 TestIsLessOp.getValue() ?
7485 (TestIsStrictOp ? BO_LT : BO_LE) :
7486 (TestIsStrictOp ? BO_GT : BO_GE),
7487 NewLB.get(), NewUB.get());
7488 if (CondExpr.isUsable()) {
7489 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7490 SemaRef.Context.BoolTy))
7491 CondExpr = SemaRef.PerformImplicitConversion(
7492 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7493 /*AllowExplicit=*/true);
7496 // Otherwise use original loop condition and evaluate it in runtime.
7497 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7500 /// Build reference expression to the counter be used for codegen.
7501 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7502 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7503 DSAStackTy &DSA) const {
7504 auto *VD = dyn_cast<VarDecl>(LCDecl);
7506 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7507 DeclRefExpr *Ref = buildDeclRefExpr(
7508 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7509 const DSAStackTy::DSAVarData Data =
7510 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7511 // If the loop control decl is explicitly marked as private, do not mark it
7512 // as captured again.
7513 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7514 Captures.insert(std::make_pair(LCRef, Ref));
7517 return cast<DeclRefExpr>(LCRef);
7520 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7521 if (LCDecl && !LCDecl->isInvalidDecl()) {
7522 QualType Type = LCDecl->getType().getNonReferenceType();
7523 VarDecl *PrivateVar = buildVarDecl(
7524 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7525 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7526 isa<VarDecl>(LCDecl)
7527 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7529 if (PrivateVar->isInvalidDecl())
7531 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7536 /// Build initialization of the counter to be used for codegen.
7537 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7539 /// Build step of the counter be used for codegen.
7540 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7542 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7543 Scope *S, Expr *Counter,
7544 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7545 Expr *Inc, OverloadedOperatorKind OOK) {
7546 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7550 assert((OOK == OO_Plus || OOK == OO_Minus) &&
7551 "Expected only + or - operations for depend clauses.");
7552 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7553 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7557 QualType VarType = LCDecl->getType().getNonReferenceType();
7558 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7559 !SemaRef.getLangOpts().CPlusPlus)
7562 Expr *Upper = TestIsLessOp.getValue()
7564 : tryBuildCapture(SemaRef, LB, Captures).get();
7565 Expr *Lower = TestIsLessOp.getValue()
7566 ? tryBuildCapture(SemaRef, LB, Captures).get()
7568 if (!Upper || !Lower)
7571 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7572 Step, VarType, /*TestIsStrictOp=*/false,
7573 /*RoundToStep=*/false, Captures);
7574 if (!Diff.isUsable())
7581 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7582 assert(getLangOpts().OpenMP && "OpenMP is not active.");
7583 assert(Init && "Expected loop in canonical form.");
7584 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7585 if (AssociatedLoops > 0 &&
7586 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7587 DSAStack->loopStart();
7588 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7589 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7590 if (ValueDecl *D = ISC.getLoopDecl()) {
7591 auto *VD = dyn_cast<VarDecl>(D);
7592 DeclRefExpr *PrivateRef = nullptr;
7594 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7597 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7598 /*WithInit=*/false);
7599 VD = cast<VarDecl>(PrivateRef->getDecl());
7602 DSAStack->addLoopControlVariable(D, VD);
7603 const Decl *LD = DSAStack->getPossiblyLoopCunter();
7604 if (LD != D->getCanonicalDecl()) {
7605 DSAStack->resetPossibleLoopCounter();
7606 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7607 MarkDeclarationsReferencedInExpr(
7608 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7609 Var->getType().getNonLValueExprType(Context),
7610 ForLoc, /*RefersToCapture=*/true));
7612 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7613 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7614 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7615 // associated for-loop of a simd construct with just one associated
7616 // for-loop may be listed in a linear clause with a constant-linear-step
7617 // that is the increment of the associated for-loop. The loop iteration
7618 // variable(s) in the associated for-loop(s) of a for or parallel for
7619 // construct may be listed in a private or lastprivate clause.
7620 DSAStackTy::DSAVarData DVar =
7621 DSAStack->getTopDSA(D, /*FromParent=*/false);
7622 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7623 // is declared in the loop and it is predetermined as a private.
7624 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7625 OpenMPClauseKind PredeterminedCKind =
7626 isOpenMPSimdDirective(DKind)
7627 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7629 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7630 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7631 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7632 DVar.CKind != OMPC_private))) ||
7633 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7634 DKind == OMPD_master_taskloop ||
7635 DKind == OMPD_parallel_master_taskloop ||
7636 isOpenMPDistributeDirective(DKind)) &&
7637 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7638 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7639 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7640 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7641 << getOpenMPClauseName(DVar.CKind)
7642 << getOpenMPDirectiveName(DKind)
7643 << getOpenMPClauseName(PredeterminedCKind);
7644 if (DVar.RefExpr == nullptr)
7645 DVar.CKind = PredeterminedCKind;
7646 reportOriginalDsa(*this, DSAStack, D, DVar,
7647 /*IsLoopIterVar=*/true);
7648 } else if (LoopDeclRefExpr) {
7649 // Make the loop iteration variable private (for worksharing
7650 // constructs), linear (for simd directives with the only one
7651 // associated loop) or lastprivate (for simd directives with several
7652 // collapsed or ordered loops).
7653 if (DVar.CKind == OMPC_unknown)
7654 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7659 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7663 /// Called on a for stmt to check and extract its iteration space
7664 /// for further processing (such as collapsing).
7665 static bool checkOpenMPIterationSpace(
7666 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7667 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7668 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7669 Expr *OrderedLoopCountExpr,
7670 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7671 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7672 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7673 // OpenMP [2.9.1, Canonical Loop Form]
7674 // for (init-expr; test-expr; incr-expr) structured-block
7675 // for (range-decl: range-expr) structured-block
7676 auto *For = dyn_cast_or_null<ForStmt>(S);
7677 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7678 // Ranged for is supported only in OpenMP 5.0.
7679 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7680 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7681 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7682 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7683 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7684 if (TotalNestedLoopCount > 1) {
7685 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7686 SemaRef.Diag(DSA.getConstructLoc(),
7687 diag::note_omp_collapse_ordered_expr)
7688 << 2 << CollapseLoopCountExpr->getSourceRange()
7689 << OrderedLoopCountExpr->getSourceRange();
7690 else if (CollapseLoopCountExpr)
7691 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7692 diag::note_omp_collapse_ordered_expr)
7693 << 0 << CollapseLoopCountExpr->getSourceRange();
7695 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7696 diag::note_omp_collapse_ordered_expr)
7697 << 1 << OrderedLoopCountExpr->getSourceRange();
7701 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7704 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7705 For ? For->getForLoc() : CXXFor->getForLoc());
7708 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7709 if (ISC.checkAndSetInit(Init))
7712 bool HasErrors = false;
7714 // Check loop variable's type.
7715 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7716 // OpenMP [2.6, Canonical Loop Form]
7717 // Var is one of the following:
7718 // A variable of signed or unsigned integer type.
7719 // For C++, a variable of a random access iterator type.
7720 // For C, a variable of a pointer type.
7721 QualType VarType = LCDecl->getType().getNonReferenceType();
7722 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7723 !VarType->isPointerType() &&
7724 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7725 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7726 << SemaRef.getLangOpts().CPlusPlus;
7730 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7732 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7733 // parallel for construct is (are) private.
7734 // The loop iteration variable in the associated for-loop of a simd
7735 // construct with just one associated for-loop is linear with a
7736 // constant-linear-step that is the increment of the associated for-loop.
7737 // Exclude loop var from the list of variables with implicitly defined data
7738 // sharing attributes.
7739 VarsWithImplicitDSA.erase(LCDecl);
7741 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
7744 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7747 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7750 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7753 // Build the loop's iteration space representation.
7754 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7755 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7756 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7757 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7758 (isOpenMPWorksharingDirective(DKind) ||
7759 isOpenMPTaskLoopDirective(DKind) ||
7760 isOpenMPDistributeDirective(DKind)),
7762 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7763 ISC.buildCounterVar(Captures, DSA);
7764 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7765 ISC.buildPrivateCounterVar();
7766 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7767 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7768 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7769 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7770 ISC.getConditionSrcRange();
7771 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7772 ISC.getIncrementSrcRange();
7773 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7774 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7775 ISC.isStrictTestOp();
7776 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7777 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7778 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7779 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7780 ISC.buildFinalCondition(DSA.getCurScope());
7781 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7782 ISC.doesInitDependOnLC();
7783 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7784 ISC.doesCondDependOnLC();
7785 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7786 ISC.getLoopDependentIdx();
7789 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7790 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7791 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7792 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7793 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7794 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7795 if (!HasErrors && DSA.isOrderedRegion()) {
7796 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7797 if (CurrentNestedLoopCount <
7798 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7799 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7800 CurrentNestedLoopCount,
7801 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7802 DSA.getOrderedRegionParam().second->setLoopCounter(
7803 CurrentNestedLoopCount,
7804 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7807 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7808 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7809 // Erroneous case - clause has some problems.
7812 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7813 Pair.second.size() <= CurrentNestedLoopCount) {
7814 // Erroneous case - clause has some problems.
7815 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7819 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7820 CntValue = ISC.buildOrderedLoopData(
7822 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7823 Pair.first->getDependencyLoc());
7825 CntValue = ISC.buildOrderedLoopData(
7827 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7828 Pair.first->getDependencyLoc(),
7829 Pair.second[CurrentNestedLoopCount].first,
7830 Pair.second[CurrentNestedLoopCount].second);
7831 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7838 /// Build 'VarRef = Start.
7840 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7841 ExprResult Start, bool IsNonRectangularLB,
7842 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7843 // Build 'VarRef = Start.
7844 ExprResult NewStart = IsNonRectangularLB
7846 : tryBuildCapture(SemaRef, Start.get(), Captures);
7847 if (!NewStart.isUsable())
7849 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7850 VarRef.get()->getType())) {
7851 NewStart = SemaRef.PerformImplicitConversion(
7852 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7853 /*AllowExplicit=*/true);
7854 if (!NewStart.isUsable())
7859 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7863 /// Build 'VarRef = Start + Iter * Step'.
7864 static ExprResult buildCounterUpdate(
7865 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7866 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7867 bool IsNonRectangularLB,
7868 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7869 // Add parentheses (for debugging purposes only).
7870 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7871 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7875 ExprResult NewStep = Step;
7877 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
7878 if (NewStep.isInvalid())
7881 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
7882 if (!Update.isUsable())
7885 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
7886 // 'VarRef = Start (+|-) Iter * Step'.
7887 if (!Start.isUsable())
7889 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
7890 if (!NewStart.isUsable())
7892 if (Captures && !IsNonRectangularLB)
7893 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
7894 if (NewStart.isInvalid())
7897 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
7898 ExprResult SavedUpdate = Update;
7899 ExprResult UpdateVal;
7900 if (VarRef.get()->getType()->isOverloadableType() ||
7901 NewStart.get()->getType()->isOverloadableType() ||
7902 Update.get()->getType()->isOverloadableType()) {
7903 Sema::TentativeAnalysisScope Trap(SemaRef);
7906 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7907 if (Update.isUsable()) {
7909 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7910 VarRef.get(), SavedUpdate.get());
7911 if (UpdateVal.isUsable()) {
7912 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
7918 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
7919 if (!Update.isUsable() || !UpdateVal.isUsable()) {
7920 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7921 NewStart.get(), SavedUpdate.get());
7922 if (!Update.isUsable())
7925 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
7926 VarRef.get()->getType())) {
7927 Update = SemaRef.PerformImplicitConversion(
7928 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
7929 if (!Update.isUsable())
7933 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
7938 /// Convert integer expression \a E to make it have at least \a Bits
7940 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
7943 ASTContext &C = SemaRef.Context;
7944 QualType OldType = E->getType();
7945 unsigned HasBits = C.getTypeSize(OldType);
7946 if (HasBits >= Bits)
7947 return ExprResult(E);
7948 // OK to convert to signed, because new type has more bits than old.
7949 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
7950 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
7954 /// Check if the given expression \a E is a constant integer that fits
7955 /// into \a Bits bits.
7956 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
7959 llvm::APSInt Result;
7960 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
7961 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
7965 /// Build preinits statement for the given declarations.
7966 static Stmt *buildPreInits(ASTContext &Context,
7967 MutableArrayRef<Decl *> PreInits) {
7968 if (!PreInits.empty()) {
7969 return new (Context) DeclStmt(
7970 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
7971 SourceLocation(), SourceLocation());
7976 /// Build preinits statement for the given declarations.
7978 buildPreInits(ASTContext &Context,
7979 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7980 if (!Captures.empty()) {
7981 SmallVector<Decl *, 16> PreInits;
7982 for (const auto &Pair : Captures)
7983 PreInits.push_back(Pair.second->getDecl());
7984 return buildPreInits(Context, PreInits);
7989 /// Build postupdate expression for the given list of postupdates expressions.
7990 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
7991 Expr *PostUpdate = nullptr;
7992 if (!PostUpdates.empty()) {
7993 for (Expr *E : PostUpdates) {
7994 Expr *ConvE = S.BuildCStyleCastExpr(
7996 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
7999 PostUpdate = PostUpdate
8000 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8009 /// Called on a for stmt to check itself and nested loops (if any).
8010 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8011 /// number of collapsed loops otherwise.
8013 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8014 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8016 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8017 OMPLoopDirective::HelperExprs &Built) {
8018 unsigned NestedLoopCount = 1;
8019 if (CollapseLoopCountExpr) {
8020 // Found 'collapse' clause - calculate collapse number.
8021 Expr::EvalResult Result;
8022 if (!CollapseLoopCountExpr->isValueDependent() &&
8023 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8024 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8026 Built.clear(/*Size=*/1);
8030 unsigned OrderedLoopCount = 1;
8031 if (OrderedLoopCountExpr) {
8032 // Found 'ordered' clause - calculate collapse number.
8033 Expr::EvalResult EVResult;
8034 if (!OrderedLoopCountExpr->isValueDependent() &&
8035 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8036 SemaRef.getASTContext())) {
8037 llvm::APSInt Result = EVResult.Val.getInt();
8038 if (Result.getLimitedValue() < NestedLoopCount) {
8039 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8040 diag::err_omp_wrong_ordered_loop_count)
8041 << OrderedLoopCountExpr->getSourceRange();
8042 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8043 diag::note_collapse_loop_count)
8044 << CollapseLoopCountExpr->getSourceRange();
8046 OrderedLoopCount = Result.getLimitedValue();
8048 Built.clear(/*Size=*/1);
8052 // This is helper routine for loop directives (e.g., 'for', 'simd',
8053 // 'for simd', etc.).
8054 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8055 SmallVector<LoopIterationSpace, 4> IterSpaces(
8056 std::max(OrderedLoopCount, NestedLoopCount));
8057 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8058 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8059 if (checkOpenMPIterationSpace(
8060 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8061 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8062 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8064 // Move on to the next nested for loop, or to the loop body.
8065 // OpenMP [2.8.1, simd construct, Restrictions]
8066 // All loops associated with the construct must be perfectly nested; that
8067 // is, there must be no intervening code nor any OpenMP directive between
8069 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8070 CurStmt = For->getBody();
8072 assert(isa<CXXForRangeStmt>(CurStmt) &&
8073 "Expected canonical for or range-based for loops.");
8074 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8076 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8077 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8079 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8080 if (checkOpenMPIterationSpace(
8081 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8082 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8083 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8085 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8086 // Handle initialization of captured loop iterator variables.
8087 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8088 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8089 Captures[DRE] = DRE;
8092 // Move on to the next nested for loop, or to the loop body.
8093 // OpenMP [2.8.1, simd construct, Restrictions]
8094 // All loops associated with the construct must be perfectly nested; that
8095 // is, there must be no intervening code nor any OpenMP directive between
8097 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8098 CurStmt = For->getBody();
8100 assert(isa<CXXForRangeStmt>(CurStmt) &&
8101 "Expected canonical for or range-based for loops.");
8102 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8104 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8105 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8108 Built.clear(/* size */ NestedLoopCount);
8110 if (SemaRef.CurContext->isDependentContext())
8111 return NestedLoopCount;
8113 // An example of what is generated for the following code:
8115 // #pragma omp simd collapse(2) ordered(2)
8116 // for (i = 0; i < NI; ++i)
8117 // for (k = 0; k < NK; ++k)
8118 // for (j = J0; j < NJ; j+=2) {
8122 // We generate the code below.
8123 // Note: the loop body may be outlined in CodeGen.
8124 // Note: some counters may be C++ classes, operator- is used to find number of
8125 // iterations and operator+= to calculate counter value.
8126 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8127 // or i64 is currently supported).
8129 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8130 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8131 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8132 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8133 // // similar updates for vars in clauses (e.g. 'linear')
8134 // <loop body (using local i and j)>
8136 // i = NI; // assign final values of counters
8140 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8141 // the iteration counts of the collapsed for loops.
8142 // Precondition tests if there is at least one iteration (all conditions are
8144 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8145 Expr *N0 = IterSpaces[0].NumIterations;
8146 ExprResult LastIteration32 =
8147 widenIterationCount(/*Bits=*/32,
8149 .PerformImplicitConversion(
8150 N0->IgnoreImpCasts(), N0->getType(),
8151 Sema::AA_Converting, /*AllowExplicit=*/true)
8154 ExprResult LastIteration64 = widenIterationCount(
8157 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8158 Sema::AA_Converting,
8159 /*AllowExplicit=*/true)
8163 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8164 return NestedLoopCount;
8166 ASTContext &C = SemaRef.Context;
8167 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8169 Scope *CurScope = DSA.getCurScope();
8170 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8171 if (PreCond.isUsable()) {
8173 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8174 PreCond.get(), IterSpaces[Cnt].PreCond);
8176 Expr *N = IterSpaces[Cnt].NumIterations;
8177 SourceLocation Loc = N->getExprLoc();
8178 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8179 if (LastIteration32.isUsable())
8180 LastIteration32 = SemaRef.BuildBinOp(
8181 CurScope, Loc, BO_Mul, LastIteration32.get(),
8183 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8184 Sema::AA_Converting,
8185 /*AllowExplicit=*/true)
8187 if (LastIteration64.isUsable())
8188 LastIteration64 = SemaRef.BuildBinOp(
8189 CurScope, Loc, BO_Mul, LastIteration64.get(),
8191 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8192 Sema::AA_Converting,
8193 /*AllowExplicit=*/true)
8197 // Choose either the 32-bit or 64-bit version.
8198 ExprResult LastIteration = LastIteration64;
8199 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8200 (LastIteration32.isUsable() &&
8201 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8202 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8205 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8206 LastIteration64.get(), SemaRef))))
8207 LastIteration = LastIteration32;
8208 QualType VType = LastIteration.get()->getType();
8209 QualType RealVType = VType;
8210 QualType StrideVType = VType;
8211 if (isOpenMPTaskLoopDirective(DKind)) {
8213 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8215 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8218 if (!LastIteration.isUsable())
8221 // Save the number of iterations.
8222 ExprResult NumIterations = LastIteration;
8224 LastIteration = SemaRef.BuildBinOp(
8225 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8226 LastIteration.get(),
8227 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8228 if (!LastIteration.isUsable())
8232 // Calculate the last iteration number beforehand instead of doing this on
8233 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8234 llvm::APSInt Result;
8236 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
8237 ExprResult CalcLastIteration;
8239 ExprResult SaveRef =
8240 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8241 LastIteration = SaveRef;
8243 // Prepare SaveRef + 1.
8244 NumIterations = SemaRef.BuildBinOp(
8245 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8246 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8247 if (!NumIterations.isUsable())
8251 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8253 // Build variables passed into runtime, necessary for worksharing directives.
8254 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8255 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8256 isOpenMPDistributeDirective(DKind)) {
8257 // Lower bound variable, initialized with zero.
8258 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8259 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8260 SemaRef.AddInitializerToDecl(LBDecl,
8261 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8262 /*DirectInit*/ false);
8264 // Upper bound variable, initialized with last iteration number.
8265 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8266 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8267 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8268 /*DirectInit*/ false);
8270 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8271 // This will be used to implement clause 'lastprivate'.
8272 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8273 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8274 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8275 SemaRef.AddInitializerToDecl(ILDecl,
8276 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8277 /*DirectInit*/ false);
8279 // Stride variable returned by runtime (we initialize it to 1 by default).
8281 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8282 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8283 SemaRef.AddInitializerToDecl(STDecl,
8284 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8285 /*DirectInit*/ false);
8287 // Build expression: UB = min(UB, LastIteration)
8288 // It is necessary for CodeGen of directives with static scheduling.
8289 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8290 UB.get(), LastIteration.get());
8291 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8292 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8293 LastIteration.get(), UB.get());
8294 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8296 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8298 // If we have a combined directive that combines 'distribute', 'for' or
8299 // 'simd' we need to be able to access the bounds of the schedule of the
8300 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8301 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8302 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8303 // Lower bound variable, initialized with zero.
8304 VarDecl *CombLBDecl =
8305 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8306 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8307 SemaRef.AddInitializerToDecl(
8308 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8309 /*DirectInit*/ false);
8311 // Upper bound variable, initialized with last iteration number.
8312 VarDecl *CombUBDecl =
8313 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8314 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8315 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8316 /*DirectInit*/ false);
8318 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8319 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8320 ExprResult CombCondOp =
8321 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8322 LastIteration.get(), CombUB.get());
8323 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8326 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8328 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8329 // We expect to have at least 2 more parameters than the 'parallel'
8330 // directive does - the lower and upper bounds of the previous schedule.
8331 assert(CD->getNumParams() >= 4 &&
8332 "Unexpected number of parameters in loop combined directive");
8334 // Set the proper type for the bounds given what we learned from the
8336 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8337 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8339 // Previous lower and upper bounds are obtained from the region
8342 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8344 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8348 // Build the iteration variable and its initialization before loop.
8350 ExprResult Init, CombInit;
8352 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8353 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8355 (isOpenMPWorksharingDirective(DKind) ||
8356 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8358 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8359 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8360 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8362 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8364 (isOpenMPWorksharingDirective(DKind) ||
8365 isOpenMPTaskLoopDirective(DKind) ||
8366 isOpenMPDistributeDirective(DKind))
8368 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8370 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8372 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8376 bool UseStrictCompare =
8377 RealVType->hasUnsignedIntegerRepresentation() &&
8378 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8379 return LIS.IsStrictCompare;
8381 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8382 // unsigned IV)) for worksharing loops.
8383 SourceLocation CondLoc = AStmt->getBeginLoc();
8384 Expr *BoundUB = UB.get();
8385 if (UseStrictCompare) {
8388 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8389 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8392 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8395 (isOpenMPWorksharingDirective(DKind) ||
8396 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8397 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8398 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8400 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8401 NumIterations.get());
8402 ExprResult CombDistCond;
8403 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8404 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8405 NumIterations.get());
8408 ExprResult CombCond;
8409 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8410 Expr *BoundCombUB = CombUB.get();
8411 if (UseStrictCompare) {
8415 CurScope, CondLoc, BO_Add, BoundCombUB,
8416 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8419 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8423 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8424 IV.get(), BoundCombUB);
8426 // Loop increment (IV = IV + 1)
8427 SourceLocation IncLoc = AStmt->getBeginLoc();
8429 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8430 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8431 if (!Inc.isUsable())
8433 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8434 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8435 if (!Inc.isUsable())
8438 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8439 // Used for directives with static scheduling.
8440 // In combined construct, add combined version that use CombLB and CombUB
8441 // base variables for the update
8442 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8443 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8444 isOpenMPDistributeDirective(DKind)) {
8446 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8447 if (!NextLB.isUsable())
8451 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8453 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8454 if (!NextLB.isUsable())
8457 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8458 if (!NextUB.isUsable())
8462 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8464 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8465 if (!NextUB.isUsable())
8467 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8469 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8470 if (!NextLB.isUsable())
8473 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8475 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8476 /*DiscardedValue*/ false);
8477 if (!CombNextLB.isUsable())
8481 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8482 if (!CombNextUB.isUsable())
8485 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8487 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8488 /*DiscardedValue*/ false);
8489 if (!CombNextUB.isUsable())
8494 // Create increment expression for distribute loop when combined in a same
8495 // directive with for as IV = IV + ST; ensure upper bound expression based
8496 // on PrevUB instead of NumIterations - used to implement 'for' when found
8497 // in combination with 'distribute', like in 'distribute parallel for'
8498 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8499 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8500 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8501 DistCond = SemaRef.BuildBinOp(
8502 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8503 assert(DistCond.isUsable() && "distribute cond expr was not built");
8506 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8507 assert(DistInc.isUsable() && "distribute inc expr was not built");
8508 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8511 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8512 assert(DistInc.isUsable() && "distribute inc expr was not built");
8514 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8516 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8517 ExprResult IsUBGreater =
8518 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8519 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8520 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8521 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8524 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8526 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8527 // parallel for is in combination with a distribute directive with
8528 // schedule(static, 1)
8529 Expr *BoundPrevUB = PrevUB.get();
8530 if (UseStrictCompare) {
8534 CurScope, CondLoc, BO_Add, BoundPrevUB,
8535 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8538 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8542 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8543 IV.get(), BoundPrevUB);
8546 // Build updates and final values of the loop counters.
8547 bool HasErrors = false;
8548 Built.Counters.resize(NestedLoopCount);
8549 Built.Inits.resize(NestedLoopCount);
8550 Built.Updates.resize(NestedLoopCount);
8551 Built.Finals.resize(NestedLoopCount);
8552 Built.DependentCounters.resize(NestedLoopCount);
8553 Built.DependentInits.resize(NestedLoopCount);
8554 Built.FinalsConditions.resize(NestedLoopCount);
8556 // We implement the following algorithm for obtaining the
8557 // original loop iteration variable values based on the
8558 // value of the collapsed loop iteration variable IV.
8560 // Let n+1 be the number of collapsed loops in the nest.
8561 // Iteration variables (I0, I1, .... In)
8562 // Iteration counts (N0, N1, ... Nn)
8566 // To compute Ik for loop k, 0 <= k <= n, generate:
8567 // Prod = N(k+1) * N(k+2) * ... * Nn;
8569 // Acc -= Ik * Prod;
8571 ExprResult Acc = IV;
8572 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8573 LoopIterationSpace &IS = IterSpaces[Cnt];
8574 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8579 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8580 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8581 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8582 IterSpaces[K].NumIterations);
8584 // Iter = Acc / Prod
8585 // If there is at least one more inner loop to avoid
8586 // multiplication by 1.
8587 if (Cnt + 1 < NestedLoopCount)
8588 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8589 Acc.get(), Prod.get());
8592 if (!Iter.isUsable()) {
8598 // Acc -= Iter * Prod
8599 // Check if there is at least one more inner loop to avoid
8600 // multiplication by 1.
8601 if (Cnt + 1 < NestedLoopCount)
8602 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8603 Iter.get(), Prod.get());
8606 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8607 Acc.get(), Prod.get());
8609 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8610 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8611 DeclRefExpr *CounterVar = buildDeclRefExpr(
8612 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8613 /*RefersToCapture=*/true);
8615 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8616 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8617 if (!Init.isUsable()) {
8621 ExprResult Update = buildCounterUpdate(
8622 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8623 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8624 if (!Update.isUsable()) {
8629 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8631 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8632 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8633 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8634 if (!Final.isUsable()) {
8639 if (!Update.isUsable() || !Final.isUsable()) {
8644 Built.Counters[Cnt] = IS.CounterVar;
8645 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8646 Built.Inits[Cnt] = Init.get();
8647 Built.Updates[Cnt] = Update.get();
8648 Built.Finals[Cnt] = Final.get();
8649 Built.DependentCounters[Cnt] = nullptr;
8650 Built.DependentInits[Cnt] = nullptr;
8651 Built.FinalsConditions[Cnt] = nullptr;
8652 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8653 Built.DependentCounters[Cnt] =
8654 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8655 Built.DependentInits[Cnt] =
8656 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8657 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8666 Built.IterationVarRef = IV.get();
8667 Built.LastIteration = LastIteration.get();
8668 Built.NumIterations = NumIterations.get();
8669 Built.CalcLastIteration = SemaRef
8670 .ActOnFinishFullExpr(CalcLastIteration.get(),
8671 /*DiscardedValue=*/false)
8673 Built.PreCond = PreCond.get();
8674 Built.PreInits = buildPreInits(C, Captures);
8675 Built.Cond = Cond.get();
8676 Built.Init = Init.get();
8677 Built.Inc = Inc.get();
8678 Built.LB = LB.get();
8679 Built.UB = UB.get();
8680 Built.IL = IL.get();
8681 Built.ST = ST.get();
8682 Built.EUB = EUB.get();
8683 Built.NLB = NextLB.get();
8684 Built.NUB = NextUB.get();
8685 Built.PrevLB = PrevLB.get();
8686 Built.PrevUB = PrevUB.get();
8687 Built.DistInc = DistInc.get();
8688 Built.PrevEUB = PrevEUB.get();
8689 Built.DistCombinedFields.LB = CombLB.get();
8690 Built.DistCombinedFields.UB = CombUB.get();
8691 Built.DistCombinedFields.EUB = CombEUB.get();
8692 Built.DistCombinedFields.Init = CombInit.get();
8693 Built.DistCombinedFields.Cond = CombCond.get();
8694 Built.DistCombinedFields.NLB = CombNextLB.get();
8695 Built.DistCombinedFields.NUB = CombNextUB.get();
8696 Built.DistCombinedFields.DistCond = CombDistCond.get();
8697 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8699 return NestedLoopCount;
8702 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8703 auto CollapseClauses =
8704 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8705 if (CollapseClauses.begin() != CollapseClauses.end())
8706 return (*CollapseClauses.begin())->getNumForLoops();
8710 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8711 auto OrderedClauses =
8712 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8713 if (OrderedClauses.begin() != OrderedClauses.end())
8714 return (*OrderedClauses.begin())->getNumForLoops();
8718 static bool checkSimdlenSafelenSpecified(Sema &S,
8719 const ArrayRef<OMPClause *> Clauses) {
8720 const OMPSafelenClause *Safelen = nullptr;
8721 const OMPSimdlenClause *Simdlen = nullptr;
8723 for (const OMPClause *Clause : Clauses) {
8724 if (Clause->getClauseKind() == OMPC_safelen)
8725 Safelen = cast<OMPSafelenClause>(Clause);
8726 else if (Clause->getClauseKind() == OMPC_simdlen)
8727 Simdlen = cast<OMPSimdlenClause>(Clause);
8728 if (Safelen && Simdlen)
8732 if (Simdlen && Safelen) {
8733 const Expr *SimdlenLength = Simdlen->getSimdlen();
8734 const Expr *SafelenLength = Safelen->getSafelen();
8735 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8736 SimdlenLength->isInstantiationDependent() ||
8737 SimdlenLength->containsUnexpandedParameterPack())
8739 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8740 SafelenLength->isInstantiationDependent() ||
8741 SafelenLength->containsUnexpandedParameterPack())
8743 Expr::EvalResult SimdlenResult, SafelenResult;
8744 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8745 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8746 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8747 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8748 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8749 // If both simdlen and safelen clauses are specified, the value of the
8750 // simdlen parameter must be less than or equal to the value of the safelen
8752 if (SimdlenRes > SafelenRes) {
8753 S.Diag(SimdlenLength->getExprLoc(),
8754 diag::err_omp_wrong_simdlen_safelen_values)
8755 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8763 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8764 SourceLocation StartLoc, SourceLocation EndLoc,
8765 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8769 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8770 OMPLoopDirective::HelperExprs B;
8771 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8772 // define the nested loops number.
8773 unsigned NestedLoopCount = checkOpenMPLoop(
8774 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8775 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8776 if (NestedLoopCount == 0)
8779 assert((CurContext->isDependentContext() || B.builtAll()) &&
8780 "omp simd loop exprs were not built");
8782 if (!CurContext->isDependentContext()) {
8783 // Finalize the clauses that need pre-built expressions for CodeGen.
8784 for (OMPClause *C : Clauses) {
8785 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8786 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8787 B.NumIterations, *this, CurScope,
8793 if (checkSimdlenSafelenSpecified(*this, Clauses))
8796 setFunctionHasBranchProtectedScope();
8797 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8802 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8803 SourceLocation StartLoc, SourceLocation EndLoc,
8804 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8808 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8809 OMPLoopDirective::HelperExprs B;
8810 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8811 // define the nested loops number.
8812 unsigned NestedLoopCount = checkOpenMPLoop(
8813 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8814 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8815 if (NestedLoopCount == 0)
8818 assert((CurContext->isDependentContext() || B.builtAll()) &&
8819 "omp for loop exprs were not built");
8821 if (!CurContext->isDependentContext()) {
8822 // Finalize the clauses that need pre-built expressions for CodeGen.
8823 for (OMPClause *C : Clauses) {
8824 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8825 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8826 B.NumIterations, *this, CurScope,
8832 setFunctionHasBranchProtectedScope();
8833 return OMPForDirective::Create(
8834 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8835 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
8838 StmtResult Sema::ActOnOpenMPForSimdDirective(
8839 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8840 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8845 OMPLoopDirective::HelperExprs B;
8846 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8847 // define the nested loops number.
8848 unsigned NestedLoopCount =
8849 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8850 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8851 VarsWithImplicitDSA, B);
8852 if (NestedLoopCount == 0)
8855 assert((CurContext->isDependentContext() || B.builtAll()) &&
8856 "omp for simd loop exprs were not built");
8858 if (!CurContext->isDependentContext()) {
8859 // Finalize the clauses that need pre-built expressions for CodeGen.
8860 for (OMPClause *C : Clauses) {
8861 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8862 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8863 B.NumIterations, *this, CurScope,
8869 if (checkSimdlenSafelenSpecified(*this, Clauses))
8872 setFunctionHasBranchProtectedScope();
8873 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8877 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
8879 SourceLocation StartLoc,
8880 SourceLocation EndLoc) {
8884 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8885 auto BaseStmt = AStmt;
8886 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8887 BaseStmt = CS->getCapturedStmt();
8888 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8889 auto S = C->children();
8890 if (S.begin() == S.end())
8892 // All associated statements must be '#pragma omp section' except for
8894 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8895 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8897 Diag(SectionStmt->getBeginLoc(),
8898 diag::err_omp_sections_substmt_not_section);
8901 cast<OMPSectionDirective>(SectionStmt)
8902 ->setHasCancel(DSAStack->isCancelRegion());
8905 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
8909 setFunctionHasBranchProtectedScope();
8911 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8912 DSAStack->getTaskgroupReductionRef(),
8913 DSAStack->isCancelRegion());
8916 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
8917 SourceLocation StartLoc,
8918 SourceLocation EndLoc) {
8922 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8924 setFunctionHasBranchProtectedScope();
8925 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
8927 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
8928 DSAStack->isCancelRegion());
8931 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
8933 SourceLocation StartLoc,
8934 SourceLocation EndLoc) {
8938 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8940 setFunctionHasBranchProtectedScope();
8942 // OpenMP [2.7.3, single Construct, Restrictions]
8943 // The copyprivate clause must not be used with the nowait clause.
8944 const OMPClause *Nowait = nullptr;
8945 const OMPClause *Copyprivate = nullptr;
8946 for (const OMPClause *Clause : Clauses) {
8947 if (Clause->getClauseKind() == OMPC_nowait)
8949 else if (Clause->getClauseKind() == OMPC_copyprivate)
8950 Copyprivate = Clause;
8951 if (Copyprivate && Nowait) {
8952 Diag(Copyprivate->getBeginLoc(),
8953 diag::err_omp_single_copyprivate_with_nowait);
8954 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
8959 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8962 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
8963 SourceLocation StartLoc,
8964 SourceLocation EndLoc) {
8968 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8970 setFunctionHasBranchProtectedScope();
8972 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
8975 StmtResult Sema::ActOnOpenMPCriticalDirective(
8976 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
8977 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
8981 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8983 bool ErrorFound = false;
8985 SourceLocation HintLoc;
8986 bool DependentHint = false;
8987 for (const OMPClause *C : Clauses) {
8988 if (C->getClauseKind() == OMPC_hint) {
8989 if (!DirName.getName()) {
8990 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
8993 Expr *E = cast<OMPHintClause>(C)->getHint();
8994 if (E->isTypeDependent() || E->isValueDependent() ||
8995 E->isInstantiationDependent()) {
8996 DependentHint = true;
8998 Hint = E->EvaluateKnownConstInt(Context);
8999 HintLoc = C->getBeginLoc();
9005 const auto Pair = DSAStack->getCriticalWithHint(DirName);
9006 if (Pair.first && DirName.getName() && !DependentHint) {
9007 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9008 Diag(StartLoc, diag::err_omp_critical_with_hint);
9009 if (HintLoc.isValid())
9010 Diag(HintLoc, diag::note_omp_critical_hint_here)
9011 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9013 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9014 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9015 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9017 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9018 /*Radix=*/10, /*Signed=*/false);
9020 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9025 setFunctionHasBranchProtectedScope();
9027 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9029 if (!Pair.first && DirName.getName() && !DependentHint)
9030 DSAStack->addCriticalWithHint(Dir, Hint);
9034 StmtResult Sema::ActOnOpenMPParallelForDirective(
9035 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9036 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9040 auto *CS = cast<CapturedStmt>(AStmt);
9041 // 1.2.2 OpenMP Language Terminology
9042 // Structured block - An executable statement with a single entry at the
9043 // top and a single exit at the bottom.
9044 // The point of exit cannot be a branch out of the structured block.
9045 // longjmp() and throw() must not violate the entry/exit criteria.
9046 CS->getCapturedDecl()->setNothrow();
9048 OMPLoopDirective::HelperExprs B;
9049 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9050 // define the nested loops number.
9051 unsigned NestedLoopCount =
9052 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9053 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9054 VarsWithImplicitDSA, B);
9055 if (NestedLoopCount == 0)
9058 assert((CurContext->isDependentContext() || B.builtAll()) &&
9059 "omp parallel for loop exprs were not built");
9061 if (!CurContext->isDependentContext()) {
9062 // Finalize the clauses that need pre-built expressions for CodeGen.
9063 for (OMPClause *C : Clauses) {
9064 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9065 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9066 B.NumIterations, *this, CurScope,
9072 setFunctionHasBranchProtectedScope();
9073 return OMPParallelForDirective::Create(
9074 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9075 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9078 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9079 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9080 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9084 auto *CS = cast<CapturedStmt>(AStmt);
9085 // 1.2.2 OpenMP Language Terminology
9086 // Structured block - An executable statement with a single entry at the
9087 // top and a single exit at the bottom.
9088 // The point of exit cannot be a branch out of the structured block.
9089 // longjmp() and throw() must not violate the entry/exit criteria.
9090 CS->getCapturedDecl()->setNothrow();
9092 OMPLoopDirective::HelperExprs B;
9093 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9094 // define the nested loops number.
9095 unsigned NestedLoopCount =
9096 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9097 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9098 VarsWithImplicitDSA, B);
9099 if (NestedLoopCount == 0)
9102 if (!CurContext->isDependentContext()) {
9103 // Finalize the clauses that need pre-built expressions for CodeGen.
9104 for (OMPClause *C : Clauses) {
9105 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9106 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9107 B.NumIterations, *this, CurScope,
9113 if (checkSimdlenSafelenSpecified(*this, Clauses))
9116 setFunctionHasBranchProtectedScope();
9117 return OMPParallelForSimdDirective::Create(
9118 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9122 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9123 Stmt *AStmt, SourceLocation StartLoc,
9124 SourceLocation EndLoc) {
9128 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9129 auto *CS = cast<CapturedStmt>(AStmt);
9130 // 1.2.2 OpenMP Language Terminology
9131 // Structured block - An executable statement with a single entry at the
9132 // top and a single exit at the bottom.
9133 // The point of exit cannot be a branch out of the structured block.
9134 // longjmp() and throw() must not violate the entry/exit criteria.
9135 CS->getCapturedDecl()->setNothrow();
9137 setFunctionHasBranchProtectedScope();
9139 return OMPParallelMasterDirective::Create(
9140 Context, StartLoc, EndLoc, Clauses, AStmt,
9141 DSAStack->getTaskgroupReductionRef());
9145 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9146 Stmt *AStmt, SourceLocation StartLoc,
9147 SourceLocation EndLoc) {
9151 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9152 auto BaseStmt = AStmt;
9153 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9154 BaseStmt = CS->getCapturedStmt();
9155 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9156 auto S = C->children();
9157 if (S.begin() == S.end())
9159 // All associated statements must be '#pragma omp section' except for
9161 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9162 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9164 Diag(SectionStmt->getBeginLoc(),
9165 diag::err_omp_parallel_sections_substmt_not_section);
9168 cast<OMPSectionDirective>(SectionStmt)
9169 ->setHasCancel(DSAStack->isCancelRegion());
9172 Diag(AStmt->getBeginLoc(),
9173 diag::err_omp_parallel_sections_not_compound_stmt);
9177 setFunctionHasBranchProtectedScope();
9179 return OMPParallelSectionsDirective::Create(
9180 Context, StartLoc, EndLoc, Clauses, AStmt,
9181 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9184 /// detach and mergeable clauses are mutially exclusive, check for it.
9185 static bool checkDetachMergeableClauses(Sema &S,
9186 ArrayRef<OMPClause *> Clauses) {
9187 const OMPClause *PrevClause = nullptr;
9188 bool ErrorFound = false;
9189 for (const OMPClause *C : Clauses) {
9190 if (C->getClauseKind() == OMPC_detach ||
9191 C->getClauseKind() == OMPC_mergeable) {
9194 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9195 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9196 << getOpenMPClauseName(C->getClauseKind())
9197 << getOpenMPClauseName(PrevClause->getClauseKind());
9198 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9199 << getOpenMPClauseName(PrevClause->getClauseKind());
9207 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9208 Stmt *AStmt, SourceLocation StartLoc,
9209 SourceLocation EndLoc) {
9213 // OpenMP 5.0, 2.10.1 task Construct
9214 // If a detach clause appears on the directive, then a mergeable clause cannot
9215 // appear on the same directive.
9216 if (checkDetachMergeableClauses(*this, Clauses))
9219 auto *CS = cast<CapturedStmt>(AStmt);
9220 // 1.2.2 OpenMP Language Terminology
9221 // Structured block - An executable statement with a single entry at the
9222 // top and a single exit at the bottom.
9223 // The point of exit cannot be a branch out of the structured block.
9224 // longjmp() and throw() must not violate the entry/exit criteria.
9225 CS->getCapturedDecl()->setNothrow();
9227 setFunctionHasBranchProtectedScope();
9229 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9230 DSAStack->isCancelRegion());
9233 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9234 SourceLocation EndLoc) {
9235 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9238 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9239 SourceLocation EndLoc) {
9240 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9243 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9244 SourceLocation EndLoc) {
9245 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9248 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9250 SourceLocation StartLoc,
9251 SourceLocation EndLoc) {
9255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9257 setFunctionHasBranchProtectedScope();
9259 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9261 DSAStack->getTaskgroupReductionRef());
9264 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9265 SourceLocation StartLoc,
9266 SourceLocation EndLoc) {
9267 OMPFlushClause *FC = nullptr;
9268 OMPClause *OrderClause = nullptr;
9269 for (OMPClause *C : Clauses) {
9270 if (C->getClauseKind() == OMPC_flush)
9271 FC = cast<OMPFlushClause>(C);
9275 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9276 SourceLocation MemOrderLoc;
9277 for (const OMPClause *C : Clauses) {
9278 if (C->getClauseKind() == OMPC_acq_rel ||
9279 C->getClauseKind() == OMPC_acquire ||
9280 C->getClauseKind() == OMPC_release) {
9281 if (MemOrderKind != OMPC_unknown) {
9282 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9283 << getOpenMPDirectiveName(OMPD_flush) << 1
9284 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9285 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9286 << getOpenMPClauseName(MemOrderKind);
9288 MemOrderKind = C->getClauseKind();
9289 MemOrderLoc = C->getBeginLoc();
9293 if (FC && OrderClause) {
9294 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9295 << getOpenMPClauseName(OrderClause->getClauseKind());
9296 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9297 << getOpenMPClauseName(OrderClause->getClauseKind());
9300 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9303 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9304 SourceLocation StartLoc,
9305 SourceLocation EndLoc) {
9306 if (Clauses.empty()) {
9307 Diag(StartLoc, diag::err_omp_depobj_expected);
9309 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9310 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9313 // Only depobj expression and another single clause is allowed.
9314 if (Clauses.size() > 2) {
9315 Diag(Clauses[2]->getBeginLoc(),
9316 diag::err_omp_depobj_single_clause_expected);
9318 } else if (Clauses.size() < 1) {
9319 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9322 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9325 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9326 SourceLocation StartLoc,
9327 SourceLocation EndLoc) {
9328 // Check that exactly one clause is specified.
9329 if (Clauses.size() != 1) {
9330 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9331 diag::err_omp_scan_single_clause_expected);
9334 // Check that scan directive is used in the scopeof the OpenMP loop body.
9335 if (Scope *S = DSAStack->getCurScope()) {
9336 Scope *ParentS = S->getParent();
9337 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9338 !ParentS->getBreakParent()->isOpenMPLoopScope())
9339 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9340 << getOpenMPDirectiveName(OMPD_scan) << 5);
9342 // Check that only one instance of scan directives is used in the same outer
9344 if (DSAStack->doesParentHasScanDirective()) {
9345 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9346 Diag(DSAStack->getParentScanDirectiveLoc(),
9347 diag::note_omp_previous_directive)
9351 DSAStack->setParentHasScanDirective(StartLoc);
9352 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9355 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9357 SourceLocation StartLoc,
9358 SourceLocation EndLoc) {
9359 const OMPClause *DependFound = nullptr;
9360 const OMPClause *DependSourceClause = nullptr;
9361 const OMPClause *DependSinkClause = nullptr;
9362 bool ErrorFound = false;
9363 const OMPThreadsClause *TC = nullptr;
9364 const OMPSIMDClause *SC = nullptr;
9365 for (const OMPClause *C : Clauses) {
9366 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9368 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9369 if (DependSourceClause) {
9370 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9371 << getOpenMPDirectiveName(OMPD_ordered)
9372 << getOpenMPClauseName(OMPC_depend) << 2;
9375 DependSourceClause = C;
9377 if (DependSinkClause) {
9378 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9382 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9383 if (DependSourceClause) {
9384 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9388 DependSinkClause = C;
9390 } else if (C->getClauseKind() == OMPC_threads) {
9391 TC = cast<OMPThreadsClause>(C);
9392 } else if (C->getClauseKind() == OMPC_simd) {
9393 SC = cast<OMPSIMDClause>(C);
9396 if (!ErrorFound && !SC &&
9397 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9398 // OpenMP [2.8.1,simd Construct, Restrictions]
9399 // An ordered construct with the simd clause is the only OpenMP construct
9400 // that can appear in the simd region.
9401 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9402 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9404 } else if (DependFound && (TC || SC)) {
9405 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9406 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9408 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9409 Diag(DependFound->getBeginLoc(),
9410 diag::err_omp_ordered_directive_without_param);
9412 } else if (TC || Clauses.empty()) {
9413 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9414 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9415 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9417 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9421 if ((!AStmt && !DependFound) || ErrorFound)
9424 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9425 // During execution of an iteration of a worksharing-loop or a loop nest
9426 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9427 // must not execute more than one ordered region corresponding to an ordered
9428 // construct without a depend clause.
9430 if (DSAStack->doesParentHasOrderedDirective()) {
9431 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9432 Diag(DSAStack->getParentOrderedDirectiveLoc(),
9433 diag::note_omp_previous_directive)
9437 DSAStack->setParentHasOrderedDirective(StartLoc);
9441 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9443 setFunctionHasBranchProtectedScope();
9446 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9450 /// Helper class for checking expression in 'omp atomic [update]'
9452 class OpenMPAtomicUpdateChecker {
9453 /// Error results for atomic update expressions.
9454 enum ExprAnalysisErrorCode {
9455 /// A statement is not an expression statement.
9457 /// Expression is not builtin binary or unary operation.
9458 NotABinaryOrUnaryExpression,
9459 /// Unary operation is not post-/pre- increment/decrement operation.
9460 NotAnUnaryIncDecExpression,
9461 /// An expression is not of scalar type.
9463 /// A binary operation is not an assignment operation.
9465 /// RHS part of the binary operation is not a binary expression.
9466 NotABinaryExpression,
9467 /// RHS part is not additive/multiplicative/shift/biwise binary
9470 /// RHS binary operation does not have reference to the updated LHS
9472 NotAnUpdateExpression,
9473 /// No errors is found.
9476 /// Reference to Sema.
9478 /// A location for note diagnostics (when error is found).
9479 SourceLocation NoteLoc;
9480 /// 'x' lvalue part of the source atomic expression.
9482 /// 'expr' rvalue part of the source atomic expression.
9484 /// Helper expression of the form
9485 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9486 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9488 /// Is 'x' a LHS in a RHS part of full update expression. It is
9489 /// important for non-associative operations.
9490 bool IsXLHSInRHSPart;
9491 BinaryOperatorKind Op;
9492 SourceLocation OpLoc;
9493 /// true if the source expression is a postfix unary operation, false
9494 /// if it is a prefix unary operation.
9495 bool IsPostfixUpdate;
9498 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9499 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9500 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9501 /// Check specified statement that it is suitable for 'atomic update'
9502 /// constructs and extract 'x', 'expr' and Operation from the original
9503 /// expression. If DiagId and NoteId == 0, then only check is performed
9504 /// without error notification.
9505 /// \param DiagId Diagnostic which should be emitted if error is found.
9506 /// \param NoteId Diagnostic note for the main error message.
9507 /// \return true if statement is not an update expression, false otherwise.
9508 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9509 /// Return the 'x' lvalue part of the source atomic expression.
9510 Expr *getX() const { return X; }
9511 /// Return the 'expr' rvalue part of the source atomic expression.
9512 Expr *getExpr() const { return E; }
9513 /// Return the update expression used in calculation of the updated
9514 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9515 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9516 Expr *getUpdateExpr() const { return UpdateExpr; }
9517 /// Return true if 'x' is LHS in RHS part of full update expression,
9518 /// false otherwise.
9519 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9521 /// true if the source expression is a postfix unary operation, false
9522 /// if it is a prefix unary operation.
9523 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9526 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9527 unsigned NoteId = 0);
9531 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9532 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9533 ExprAnalysisErrorCode ErrorFound = NoError;
9534 SourceLocation ErrorLoc, NoteLoc;
9535 SourceRange ErrorRange, NoteRange;
9536 // Allowed constructs are:
9537 // x = x binop expr;
9538 // x = expr binop x;
9539 if (AtomicBinOp->getOpcode() == BO_Assign) {
9540 X = AtomicBinOp->getLHS();
9541 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9542 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9543 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9544 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9545 AtomicInnerBinOp->isBitwiseOp()) {
9546 Op = AtomicInnerBinOp->getOpcode();
9547 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9548 Expr *LHS = AtomicInnerBinOp->getLHS();
9549 Expr *RHS = AtomicInnerBinOp->getRHS();
9550 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9551 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9552 /*Canonical=*/true);
9553 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9554 /*Canonical=*/true);
9555 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9556 /*Canonical=*/true);
9559 IsXLHSInRHSPart = true;
9560 } else if (XId == RHSId) {
9562 IsXLHSInRHSPart = false;
9564 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9565 ErrorRange = AtomicInnerBinOp->getSourceRange();
9566 NoteLoc = X->getExprLoc();
9567 NoteRange = X->getSourceRange();
9568 ErrorFound = NotAnUpdateExpression;
9571 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9572 ErrorRange = AtomicInnerBinOp->getSourceRange();
9573 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9574 NoteRange = SourceRange(NoteLoc, NoteLoc);
9575 ErrorFound = NotABinaryOperator;
9578 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9579 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9580 ErrorFound = NotABinaryExpression;
9583 ErrorLoc = AtomicBinOp->getExprLoc();
9584 ErrorRange = AtomicBinOp->getSourceRange();
9585 NoteLoc = AtomicBinOp->getOperatorLoc();
9586 NoteRange = SourceRange(NoteLoc, NoteLoc);
9587 ErrorFound = NotAnAssignmentOp;
9589 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9590 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9591 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9594 if (SemaRef.CurContext->isDependentContext())
9595 E = X = UpdateExpr = nullptr;
9596 return ErrorFound != NoError;
9599 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9601 ExprAnalysisErrorCode ErrorFound = NoError;
9602 SourceLocation ErrorLoc, NoteLoc;
9603 SourceRange ErrorRange, NoteRange;
9604 // Allowed constructs are:
9610 // x = x binop expr;
9611 // x = expr binop x;
9612 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9613 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9614 if (AtomicBody->getType()->isScalarType() ||
9615 AtomicBody->isInstantiationDependent()) {
9616 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9617 AtomicBody->IgnoreParenImpCasts())) {
9618 // Check for Compound Assignment Operation
9619 Op = BinaryOperator::getOpForCompoundAssignment(
9620 AtomicCompAssignOp->getOpcode());
9621 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9622 E = AtomicCompAssignOp->getRHS();
9623 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9624 IsXLHSInRHSPart = true;
9625 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9626 AtomicBody->IgnoreParenImpCasts())) {
9627 // Check for Binary Operation
9628 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9630 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9631 AtomicBody->IgnoreParenImpCasts())) {
9632 // Check for Unary Operation
9633 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9634 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9635 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9636 OpLoc = AtomicUnaryOp->getOperatorLoc();
9637 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9638 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9639 IsXLHSInRHSPart = true;
9641 ErrorFound = NotAnUnaryIncDecExpression;
9642 ErrorLoc = AtomicUnaryOp->getExprLoc();
9643 ErrorRange = AtomicUnaryOp->getSourceRange();
9644 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9645 NoteRange = SourceRange(NoteLoc, NoteLoc);
9647 } else if (!AtomicBody->isInstantiationDependent()) {
9648 ErrorFound = NotABinaryOrUnaryExpression;
9649 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9650 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9653 ErrorFound = NotAScalarType;
9654 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9655 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9658 ErrorFound = NotAnExpression;
9659 NoteLoc = ErrorLoc = S->getBeginLoc();
9660 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9662 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9663 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9664 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9667 if (SemaRef.CurContext->isDependentContext())
9668 E = X = UpdateExpr = nullptr;
9669 if (ErrorFound == NoError && E && X) {
9670 // Build an update expression of form 'OpaqueValueExpr(x) binop
9671 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9672 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9673 auto *OVEX = new (SemaRef.getASTContext())
9674 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9675 auto *OVEExpr = new (SemaRef.getASTContext())
9676 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9678 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9679 IsXLHSInRHSPart ? OVEExpr : OVEX);
9680 if (Update.isInvalid())
9682 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9684 if (Update.isInvalid())
9686 UpdateExpr = Update.get();
9688 return ErrorFound != NoError;
9691 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9693 SourceLocation StartLoc,
9694 SourceLocation EndLoc) {
9695 // Register location of the first atomic directive.
9696 DSAStack->addAtomicDirectiveLoc(StartLoc);
9700 auto *CS = cast<CapturedStmt>(AStmt);
9701 // 1.2.2 OpenMP Language Terminology
9702 // Structured block - An executable statement with a single entry at the
9703 // top and a single exit at the bottom.
9704 // The point of exit cannot be a branch out of the structured block.
9705 // longjmp() and throw() must not violate the entry/exit criteria.
9706 OpenMPClauseKind AtomicKind = OMPC_unknown;
9707 SourceLocation AtomicKindLoc;
9708 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9709 SourceLocation MemOrderLoc;
9710 for (const OMPClause *C : Clauses) {
9711 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9712 C->getClauseKind() == OMPC_update ||
9713 C->getClauseKind() == OMPC_capture) {
9714 if (AtomicKind != OMPC_unknown) {
9715 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9716 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9717 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9718 << getOpenMPClauseName(AtomicKind);
9720 AtomicKind = C->getClauseKind();
9721 AtomicKindLoc = C->getBeginLoc();
9724 if (C->getClauseKind() == OMPC_seq_cst ||
9725 C->getClauseKind() == OMPC_acq_rel ||
9726 C->getClauseKind() == OMPC_acquire ||
9727 C->getClauseKind() == OMPC_release ||
9728 C->getClauseKind() == OMPC_relaxed) {
9729 if (MemOrderKind != OMPC_unknown) {
9730 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9731 << getOpenMPDirectiveName(OMPD_atomic) << 0
9732 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9733 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9734 << getOpenMPClauseName(MemOrderKind);
9736 MemOrderKind = C->getClauseKind();
9737 MemOrderLoc = C->getBeginLoc();
9741 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9742 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9744 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9746 // If atomic-clause is update or not present then memory-order-clause must not
9747 // be acq_rel or acquire.
9748 if ((AtomicKind == OMPC_read &&
9749 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9750 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9751 AtomicKind == OMPC_unknown) &&
9752 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9753 SourceLocation Loc = AtomicKindLoc;
9754 if (AtomicKind == OMPC_unknown)
9756 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9757 << getOpenMPClauseName(AtomicKind)
9758 << (AtomicKind == OMPC_unknown ? 1 : 0)
9759 << getOpenMPClauseName(MemOrderKind);
9760 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9761 << getOpenMPClauseName(MemOrderKind);
9764 Stmt *Body = CS->getCapturedStmt();
9765 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9766 Body = EWC->getSubExpr();
9772 bool IsXLHSInRHSPart = false;
9773 bool IsPostfixUpdate = false;
9774 // OpenMP [2.12.6, atomic Construct]
9775 // In the next expressions:
9776 // * x and v (as applicable) are both l-value expressions with scalar type.
9777 // * During the execution of an atomic region, multiple syntactic
9778 // occurrences of x must designate the same storage location.
9779 // * Neither of v and expr (as applicable) may access the storage location
9781 // * Neither of x and expr (as applicable) may access the storage location
9783 // * expr is an expression with scalar type.
9784 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9785 // * binop, binop=, ++, and -- are not overloaded operators.
9786 // * The expression x binop expr must be numerically equivalent to x binop
9787 // (expr). This requirement is satisfied if the operators in expr have
9788 // precedence greater than binop, or by using parentheses around expr or
9789 // subexpressions of expr.
9790 // * The expression expr binop x must be numerically equivalent to (expr)
9791 // binop x. This requirement is satisfied if the operators in expr have
9792 // precedence equal to or greater than binop, or by using parentheses around
9793 // expr or subexpressions of expr.
9794 // * For forms that allow multiple occurrences of x, the number of times
9795 // that x is evaluated is unspecified.
9796 if (AtomicKind == OMPC_read) {
9803 } ErrorFound = NoError;
9804 SourceLocation ErrorLoc, NoteLoc;
9805 SourceRange ErrorRange, NoteRange;
9806 // If clause is read:
9808 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9809 const auto *AtomicBinOp =
9810 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9811 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9812 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9813 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9814 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9815 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9816 if (!X->isLValue() || !V->isLValue()) {
9817 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9818 ErrorFound = NotAnLValue;
9819 ErrorLoc = AtomicBinOp->getExprLoc();
9820 ErrorRange = AtomicBinOp->getSourceRange();
9821 NoteLoc = NotLValueExpr->getExprLoc();
9822 NoteRange = NotLValueExpr->getSourceRange();
9824 } else if (!X->isInstantiationDependent() ||
9825 !V->isInstantiationDependent()) {
9826 const Expr *NotScalarExpr =
9827 (X->isInstantiationDependent() || X->getType()->isScalarType())
9830 ErrorFound = NotAScalarType;
9831 ErrorLoc = AtomicBinOp->getExprLoc();
9832 ErrorRange = AtomicBinOp->getSourceRange();
9833 NoteLoc = NotScalarExpr->getExprLoc();
9834 NoteRange = NotScalarExpr->getSourceRange();
9836 } else if (!AtomicBody->isInstantiationDependent()) {
9837 ErrorFound = NotAnAssignmentOp;
9838 ErrorLoc = AtomicBody->getExprLoc();
9839 ErrorRange = AtomicBody->getSourceRange();
9840 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9841 : AtomicBody->getExprLoc();
9842 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9843 : AtomicBody->getSourceRange();
9846 ErrorFound = NotAnExpression;
9847 NoteLoc = ErrorLoc = Body->getBeginLoc();
9848 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9850 if (ErrorFound != NoError) {
9851 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9853 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9857 if (CurContext->isDependentContext())
9859 } else if (AtomicKind == OMPC_write) {
9866 } ErrorFound = NoError;
9867 SourceLocation ErrorLoc, NoteLoc;
9868 SourceRange ErrorRange, NoteRange;
9869 // If clause is write:
9871 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9872 const auto *AtomicBinOp =
9873 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9874 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9875 X = AtomicBinOp->getLHS();
9876 E = AtomicBinOp->getRHS();
9877 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9878 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
9879 if (!X->isLValue()) {
9880 ErrorFound = NotAnLValue;
9881 ErrorLoc = AtomicBinOp->getExprLoc();
9882 ErrorRange = AtomicBinOp->getSourceRange();
9883 NoteLoc = X->getExprLoc();
9884 NoteRange = X->getSourceRange();
9886 } else if (!X->isInstantiationDependent() ||
9887 !E->isInstantiationDependent()) {
9888 const Expr *NotScalarExpr =
9889 (X->isInstantiationDependent() || X->getType()->isScalarType())
9892 ErrorFound = NotAScalarType;
9893 ErrorLoc = AtomicBinOp->getExprLoc();
9894 ErrorRange = AtomicBinOp->getSourceRange();
9895 NoteLoc = NotScalarExpr->getExprLoc();
9896 NoteRange = NotScalarExpr->getSourceRange();
9898 } else if (!AtomicBody->isInstantiationDependent()) {
9899 ErrorFound = NotAnAssignmentOp;
9900 ErrorLoc = AtomicBody->getExprLoc();
9901 ErrorRange = AtomicBody->getSourceRange();
9902 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9903 : AtomicBody->getExprLoc();
9904 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9905 : AtomicBody->getSourceRange();
9908 ErrorFound = NotAnExpression;
9909 NoteLoc = ErrorLoc = Body->getBeginLoc();
9910 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9912 if (ErrorFound != NoError) {
9913 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
9915 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9919 if (CurContext->isDependentContext())
9921 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
9922 // If clause is update:
9928 // x = x binop expr;
9929 // x = expr binop x;
9930 OpenMPAtomicUpdateChecker Checker(*this);
9931 if (Checker.checkStatement(
9932 Body, (AtomicKind == OMPC_update)
9933 ? diag::err_omp_atomic_update_not_expression_statement
9934 : diag::err_omp_atomic_not_expression_statement,
9935 diag::note_omp_atomic_update))
9937 if (!CurContext->isDependentContext()) {
9938 E = Checker.getExpr();
9940 UE = Checker.getUpdateExpr();
9941 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9943 } else if (AtomicKind == OMPC_capture) {
9946 NotACompoundStatement,
9947 NotTwoSubstatements,
9948 NotASpecificExpression,
9950 } ErrorFound = NoError;
9951 SourceLocation ErrorLoc, NoteLoc;
9952 SourceRange ErrorRange, NoteRange;
9953 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9954 // If clause is a capture:
9959 // v = x binop= expr;
9960 // v = x = x binop expr;
9961 // v = x = expr binop x;
9962 const auto *AtomicBinOp =
9963 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9964 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9965 V = AtomicBinOp->getLHS();
9966 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9967 OpenMPAtomicUpdateChecker Checker(*this);
9968 if (Checker.checkStatement(
9969 Body, diag::err_omp_atomic_capture_not_expression_statement,
9970 diag::note_omp_atomic_update))
9972 E = Checker.getExpr();
9974 UE = Checker.getUpdateExpr();
9975 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9976 IsPostfixUpdate = Checker.isPostfixUpdate();
9977 } else if (!AtomicBody->isInstantiationDependent()) {
9978 ErrorLoc = AtomicBody->getExprLoc();
9979 ErrorRange = AtomicBody->getSourceRange();
9980 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9981 : AtomicBody->getExprLoc();
9982 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9983 : AtomicBody->getSourceRange();
9984 ErrorFound = NotAnAssignmentOp;
9986 if (ErrorFound != NoError) {
9987 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
9989 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9992 if (CurContext->isDependentContext())
9993 UE = V = E = X = nullptr;
9995 // If clause is a capture:
9996 // { v = x; x = expr; }
10001 // { v = x; x binop= expr; }
10002 // { v = x; x = x binop expr; }
10003 // { v = x; x = expr binop x; }
10008 // { x binop= expr; v = x; }
10009 // { x = x binop expr; v = x; }
10010 // { x = expr binop x; v = x; }
10011 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10012 // Check that this is { expr1; expr2; }
10013 if (CS->size() == 2) {
10014 Stmt *First = CS->body_front();
10015 Stmt *Second = CS->body_back();
10016 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10017 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10018 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10019 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10020 // Need to find what subexpression is 'v' and what is 'x'.
10021 OpenMPAtomicUpdateChecker Checker(*this);
10022 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10023 BinaryOperator *BinOp = nullptr;
10024 if (IsUpdateExprFound) {
10025 BinOp = dyn_cast<BinaryOperator>(First);
10026 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10028 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10033 // { v = x; x binop= expr; }
10034 // { v = x; x = x binop expr; }
10035 // { v = x; x = expr binop x; }
10036 // Check that the first expression has form v = x.
10037 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10038 llvm::FoldingSetNodeID XId, PossibleXId;
10039 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10040 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10041 IsUpdateExprFound = XId == PossibleXId;
10042 if (IsUpdateExprFound) {
10043 V = BinOp->getLHS();
10044 X = Checker.getX();
10045 E = Checker.getExpr();
10046 UE = Checker.getUpdateExpr();
10047 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10048 IsPostfixUpdate = true;
10051 if (!IsUpdateExprFound) {
10052 IsUpdateExprFound = !Checker.checkStatement(First);
10054 if (IsUpdateExprFound) {
10055 BinOp = dyn_cast<BinaryOperator>(Second);
10056 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10058 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10063 // { x binop= expr; v = x; }
10064 // { x = x binop expr; v = x; }
10065 // { x = expr binop x; v = x; }
10066 // Check that the second expression has form v = x.
10067 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10068 llvm::FoldingSetNodeID XId, PossibleXId;
10069 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10070 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10071 IsUpdateExprFound = XId == PossibleXId;
10072 if (IsUpdateExprFound) {
10073 V = BinOp->getLHS();
10074 X = Checker.getX();
10075 E = Checker.getExpr();
10076 UE = Checker.getUpdateExpr();
10077 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10078 IsPostfixUpdate = false;
10082 if (!IsUpdateExprFound) {
10083 // { v = x; x = expr; }
10084 auto *FirstExpr = dyn_cast<Expr>(First);
10085 auto *SecondExpr = dyn_cast<Expr>(Second);
10086 if (!FirstExpr || !SecondExpr ||
10087 !(FirstExpr->isInstantiationDependent() ||
10088 SecondExpr->isInstantiationDependent())) {
10089 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10090 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10091 ErrorFound = NotAnAssignmentOp;
10092 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10093 : First->getBeginLoc();
10094 NoteRange = ErrorRange = FirstBinOp
10095 ? FirstBinOp->getSourceRange()
10096 : SourceRange(ErrorLoc, ErrorLoc);
10098 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10099 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10100 ErrorFound = NotAnAssignmentOp;
10101 NoteLoc = ErrorLoc = SecondBinOp
10102 ? SecondBinOp->getOperatorLoc()
10103 : Second->getBeginLoc();
10104 NoteRange = ErrorRange =
10105 SecondBinOp ? SecondBinOp->getSourceRange()
10106 : SourceRange(ErrorLoc, ErrorLoc);
10108 Expr *PossibleXRHSInFirst =
10109 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10110 Expr *PossibleXLHSInSecond =
10111 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10112 llvm::FoldingSetNodeID X1Id, X2Id;
10113 PossibleXRHSInFirst->Profile(X1Id, Context,
10114 /*Canonical=*/true);
10115 PossibleXLHSInSecond->Profile(X2Id, Context,
10116 /*Canonical=*/true);
10117 IsUpdateExprFound = X1Id == X2Id;
10118 if (IsUpdateExprFound) {
10119 V = FirstBinOp->getLHS();
10120 X = SecondBinOp->getLHS();
10121 E = SecondBinOp->getRHS();
10123 IsXLHSInRHSPart = false;
10124 IsPostfixUpdate = true;
10126 ErrorFound = NotASpecificExpression;
10127 ErrorLoc = FirstBinOp->getExprLoc();
10128 ErrorRange = FirstBinOp->getSourceRange();
10129 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10130 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10137 NoteLoc = ErrorLoc = Body->getBeginLoc();
10138 NoteRange = ErrorRange =
10139 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10140 ErrorFound = NotTwoSubstatements;
10143 NoteLoc = ErrorLoc = Body->getBeginLoc();
10144 NoteRange = ErrorRange =
10145 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10146 ErrorFound = NotACompoundStatement;
10148 if (ErrorFound != NoError) {
10149 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10151 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10152 return StmtError();
10154 if (CurContext->isDependentContext())
10155 UE = V = E = X = nullptr;
10159 setFunctionHasBranchProtectedScope();
10161 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10162 X, V, E, UE, IsXLHSInRHSPart,
10166 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10168 SourceLocation StartLoc,
10169 SourceLocation EndLoc) {
10171 return StmtError();
10173 auto *CS = cast<CapturedStmt>(AStmt);
10174 // 1.2.2 OpenMP Language Terminology
10175 // Structured block - An executable statement with a single entry at the
10176 // top and a single exit at the bottom.
10177 // The point of exit cannot be a branch out of the structured block.
10178 // longjmp() and throw() must not violate the entry/exit criteria.
10179 CS->getCapturedDecl()->setNothrow();
10180 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10181 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10182 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10183 // 1.2.2 OpenMP Language Terminology
10184 // Structured block - An executable statement with a single entry at the
10185 // top and a single exit at the bottom.
10186 // The point of exit cannot be a branch out of the structured block.
10187 // longjmp() and throw() must not violate the entry/exit criteria.
10188 CS->getCapturedDecl()->setNothrow();
10191 // OpenMP [2.16, Nesting of Regions]
10192 // If specified, a teams construct must be contained within a target
10193 // construct. That target construct must contain no statements or directives
10194 // outside of the teams construct.
10195 if (DSAStack->hasInnerTeamsRegion()) {
10196 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10197 bool OMPTeamsFound = true;
10198 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10199 auto I = CS->body_begin();
10200 while (I != CS->body_end()) {
10201 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10202 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10205 OMPTeamsFound = false;
10210 assert(I != CS->body_end() && "Not found statement");
10213 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10214 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10216 if (!OMPTeamsFound) {
10217 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10218 Diag(DSAStack->getInnerTeamsRegionLoc(),
10219 diag::note_omp_nested_teams_construct_here);
10220 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10221 << isa<OMPExecutableDirective>(S);
10222 return StmtError();
10226 setFunctionHasBranchProtectedScope();
10228 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10232 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10233 Stmt *AStmt, SourceLocation StartLoc,
10234 SourceLocation EndLoc) {
10236 return StmtError();
10238 auto *CS = cast<CapturedStmt>(AStmt);
10239 // 1.2.2 OpenMP Language Terminology
10240 // Structured block - An executable statement with a single entry at the
10241 // top and a single exit at the bottom.
10242 // The point of exit cannot be a branch out of the structured block.
10243 // longjmp() and throw() must not violate the entry/exit criteria.
10244 CS->getCapturedDecl()->setNothrow();
10245 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10246 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10247 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10248 // 1.2.2 OpenMP Language Terminology
10249 // Structured block - An executable statement with a single entry at the
10250 // top and a single exit at the bottom.
10251 // The point of exit cannot be a branch out of the structured block.
10252 // longjmp() and throw() must not violate the entry/exit criteria.
10253 CS->getCapturedDecl()->setNothrow();
10256 setFunctionHasBranchProtectedScope();
10258 return OMPTargetParallelDirective::Create(
10259 Context, StartLoc, EndLoc, Clauses, AStmt,
10260 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10263 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10264 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10265 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10267 return StmtError();
10269 auto *CS = cast<CapturedStmt>(AStmt);
10270 // 1.2.2 OpenMP Language Terminology
10271 // Structured block - An executable statement with a single entry at the
10272 // top and a single exit at the bottom.
10273 // The point of exit cannot be a branch out of the structured block.
10274 // longjmp() and throw() must not violate the entry/exit criteria.
10275 CS->getCapturedDecl()->setNothrow();
10276 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10277 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10278 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10279 // 1.2.2 OpenMP Language Terminology
10280 // Structured block - An executable statement with a single entry at the
10281 // top and a single exit at the bottom.
10282 // The point of exit cannot be a branch out of the structured block.
10283 // longjmp() and throw() must not violate the entry/exit criteria.
10284 CS->getCapturedDecl()->setNothrow();
10287 OMPLoopDirective::HelperExprs B;
10288 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10289 // define the nested loops number.
10290 unsigned NestedLoopCount =
10291 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10292 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10293 VarsWithImplicitDSA, B);
10294 if (NestedLoopCount == 0)
10295 return StmtError();
10297 assert((CurContext->isDependentContext() || B.builtAll()) &&
10298 "omp target parallel for loop exprs were not built");
10300 if (!CurContext->isDependentContext()) {
10301 // Finalize the clauses that need pre-built expressions for CodeGen.
10302 for (OMPClause *C : Clauses) {
10303 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10304 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10305 B.NumIterations, *this, CurScope,
10307 return StmtError();
10311 setFunctionHasBranchProtectedScope();
10312 return OMPTargetParallelForDirective::Create(
10313 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10314 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10317 /// Check for existence of a map clause in the list of clauses.
10318 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10319 const OpenMPClauseKind K) {
10320 return llvm::any_of(
10321 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10324 template <typename... Params>
10325 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10326 const Params... ClauseTypes) {
10327 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10330 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10332 SourceLocation StartLoc,
10333 SourceLocation EndLoc) {
10335 return StmtError();
10337 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10339 // OpenMP [2.12.2, target data Construct, Restrictions]
10340 // At least one map, use_device_addr or use_device_ptr clause must appear on
10342 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10343 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10344 StringRef Expected;
10345 if (LangOpts.OpenMP < 50)
10346 Expected = "'map' or 'use_device_ptr'";
10348 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10349 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10350 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10351 return StmtError();
10354 setFunctionHasBranchProtectedScope();
10356 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10361 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10362 SourceLocation StartLoc,
10363 SourceLocation EndLoc, Stmt *AStmt) {
10365 return StmtError();
10367 auto *CS = cast<CapturedStmt>(AStmt);
10368 // 1.2.2 OpenMP Language Terminology
10369 // Structured block - An executable statement with a single entry at the
10370 // top and a single exit at the bottom.
10371 // The point of exit cannot be a branch out of the structured block.
10372 // longjmp() and throw() must not violate the entry/exit criteria.
10373 CS->getCapturedDecl()->setNothrow();
10374 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10375 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10376 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10377 // 1.2.2 OpenMP Language Terminology
10378 // Structured block - An executable statement with a single entry at the
10379 // top and a single exit at the bottom.
10380 // The point of exit cannot be a branch out of the structured block.
10381 // longjmp() and throw() must not violate the entry/exit criteria.
10382 CS->getCapturedDecl()->setNothrow();
10385 // OpenMP [2.10.2, Restrictions, p. 99]
10386 // At least one map clause must appear on the directive.
10387 if (!hasClauses(Clauses, OMPC_map)) {
10388 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10389 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10390 return StmtError();
10393 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10398 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10399 SourceLocation StartLoc,
10400 SourceLocation EndLoc, Stmt *AStmt) {
10402 return StmtError();
10404 auto *CS = cast<CapturedStmt>(AStmt);
10405 // 1.2.2 OpenMP Language Terminology
10406 // Structured block - An executable statement with a single entry at the
10407 // top and a single exit at the bottom.
10408 // The point of exit cannot be a branch out of the structured block.
10409 // longjmp() and throw() must not violate the entry/exit criteria.
10410 CS->getCapturedDecl()->setNothrow();
10411 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10412 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10413 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10414 // 1.2.2 OpenMP Language Terminology
10415 // Structured block - An executable statement with a single entry at the
10416 // top and a single exit at the bottom.
10417 // The point of exit cannot be a branch out of the structured block.
10418 // longjmp() and throw() must not violate the entry/exit criteria.
10419 CS->getCapturedDecl()->setNothrow();
10422 // OpenMP [2.10.3, Restrictions, p. 102]
10423 // At least one map clause must appear on the directive.
10424 if (!hasClauses(Clauses, OMPC_map)) {
10425 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10426 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10427 return StmtError();
10430 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10434 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10435 SourceLocation StartLoc,
10436 SourceLocation EndLoc,
10439 return StmtError();
10441 auto *CS = cast<CapturedStmt>(AStmt);
10442 // 1.2.2 OpenMP Language Terminology
10443 // Structured block - An executable statement with a single entry at the
10444 // top and a single exit at the bottom.
10445 // The point of exit cannot be a branch out of the structured block.
10446 // longjmp() and throw() must not violate the entry/exit criteria.
10447 CS->getCapturedDecl()->setNothrow();
10448 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10449 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10450 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10451 // 1.2.2 OpenMP Language Terminology
10452 // Structured block - An executable statement with a single entry at the
10453 // top and a single exit at the bottom.
10454 // The point of exit cannot be a branch out of the structured block.
10455 // longjmp() and throw() must not violate the entry/exit criteria.
10456 CS->getCapturedDecl()->setNothrow();
10459 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10460 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10461 return StmtError();
10463 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10467 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10468 Stmt *AStmt, SourceLocation StartLoc,
10469 SourceLocation EndLoc) {
10471 return StmtError();
10473 auto *CS = cast<CapturedStmt>(AStmt);
10474 // 1.2.2 OpenMP Language Terminology
10475 // Structured block - An executable statement with a single entry at the
10476 // top and a single exit at the bottom.
10477 // The point of exit cannot be a branch out of the structured block.
10478 // longjmp() and throw() must not violate the entry/exit criteria.
10479 CS->getCapturedDecl()->setNothrow();
10481 setFunctionHasBranchProtectedScope();
10483 DSAStack->setParentTeamsRegionLoc(StartLoc);
10485 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10489 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10490 SourceLocation EndLoc,
10491 OpenMPDirectiveKind CancelRegion) {
10492 if (DSAStack->isParentNowaitRegion()) {
10493 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10494 return StmtError();
10496 if (DSAStack->isParentOrderedRegion()) {
10497 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10498 return StmtError();
10500 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10504 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10505 SourceLocation StartLoc,
10506 SourceLocation EndLoc,
10507 OpenMPDirectiveKind CancelRegion) {
10508 if (DSAStack->isParentNowaitRegion()) {
10509 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10510 return StmtError();
10512 if (DSAStack->isParentOrderedRegion()) {
10513 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10514 return StmtError();
10516 DSAStack->setParentCancelRegion(/*Cancel=*/true);
10517 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10521 static bool checkGrainsizeNumTasksClauses(Sema &S,
10522 ArrayRef<OMPClause *> Clauses) {
10523 const OMPClause *PrevClause = nullptr;
10524 bool ErrorFound = false;
10525 for (const OMPClause *C : Clauses) {
10526 if (C->getClauseKind() == OMPC_grainsize ||
10527 C->getClauseKind() == OMPC_num_tasks) {
10530 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10531 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10532 << getOpenMPClauseName(C->getClauseKind())
10533 << getOpenMPClauseName(PrevClause->getClauseKind());
10534 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10535 << getOpenMPClauseName(PrevClause->getClauseKind());
10543 static bool checkReductionClauseWithNogroup(Sema &S,
10544 ArrayRef<OMPClause *> Clauses) {
10545 const OMPClause *ReductionClause = nullptr;
10546 const OMPClause *NogroupClause = nullptr;
10547 for (const OMPClause *C : Clauses) {
10548 if (C->getClauseKind() == OMPC_reduction) {
10549 ReductionClause = C;
10554 if (C->getClauseKind() == OMPC_nogroup) {
10556 if (ReductionClause)
10561 if (ReductionClause && NogroupClause) {
10562 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10563 << SourceRange(NogroupClause->getBeginLoc(),
10564 NogroupClause->getEndLoc());
10570 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10571 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10572 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10574 return StmtError();
10576 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10577 OMPLoopDirective::HelperExprs B;
10578 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10579 // define the nested loops number.
10580 unsigned NestedLoopCount =
10581 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10582 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10583 VarsWithImplicitDSA, B);
10584 if (NestedLoopCount == 0)
10585 return StmtError();
10587 assert((CurContext->isDependentContext() || B.builtAll()) &&
10588 "omp for loop exprs were not built");
10590 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10591 // The grainsize clause and num_tasks clause are mutually exclusive and may
10592 // not appear on the same taskloop directive.
10593 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10594 return StmtError();
10595 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10596 // If a reduction clause is present on the taskloop directive, the nogroup
10597 // clause must not be specified.
10598 if (checkReductionClauseWithNogroup(*this, Clauses))
10599 return StmtError();
10601 setFunctionHasBranchProtectedScope();
10602 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10603 NestedLoopCount, Clauses, AStmt, B,
10604 DSAStack->isCancelRegion());
10607 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10608 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10609 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10611 return StmtError();
10613 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10614 OMPLoopDirective::HelperExprs B;
10615 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10616 // define the nested loops number.
10617 unsigned NestedLoopCount =
10618 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10619 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10620 VarsWithImplicitDSA, B);
10621 if (NestedLoopCount == 0)
10622 return StmtError();
10624 assert((CurContext->isDependentContext() || B.builtAll()) &&
10625 "omp for loop exprs were not built");
10627 if (!CurContext->isDependentContext()) {
10628 // Finalize the clauses that need pre-built expressions for CodeGen.
10629 for (OMPClause *C : Clauses) {
10630 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10631 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10632 B.NumIterations, *this, CurScope,
10634 return StmtError();
10638 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10639 // The grainsize clause and num_tasks clause are mutually exclusive and may
10640 // not appear on the same taskloop directive.
10641 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10642 return StmtError();
10643 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10644 // If a reduction clause is present on the taskloop directive, the nogroup
10645 // clause must not be specified.
10646 if (checkReductionClauseWithNogroup(*this, Clauses))
10647 return StmtError();
10648 if (checkSimdlenSafelenSpecified(*this, Clauses))
10649 return StmtError();
10651 setFunctionHasBranchProtectedScope();
10652 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10653 NestedLoopCount, Clauses, AStmt, B);
10656 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10657 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10658 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10660 return StmtError();
10662 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10663 OMPLoopDirective::HelperExprs B;
10664 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10665 // define the nested loops number.
10666 unsigned NestedLoopCount =
10667 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10668 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10669 VarsWithImplicitDSA, B);
10670 if (NestedLoopCount == 0)
10671 return StmtError();
10673 assert((CurContext->isDependentContext() || B.builtAll()) &&
10674 "omp for loop exprs were not built");
10676 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10677 // The grainsize clause and num_tasks clause are mutually exclusive and may
10678 // not appear on the same taskloop directive.
10679 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10680 return StmtError();
10681 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10682 // If a reduction clause is present on the taskloop directive, the nogroup
10683 // clause must not be specified.
10684 if (checkReductionClauseWithNogroup(*this, Clauses))
10685 return StmtError();
10687 setFunctionHasBranchProtectedScope();
10688 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10689 NestedLoopCount, Clauses, AStmt, B,
10690 DSAStack->isCancelRegion());
10693 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10694 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10695 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10697 return StmtError();
10699 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10700 OMPLoopDirective::HelperExprs B;
10701 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10702 // define the nested loops number.
10703 unsigned NestedLoopCount =
10704 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10705 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10706 VarsWithImplicitDSA, B);
10707 if (NestedLoopCount == 0)
10708 return StmtError();
10710 assert((CurContext->isDependentContext() || B.builtAll()) &&
10711 "omp for loop exprs were not built");
10713 if (!CurContext->isDependentContext()) {
10714 // Finalize the clauses that need pre-built expressions for CodeGen.
10715 for (OMPClause *C : Clauses) {
10716 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10717 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10718 B.NumIterations, *this, CurScope,
10720 return StmtError();
10724 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10725 // The grainsize clause and num_tasks clause are mutually exclusive and may
10726 // not appear on the same taskloop directive.
10727 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10728 return StmtError();
10729 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10730 // If a reduction clause is present on the taskloop directive, the nogroup
10731 // clause must not be specified.
10732 if (checkReductionClauseWithNogroup(*this, Clauses))
10733 return StmtError();
10734 if (checkSimdlenSafelenSpecified(*this, Clauses))
10735 return StmtError();
10737 setFunctionHasBranchProtectedScope();
10738 return OMPMasterTaskLoopSimdDirective::Create(
10739 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10742 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10743 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10744 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10746 return StmtError();
10748 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10749 auto *CS = cast<CapturedStmt>(AStmt);
10750 // 1.2.2 OpenMP Language Terminology
10751 // Structured block - An executable statement with a single entry at the
10752 // top and a single exit at the bottom.
10753 // The point of exit cannot be a branch out of the structured block.
10754 // longjmp() and throw() must not violate the entry/exit criteria.
10755 CS->getCapturedDecl()->setNothrow();
10756 for (int ThisCaptureLevel =
10757 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10758 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10759 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10760 // 1.2.2 OpenMP Language Terminology
10761 // Structured block - An executable statement with a single entry at the
10762 // top and a single exit at the bottom.
10763 // The point of exit cannot be a branch out of the structured block.
10764 // longjmp() and throw() must not violate the entry/exit criteria.
10765 CS->getCapturedDecl()->setNothrow();
10768 OMPLoopDirective::HelperExprs B;
10769 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10770 // define the nested loops number.
10771 unsigned NestedLoopCount = checkOpenMPLoop(
10772 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10773 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10774 VarsWithImplicitDSA, B);
10775 if (NestedLoopCount == 0)
10776 return StmtError();
10778 assert((CurContext->isDependentContext() || B.builtAll()) &&
10779 "omp for loop exprs were not built");
10781 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10782 // The grainsize clause and num_tasks clause are mutually exclusive and may
10783 // not appear on the same taskloop directive.
10784 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10785 return StmtError();
10786 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10787 // If a reduction clause is present on the taskloop directive, the nogroup
10788 // clause must not be specified.
10789 if (checkReductionClauseWithNogroup(*this, Clauses))
10790 return StmtError();
10792 setFunctionHasBranchProtectedScope();
10793 return OMPParallelMasterTaskLoopDirective::Create(
10794 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10795 DSAStack->isCancelRegion());
10798 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10799 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10800 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10802 return StmtError();
10804 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10805 auto *CS = cast<CapturedStmt>(AStmt);
10806 // 1.2.2 OpenMP Language Terminology
10807 // Structured block - An executable statement with a single entry at the
10808 // top and a single exit at the bottom.
10809 // The point of exit cannot be a branch out of the structured block.
10810 // longjmp() and throw() must not violate the entry/exit criteria.
10811 CS->getCapturedDecl()->setNothrow();
10812 for (int ThisCaptureLevel =
10813 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10814 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10815 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10816 // 1.2.2 OpenMP Language Terminology
10817 // Structured block - An executable statement with a single entry at the
10818 // top and a single exit at the bottom.
10819 // The point of exit cannot be a branch out of the structured block.
10820 // longjmp() and throw() must not violate the entry/exit criteria.
10821 CS->getCapturedDecl()->setNothrow();
10824 OMPLoopDirective::HelperExprs B;
10825 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10826 // define the nested loops number.
10827 unsigned NestedLoopCount = checkOpenMPLoop(
10828 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10829 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10830 VarsWithImplicitDSA, B);
10831 if (NestedLoopCount == 0)
10832 return StmtError();
10834 assert((CurContext->isDependentContext() || B.builtAll()) &&
10835 "omp for loop exprs were not built");
10837 if (!CurContext->isDependentContext()) {
10838 // Finalize the clauses that need pre-built expressions for CodeGen.
10839 for (OMPClause *C : Clauses) {
10840 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10841 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10842 B.NumIterations, *this, CurScope,
10844 return StmtError();
10848 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10849 // The grainsize clause and num_tasks clause are mutually exclusive and may
10850 // not appear on the same taskloop directive.
10851 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10852 return StmtError();
10853 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10854 // If a reduction clause is present on the taskloop directive, the nogroup
10855 // clause must not be specified.
10856 if (checkReductionClauseWithNogroup(*this, Clauses))
10857 return StmtError();
10858 if (checkSimdlenSafelenSpecified(*this, Clauses))
10859 return StmtError();
10861 setFunctionHasBranchProtectedScope();
10862 return OMPParallelMasterTaskLoopSimdDirective::Create(
10863 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10866 StmtResult Sema::ActOnOpenMPDistributeDirective(
10867 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10868 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10870 return StmtError();
10872 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10873 OMPLoopDirective::HelperExprs B;
10874 // In presence of clause 'collapse' with number of loops, it will
10875 // define the nested loops number.
10876 unsigned NestedLoopCount =
10877 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
10878 nullptr /*ordered not a clause on distribute*/, AStmt,
10879 *this, *DSAStack, VarsWithImplicitDSA, B);
10880 if (NestedLoopCount == 0)
10881 return StmtError();
10883 assert((CurContext->isDependentContext() || B.builtAll()) &&
10884 "omp for loop exprs were not built");
10886 setFunctionHasBranchProtectedScope();
10887 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
10888 NestedLoopCount, Clauses, AStmt, B);
10891 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
10892 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10893 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10895 return StmtError();
10897 auto *CS = cast<CapturedStmt>(AStmt);
10898 // 1.2.2 OpenMP Language Terminology
10899 // Structured block - An executable statement with a single entry at the
10900 // top and a single exit at the bottom.
10901 // The point of exit cannot be a branch out of the structured block.
10902 // longjmp() and throw() must not violate the entry/exit criteria.
10903 CS->getCapturedDecl()->setNothrow();
10904 for (int ThisCaptureLevel =
10905 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
10906 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10907 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10908 // 1.2.2 OpenMP Language Terminology
10909 // Structured block - An executable statement with a single entry at the
10910 // top and a single exit at the bottom.
10911 // The point of exit cannot be a branch out of the structured block.
10912 // longjmp() and throw() must not violate the entry/exit criteria.
10913 CS->getCapturedDecl()->setNothrow();
10916 OMPLoopDirective::HelperExprs B;
10917 // In presence of clause 'collapse' with number of loops, it will
10918 // define the nested loops number.
10919 unsigned NestedLoopCount = checkOpenMPLoop(
10920 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10921 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10922 VarsWithImplicitDSA, B);
10923 if (NestedLoopCount == 0)
10924 return StmtError();
10926 assert((CurContext->isDependentContext() || B.builtAll()) &&
10927 "omp for loop exprs were not built");
10929 setFunctionHasBranchProtectedScope();
10930 return OMPDistributeParallelForDirective::Create(
10931 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10932 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10935 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
10936 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10937 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10939 return StmtError();
10941 auto *CS = cast<CapturedStmt>(AStmt);
10942 // 1.2.2 OpenMP Language Terminology
10943 // Structured block - An executable statement with a single entry at the
10944 // top and a single exit at the bottom.
10945 // The point of exit cannot be a branch out of the structured block.
10946 // longjmp() and throw() must not violate the entry/exit criteria.
10947 CS->getCapturedDecl()->setNothrow();
10948 for (int ThisCaptureLevel =
10949 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10950 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10951 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10952 // 1.2.2 OpenMP Language Terminology
10953 // Structured block - An executable statement with a single entry at the
10954 // top and a single exit at the bottom.
10955 // The point of exit cannot be a branch out of the structured block.
10956 // longjmp() and throw() must not violate the entry/exit criteria.
10957 CS->getCapturedDecl()->setNothrow();
10960 OMPLoopDirective::HelperExprs B;
10961 // In presence of clause 'collapse' with number of loops, it will
10962 // define the nested loops number.
10963 unsigned NestedLoopCount = checkOpenMPLoop(
10964 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10965 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10966 VarsWithImplicitDSA, B);
10967 if (NestedLoopCount == 0)
10968 return StmtError();
10970 assert((CurContext->isDependentContext() || B.builtAll()) &&
10971 "omp for loop exprs were not built");
10973 if (!CurContext->isDependentContext()) {
10974 // Finalize the clauses that need pre-built expressions for CodeGen.
10975 for (OMPClause *C : Clauses) {
10976 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10977 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10978 B.NumIterations, *this, CurScope,
10980 return StmtError();
10984 if (checkSimdlenSafelenSpecified(*this, Clauses))
10985 return StmtError();
10987 setFunctionHasBranchProtectedScope();
10988 return OMPDistributeParallelForSimdDirective::Create(
10989 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10992 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
10993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10994 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10996 return StmtError();
10998 auto *CS = cast<CapturedStmt>(AStmt);
10999 // 1.2.2 OpenMP Language Terminology
11000 // Structured block - An executable statement with a single entry at the
11001 // top and a single exit at the bottom.
11002 // The point of exit cannot be a branch out of the structured block.
11003 // longjmp() and throw() must not violate the entry/exit criteria.
11004 CS->getCapturedDecl()->setNothrow();
11005 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11006 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11007 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11008 // 1.2.2 OpenMP Language Terminology
11009 // Structured block - An executable statement with a single entry at the
11010 // top and a single exit at the bottom.
11011 // The point of exit cannot be a branch out of the structured block.
11012 // longjmp() and throw() must not violate the entry/exit criteria.
11013 CS->getCapturedDecl()->setNothrow();
11016 OMPLoopDirective::HelperExprs B;
11017 // In presence of clause 'collapse' with number of loops, it will
11018 // define the nested loops number.
11019 unsigned NestedLoopCount =
11020 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11021 nullptr /*ordered not a clause on distribute*/, CS, *this,
11022 *DSAStack, VarsWithImplicitDSA, B);
11023 if (NestedLoopCount == 0)
11024 return StmtError();
11026 assert((CurContext->isDependentContext() || B.builtAll()) &&
11027 "omp for loop exprs were not built");
11029 if (!CurContext->isDependentContext()) {
11030 // Finalize the clauses that need pre-built expressions for CodeGen.
11031 for (OMPClause *C : Clauses) {
11032 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11033 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11034 B.NumIterations, *this, CurScope,
11036 return StmtError();
11040 if (checkSimdlenSafelenSpecified(*this, Clauses))
11041 return StmtError();
11043 setFunctionHasBranchProtectedScope();
11044 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11045 NestedLoopCount, Clauses, AStmt, B);
11048 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11049 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11050 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11052 return StmtError();
11054 auto *CS = cast<CapturedStmt>(AStmt);
11055 // 1.2.2 OpenMP Language Terminology
11056 // Structured block - An executable statement with a single entry at the
11057 // top and a single exit at the bottom.
11058 // The point of exit cannot be a branch out of the structured block.
11059 // longjmp() and throw() must not violate the entry/exit criteria.
11060 CS->getCapturedDecl()->setNothrow();
11061 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11062 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11063 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11064 // 1.2.2 OpenMP Language Terminology
11065 // Structured block - An executable statement with a single entry at the
11066 // top and a single exit at the bottom.
11067 // The point of exit cannot be a branch out of the structured block.
11068 // longjmp() and throw() must not violate the entry/exit criteria.
11069 CS->getCapturedDecl()->setNothrow();
11072 OMPLoopDirective::HelperExprs B;
11073 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11074 // define the nested loops number.
11075 unsigned NestedLoopCount = checkOpenMPLoop(
11076 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11077 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11078 VarsWithImplicitDSA, B);
11079 if (NestedLoopCount == 0)
11080 return StmtError();
11082 assert((CurContext->isDependentContext() || B.builtAll()) &&
11083 "omp target parallel for simd loop exprs were not built");
11085 if (!CurContext->isDependentContext()) {
11086 // Finalize the clauses that need pre-built expressions for CodeGen.
11087 for (OMPClause *C : Clauses) {
11088 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11089 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11090 B.NumIterations, *this, CurScope,
11092 return StmtError();
11095 if (checkSimdlenSafelenSpecified(*this, Clauses))
11096 return StmtError();
11098 setFunctionHasBranchProtectedScope();
11099 return OMPTargetParallelForSimdDirective::Create(
11100 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11103 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11104 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11105 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11107 return StmtError();
11109 auto *CS = cast<CapturedStmt>(AStmt);
11110 // 1.2.2 OpenMP Language Terminology
11111 // Structured block - An executable statement with a single entry at the
11112 // top and a single exit at the bottom.
11113 // The point of exit cannot be a branch out of the structured block.
11114 // longjmp() and throw() must not violate the entry/exit criteria.
11115 CS->getCapturedDecl()->setNothrow();
11116 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11117 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11118 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11119 // 1.2.2 OpenMP Language Terminology
11120 // Structured block - An executable statement with a single entry at the
11121 // top and a single exit at the bottom.
11122 // The point of exit cannot be a branch out of the structured block.
11123 // longjmp() and throw() must not violate the entry/exit criteria.
11124 CS->getCapturedDecl()->setNothrow();
11127 OMPLoopDirective::HelperExprs B;
11128 // In presence of clause 'collapse' with number of loops, it will define the
11129 // nested loops number.
11130 unsigned NestedLoopCount =
11131 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11132 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11133 VarsWithImplicitDSA, B);
11134 if (NestedLoopCount == 0)
11135 return StmtError();
11137 assert((CurContext->isDependentContext() || B.builtAll()) &&
11138 "omp target simd loop exprs were not built");
11140 if (!CurContext->isDependentContext()) {
11141 // Finalize the clauses that need pre-built expressions for CodeGen.
11142 for (OMPClause *C : Clauses) {
11143 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11144 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11145 B.NumIterations, *this, CurScope,
11147 return StmtError();
11151 if (checkSimdlenSafelenSpecified(*this, Clauses))
11152 return StmtError();
11154 setFunctionHasBranchProtectedScope();
11155 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11156 NestedLoopCount, Clauses, AStmt, B);
11159 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11160 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11161 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11163 return StmtError();
11165 auto *CS = cast<CapturedStmt>(AStmt);
11166 // 1.2.2 OpenMP Language Terminology
11167 // Structured block - An executable statement with a single entry at the
11168 // top and a single exit at the bottom.
11169 // The point of exit cannot be a branch out of the structured block.
11170 // longjmp() and throw() must not violate the entry/exit criteria.
11171 CS->getCapturedDecl()->setNothrow();
11172 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11173 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11174 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11175 // 1.2.2 OpenMP Language Terminology
11176 // Structured block - An executable statement with a single entry at the
11177 // top and a single exit at the bottom.
11178 // The point of exit cannot be a branch out of the structured block.
11179 // longjmp() and throw() must not violate the entry/exit criteria.
11180 CS->getCapturedDecl()->setNothrow();
11183 OMPLoopDirective::HelperExprs B;
11184 // In presence of clause 'collapse' with number of loops, it will
11185 // define the nested loops number.
11186 unsigned NestedLoopCount =
11187 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11188 nullptr /*ordered not a clause on distribute*/, CS, *this,
11189 *DSAStack, VarsWithImplicitDSA, B);
11190 if (NestedLoopCount == 0)
11191 return StmtError();
11193 assert((CurContext->isDependentContext() || B.builtAll()) &&
11194 "omp teams distribute loop exprs were not built");
11196 setFunctionHasBranchProtectedScope();
11198 DSAStack->setParentTeamsRegionLoc(StartLoc);
11200 return OMPTeamsDistributeDirective::Create(
11201 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11204 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11205 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11206 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11208 return StmtError();
11210 auto *CS = cast<CapturedStmt>(AStmt);
11211 // 1.2.2 OpenMP Language Terminology
11212 // Structured block - An executable statement with a single entry at the
11213 // top and a single exit at the bottom.
11214 // The point of exit cannot be a branch out of the structured block.
11215 // longjmp() and throw() must not violate the entry/exit criteria.
11216 CS->getCapturedDecl()->setNothrow();
11217 for (int ThisCaptureLevel =
11218 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11219 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11220 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11221 // 1.2.2 OpenMP Language Terminology
11222 // Structured block - An executable statement with a single entry at the
11223 // top and a single exit at the bottom.
11224 // The point of exit cannot be a branch out of the structured block.
11225 // longjmp() and throw() must not violate the entry/exit criteria.
11226 CS->getCapturedDecl()->setNothrow();
11229 OMPLoopDirective::HelperExprs B;
11230 // In presence of clause 'collapse' with number of loops, it will
11231 // define the nested loops number.
11232 unsigned NestedLoopCount = checkOpenMPLoop(
11233 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11234 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11235 VarsWithImplicitDSA, B);
11237 if (NestedLoopCount == 0)
11238 return StmtError();
11240 assert((CurContext->isDependentContext() || B.builtAll()) &&
11241 "omp teams distribute simd loop exprs were not built");
11243 if (!CurContext->isDependentContext()) {
11244 // Finalize the clauses that need pre-built expressions for CodeGen.
11245 for (OMPClause *C : Clauses) {
11246 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11247 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11248 B.NumIterations, *this, CurScope,
11250 return StmtError();
11254 if (checkSimdlenSafelenSpecified(*this, Clauses))
11255 return StmtError();
11257 setFunctionHasBranchProtectedScope();
11259 DSAStack->setParentTeamsRegionLoc(StartLoc);
11261 return OMPTeamsDistributeSimdDirective::Create(
11262 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11265 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11267 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11269 return StmtError();
11271 auto *CS = cast<CapturedStmt>(AStmt);
11272 // 1.2.2 OpenMP Language Terminology
11273 // Structured block - An executable statement with a single entry at the
11274 // top and a single exit at the bottom.
11275 // The point of exit cannot be a branch out of the structured block.
11276 // longjmp() and throw() must not violate the entry/exit criteria.
11277 CS->getCapturedDecl()->setNothrow();
11279 for (int ThisCaptureLevel =
11280 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11281 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11282 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11283 // 1.2.2 OpenMP Language Terminology
11284 // Structured block - An executable statement with a single entry at the
11285 // top and a single exit at the bottom.
11286 // The point of exit cannot be a branch out of the structured block.
11287 // longjmp() and throw() must not violate the entry/exit criteria.
11288 CS->getCapturedDecl()->setNothrow();
11291 OMPLoopDirective::HelperExprs B;
11292 // In presence of clause 'collapse' with number of loops, it will
11293 // define the nested loops number.
11294 unsigned NestedLoopCount = checkOpenMPLoop(
11295 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11296 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11297 VarsWithImplicitDSA, B);
11299 if (NestedLoopCount == 0)
11300 return StmtError();
11302 assert((CurContext->isDependentContext() || B.builtAll()) &&
11303 "omp for loop exprs were not built");
11305 if (!CurContext->isDependentContext()) {
11306 // Finalize the clauses that need pre-built expressions for CodeGen.
11307 for (OMPClause *C : Clauses) {
11308 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11309 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11310 B.NumIterations, *this, CurScope,
11312 return StmtError();
11316 if (checkSimdlenSafelenSpecified(*this, Clauses))
11317 return StmtError();
11319 setFunctionHasBranchProtectedScope();
11321 DSAStack->setParentTeamsRegionLoc(StartLoc);
11323 return OMPTeamsDistributeParallelForSimdDirective::Create(
11324 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11327 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11328 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11329 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11331 return StmtError();
11333 auto *CS = cast<CapturedStmt>(AStmt);
11334 // 1.2.2 OpenMP Language Terminology
11335 // Structured block - An executable statement with a single entry at the
11336 // top and a single exit at the bottom.
11337 // The point of exit cannot be a branch out of the structured block.
11338 // longjmp() and throw() must not violate the entry/exit criteria.
11339 CS->getCapturedDecl()->setNothrow();
11341 for (int ThisCaptureLevel =
11342 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11343 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11344 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11345 // 1.2.2 OpenMP Language Terminology
11346 // Structured block - An executable statement with a single entry at the
11347 // top and a single exit at the bottom.
11348 // The point of exit cannot be a branch out of the structured block.
11349 // longjmp() and throw() must not violate the entry/exit criteria.
11350 CS->getCapturedDecl()->setNothrow();
11353 OMPLoopDirective::HelperExprs B;
11354 // In presence of clause 'collapse' with number of loops, it will
11355 // define the nested loops number.
11356 unsigned NestedLoopCount = checkOpenMPLoop(
11357 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11358 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11359 VarsWithImplicitDSA, B);
11361 if (NestedLoopCount == 0)
11362 return StmtError();
11364 assert((CurContext->isDependentContext() || B.builtAll()) &&
11365 "omp for loop exprs were not built");
11367 setFunctionHasBranchProtectedScope();
11369 DSAStack->setParentTeamsRegionLoc(StartLoc);
11371 return OMPTeamsDistributeParallelForDirective::Create(
11372 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11373 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11376 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11378 SourceLocation StartLoc,
11379 SourceLocation EndLoc) {
11381 return StmtError();
11383 auto *CS = cast<CapturedStmt>(AStmt);
11384 // 1.2.2 OpenMP Language Terminology
11385 // Structured block - An executable statement with a single entry at the
11386 // top and a single exit at the bottom.
11387 // The point of exit cannot be a branch out of the structured block.
11388 // longjmp() and throw() must not violate the entry/exit criteria.
11389 CS->getCapturedDecl()->setNothrow();
11391 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11392 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11393 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11394 // 1.2.2 OpenMP Language Terminology
11395 // Structured block - An executable statement with a single entry at the
11396 // top and a single exit at the bottom.
11397 // The point of exit cannot be a branch out of the structured block.
11398 // longjmp() and throw() must not violate the entry/exit criteria.
11399 CS->getCapturedDecl()->setNothrow();
11401 setFunctionHasBranchProtectedScope();
11403 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11407 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11408 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11409 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11411 return StmtError();
11413 auto *CS = cast<CapturedStmt>(AStmt);
11414 // 1.2.2 OpenMP Language Terminology
11415 // Structured block - An executable statement with a single entry at the
11416 // top and a single exit at the bottom.
11417 // The point of exit cannot be a branch out of the structured block.
11418 // longjmp() and throw() must not violate the entry/exit criteria.
11419 CS->getCapturedDecl()->setNothrow();
11420 for (int ThisCaptureLevel =
11421 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11422 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11423 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11424 // 1.2.2 OpenMP Language Terminology
11425 // Structured block - An executable statement with a single entry at the
11426 // top and a single exit at the bottom.
11427 // The point of exit cannot be a branch out of the structured block.
11428 // longjmp() and throw() must not violate the entry/exit criteria.
11429 CS->getCapturedDecl()->setNothrow();
11432 OMPLoopDirective::HelperExprs B;
11433 // In presence of clause 'collapse' with number of loops, it will
11434 // define the nested loops number.
11435 unsigned NestedLoopCount = checkOpenMPLoop(
11436 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11437 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11438 VarsWithImplicitDSA, B);
11439 if (NestedLoopCount == 0)
11440 return StmtError();
11442 assert((CurContext->isDependentContext() || B.builtAll()) &&
11443 "omp target teams distribute loop exprs were not built");
11445 setFunctionHasBranchProtectedScope();
11446 return OMPTargetTeamsDistributeDirective::Create(
11447 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11450 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11451 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11452 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11454 return StmtError();
11456 auto *CS = cast<CapturedStmt>(AStmt);
11457 // 1.2.2 OpenMP Language Terminology
11458 // Structured block - An executable statement with a single entry at the
11459 // top and a single exit at the bottom.
11460 // The point of exit cannot be a branch out of the structured block.
11461 // longjmp() and throw() must not violate the entry/exit criteria.
11462 CS->getCapturedDecl()->setNothrow();
11463 for (int ThisCaptureLevel =
11464 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11465 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11466 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11467 // 1.2.2 OpenMP Language Terminology
11468 // Structured block - An executable statement with a single entry at the
11469 // top and a single exit at the bottom.
11470 // The point of exit cannot be a branch out of the structured block.
11471 // longjmp() and throw() must not violate the entry/exit criteria.
11472 CS->getCapturedDecl()->setNothrow();
11475 OMPLoopDirective::HelperExprs B;
11476 // In presence of clause 'collapse' with number of loops, it will
11477 // define the nested loops number.
11478 unsigned NestedLoopCount = checkOpenMPLoop(
11479 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11480 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11481 VarsWithImplicitDSA, B);
11482 if (NestedLoopCount == 0)
11483 return StmtError();
11485 assert((CurContext->isDependentContext() || B.builtAll()) &&
11486 "omp target teams distribute parallel for loop exprs were not built");
11488 if (!CurContext->isDependentContext()) {
11489 // Finalize the clauses that need pre-built expressions for CodeGen.
11490 for (OMPClause *C : Clauses) {
11491 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11492 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11493 B.NumIterations, *this, CurScope,
11495 return StmtError();
11499 setFunctionHasBranchProtectedScope();
11500 return OMPTargetTeamsDistributeParallelForDirective::Create(
11501 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11502 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11505 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11506 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11507 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11509 return StmtError();
11511 auto *CS = cast<CapturedStmt>(AStmt);
11512 // 1.2.2 OpenMP Language Terminology
11513 // Structured block - An executable statement with a single entry at the
11514 // top and a single exit at the bottom.
11515 // The point of exit cannot be a branch out of the structured block.
11516 // longjmp() and throw() must not violate the entry/exit criteria.
11517 CS->getCapturedDecl()->setNothrow();
11518 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11519 OMPD_target_teams_distribute_parallel_for_simd);
11520 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11521 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11522 // 1.2.2 OpenMP Language Terminology
11523 // Structured block - An executable statement with a single entry at the
11524 // top and a single exit at the bottom.
11525 // The point of exit cannot be a branch out of the structured block.
11526 // longjmp() and throw() must not violate the entry/exit criteria.
11527 CS->getCapturedDecl()->setNothrow();
11530 OMPLoopDirective::HelperExprs B;
11531 // In presence of clause 'collapse' with number of loops, it will
11532 // define the nested loops number.
11533 unsigned NestedLoopCount =
11534 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11535 getCollapseNumberExpr(Clauses),
11536 nullptr /*ordered not a clause on distribute*/, CS, *this,
11537 *DSAStack, VarsWithImplicitDSA, B);
11538 if (NestedLoopCount == 0)
11539 return StmtError();
11541 assert((CurContext->isDependentContext() || B.builtAll()) &&
11542 "omp target teams distribute parallel for simd loop exprs were not "
11545 if (!CurContext->isDependentContext()) {
11546 // Finalize the clauses that need pre-built expressions for CodeGen.
11547 for (OMPClause *C : Clauses) {
11548 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11549 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11550 B.NumIterations, *this, CurScope,
11552 return StmtError();
11556 if (checkSimdlenSafelenSpecified(*this, Clauses))
11557 return StmtError();
11559 setFunctionHasBranchProtectedScope();
11560 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11561 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11564 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11565 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11566 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11568 return StmtError();
11570 auto *CS = cast<CapturedStmt>(AStmt);
11571 // 1.2.2 OpenMP Language Terminology
11572 // Structured block - An executable statement with a single entry at the
11573 // top and a single exit at the bottom.
11574 // The point of exit cannot be a branch out of the structured block.
11575 // longjmp() and throw() must not violate the entry/exit criteria.
11576 CS->getCapturedDecl()->setNothrow();
11577 for (int ThisCaptureLevel =
11578 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11579 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11580 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11581 // 1.2.2 OpenMP Language Terminology
11582 // Structured block - An executable statement with a single entry at the
11583 // top and a single exit at the bottom.
11584 // The point of exit cannot be a branch out of the structured block.
11585 // longjmp() and throw() must not violate the entry/exit criteria.
11586 CS->getCapturedDecl()->setNothrow();
11589 OMPLoopDirective::HelperExprs B;
11590 // In presence of clause 'collapse' with number of loops, it will
11591 // define the nested loops number.
11592 unsigned NestedLoopCount = checkOpenMPLoop(
11593 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11594 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11595 VarsWithImplicitDSA, B);
11596 if (NestedLoopCount == 0)
11597 return StmtError();
11599 assert((CurContext->isDependentContext() || B.builtAll()) &&
11600 "omp target teams distribute simd loop exprs were not built");
11602 if (!CurContext->isDependentContext()) {
11603 // Finalize the clauses that need pre-built expressions for CodeGen.
11604 for (OMPClause *C : Clauses) {
11605 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11606 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11607 B.NumIterations, *this, CurScope,
11609 return StmtError();
11613 if (checkSimdlenSafelenSpecified(*this, Clauses))
11614 return StmtError();
11616 setFunctionHasBranchProtectedScope();
11617 return OMPTargetTeamsDistributeSimdDirective::Create(
11618 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11621 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11622 SourceLocation StartLoc,
11623 SourceLocation LParenLoc,
11624 SourceLocation EndLoc) {
11625 OMPClause *Res = nullptr;
11628 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11630 case OMPC_num_threads:
11631 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11634 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11637 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11639 case OMPC_allocator:
11640 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11642 case OMPC_collapse:
11643 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11646 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11648 case OMPC_num_teams:
11649 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11651 case OMPC_thread_limit:
11652 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11654 case OMPC_priority:
11655 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11657 case OMPC_grainsize:
11658 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11660 case OMPC_num_tasks:
11661 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11664 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11667 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11670 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11675 case OMPC_proc_bind:
11676 case OMPC_schedule:
11678 case OMPC_firstprivate:
11679 case OMPC_lastprivate:
11681 case OMPC_reduction:
11682 case OMPC_task_reduction:
11683 case OMPC_in_reduction:
11687 case OMPC_copyprivate:
11690 case OMPC_mergeable:
11691 case OMPC_threadprivate:
11692 case OMPC_allocate:
11708 case OMPC_dist_schedule:
11709 case OMPC_defaultmap:
11714 case OMPC_use_device_ptr:
11715 case OMPC_use_device_addr:
11716 case OMPC_is_device_ptr:
11717 case OMPC_unified_address:
11718 case OMPC_unified_shared_memory:
11719 case OMPC_reverse_offload:
11720 case OMPC_dynamic_allocators:
11721 case OMPC_atomic_default_mem_order:
11722 case OMPC_device_type:
11724 case OMPC_nontemporal:
11727 case OMPC_inclusive:
11728 case OMPC_exclusive:
11729 case OMPC_uses_allocators:
11730 case OMPC_affinity:
11732 llvm_unreachable("Clause is not allowed.");
11737 // An OpenMP directive such as 'target parallel' has two captured regions:
11738 // for the 'target' and 'parallel' respectively. This function returns
11739 // the region in which to capture expressions associated with a clause.
11740 // A return value of OMPD_unknown signifies that the expression should not
11742 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11743 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11744 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11745 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11749 case OMPD_target_parallel_for_simd:
11750 if (OpenMPVersion >= 50 &&
11751 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11752 CaptureRegion = OMPD_parallel;
11756 case OMPD_target_parallel:
11757 case OMPD_target_parallel_for:
11758 // If this clause applies to the nested 'parallel' region, capture within
11759 // the 'target' region, otherwise do not capture.
11760 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11761 CaptureRegion = OMPD_target;
11763 case OMPD_target_teams_distribute_parallel_for_simd:
11764 if (OpenMPVersion >= 50 &&
11765 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11766 CaptureRegion = OMPD_parallel;
11770 case OMPD_target_teams_distribute_parallel_for:
11771 // If this clause applies to the nested 'parallel' region, capture within
11772 // the 'teams' region, otherwise do not capture.
11773 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11774 CaptureRegion = OMPD_teams;
11776 case OMPD_teams_distribute_parallel_for_simd:
11777 if (OpenMPVersion >= 50 &&
11778 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11779 CaptureRegion = OMPD_parallel;
11783 case OMPD_teams_distribute_parallel_for:
11784 CaptureRegion = OMPD_teams;
11786 case OMPD_target_update:
11787 case OMPD_target_enter_data:
11788 case OMPD_target_exit_data:
11789 CaptureRegion = OMPD_task;
11791 case OMPD_parallel_master_taskloop:
11792 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11793 CaptureRegion = OMPD_parallel;
11795 case OMPD_parallel_master_taskloop_simd:
11796 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11797 NameModifier == OMPD_taskloop) {
11798 CaptureRegion = OMPD_parallel;
11801 if (OpenMPVersion <= 45)
11803 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11804 CaptureRegion = OMPD_taskloop;
11806 case OMPD_parallel_for_simd:
11807 if (OpenMPVersion <= 45)
11809 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11810 CaptureRegion = OMPD_parallel;
11812 case OMPD_taskloop_simd:
11813 case OMPD_master_taskloop_simd:
11814 if (OpenMPVersion <= 45)
11816 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11817 CaptureRegion = OMPD_taskloop;
11819 case OMPD_distribute_parallel_for_simd:
11820 if (OpenMPVersion <= 45)
11822 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11823 CaptureRegion = OMPD_parallel;
11825 case OMPD_target_simd:
11826 if (OpenMPVersion >= 50 &&
11827 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11828 CaptureRegion = OMPD_target;
11830 case OMPD_teams_distribute_simd:
11831 case OMPD_target_teams_distribute_simd:
11832 if (OpenMPVersion >= 50 &&
11833 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11834 CaptureRegion = OMPD_teams;
11837 case OMPD_parallel:
11838 case OMPD_parallel_master:
11839 case OMPD_parallel_sections:
11840 case OMPD_parallel_for:
11842 case OMPD_target_teams:
11843 case OMPD_target_teams_distribute:
11844 case OMPD_distribute_parallel_for:
11846 case OMPD_taskloop:
11847 case OMPD_master_taskloop:
11848 case OMPD_target_data:
11850 case OMPD_for_simd:
11851 case OMPD_distribute_simd:
11852 // Do not capture if-clause expressions.
11854 case OMPD_threadprivate:
11855 case OMPD_allocate:
11856 case OMPD_taskyield:
11858 case OMPD_taskwait:
11859 case OMPD_cancellation_point:
11863 case OMPD_declare_reduction:
11864 case OMPD_declare_mapper:
11865 case OMPD_declare_simd:
11866 case OMPD_declare_variant:
11867 case OMPD_begin_declare_variant:
11868 case OMPD_end_declare_variant:
11869 case OMPD_declare_target:
11870 case OMPD_end_declare_target:
11873 case OMPD_sections:
11877 case OMPD_critical:
11878 case OMPD_taskgroup:
11879 case OMPD_distribute:
11882 case OMPD_teams_distribute:
11883 case OMPD_requires:
11884 llvm_unreachable("Unexpected OpenMP directive with if-clause");
11887 llvm_unreachable("Unknown OpenMP directive");
11890 case OMPC_num_threads:
11892 case OMPD_target_parallel:
11893 case OMPD_target_parallel_for:
11894 case OMPD_target_parallel_for_simd:
11895 CaptureRegion = OMPD_target;
11897 case OMPD_teams_distribute_parallel_for:
11898 case OMPD_teams_distribute_parallel_for_simd:
11899 case OMPD_target_teams_distribute_parallel_for:
11900 case OMPD_target_teams_distribute_parallel_for_simd:
11901 CaptureRegion = OMPD_teams;
11903 case OMPD_parallel:
11904 case OMPD_parallel_master:
11905 case OMPD_parallel_sections:
11906 case OMPD_parallel_for:
11907 case OMPD_parallel_for_simd:
11908 case OMPD_distribute_parallel_for:
11909 case OMPD_distribute_parallel_for_simd:
11910 case OMPD_parallel_master_taskloop:
11911 case OMPD_parallel_master_taskloop_simd:
11912 // Do not capture num_threads-clause expressions.
11914 case OMPD_target_data:
11915 case OMPD_target_enter_data:
11916 case OMPD_target_exit_data:
11917 case OMPD_target_update:
11919 case OMPD_target_simd:
11920 case OMPD_target_teams:
11921 case OMPD_target_teams_distribute:
11922 case OMPD_target_teams_distribute_simd:
11925 case OMPD_taskloop:
11926 case OMPD_taskloop_simd:
11927 case OMPD_master_taskloop:
11928 case OMPD_master_taskloop_simd:
11929 case OMPD_threadprivate:
11930 case OMPD_allocate:
11931 case OMPD_taskyield:
11933 case OMPD_taskwait:
11934 case OMPD_cancellation_point:
11938 case OMPD_declare_reduction:
11939 case OMPD_declare_mapper:
11940 case OMPD_declare_simd:
11941 case OMPD_declare_variant:
11942 case OMPD_begin_declare_variant:
11943 case OMPD_end_declare_variant:
11944 case OMPD_declare_target:
11945 case OMPD_end_declare_target:
11949 case OMPD_for_simd:
11950 case OMPD_sections:
11954 case OMPD_critical:
11955 case OMPD_taskgroup:
11956 case OMPD_distribute:
11959 case OMPD_distribute_simd:
11960 case OMPD_teams_distribute:
11961 case OMPD_teams_distribute_simd:
11962 case OMPD_requires:
11963 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
11966 llvm_unreachable("Unknown OpenMP directive");
11969 case OMPC_num_teams:
11971 case OMPD_target_teams:
11972 case OMPD_target_teams_distribute:
11973 case OMPD_target_teams_distribute_simd:
11974 case OMPD_target_teams_distribute_parallel_for:
11975 case OMPD_target_teams_distribute_parallel_for_simd:
11976 CaptureRegion = OMPD_target;
11978 case OMPD_teams_distribute_parallel_for:
11979 case OMPD_teams_distribute_parallel_for_simd:
11981 case OMPD_teams_distribute:
11982 case OMPD_teams_distribute_simd:
11983 // Do not capture num_teams-clause expressions.
11985 case OMPD_distribute_parallel_for:
11986 case OMPD_distribute_parallel_for_simd:
11988 case OMPD_taskloop:
11989 case OMPD_taskloop_simd:
11990 case OMPD_master_taskloop:
11991 case OMPD_master_taskloop_simd:
11992 case OMPD_parallel_master_taskloop:
11993 case OMPD_parallel_master_taskloop_simd:
11994 case OMPD_target_data:
11995 case OMPD_target_enter_data:
11996 case OMPD_target_exit_data:
11997 case OMPD_target_update:
11999 case OMPD_parallel:
12000 case OMPD_parallel_master:
12001 case OMPD_parallel_sections:
12002 case OMPD_parallel_for:
12003 case OMPD_parallel_for_simd:
12005 case OMPD_target_simd:
12006 case OMPD_target_parallel:
12007 case OMPD_target_parallel_for:
12008 case OMPD_target_parallel_for_simd:
12009 case OMPD_threadprivate:
12010 case OMPD_allocate:
12011 case OMPD_taskyield:
12013 case OMPD_taskwait:
12014 case OMPD_cancellation_point:
12018 case OMPD_declare_reduction:
12019 case OMPD_declare_mapper:
12020 case OMPD_declare_simd:
12021 case OMPD_declare_variant:
12022 case OMPD_begin_declare_variant:
12023 case OMPD_end_declare_variant:
12024 case OMPD_declare_target:
12025 case OMPD_end_declare_target:
12028 case OMPD_for_simd:
12029 case OMPD_sections:
12033 case OMPD_critical:
12034 case OMPD_taskgroup:
12035 case OMPD_distribute:
12038 case OMPD_distribute_simd:
12039 case OMPD_requires:
12040 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12043 llvm_unreachable("Unknown OpenMP directive");
12046 case OMPC_thread_limit:
12048 case OMPD_target_teams:
12049 case OMPD_target_teams_distribute:
12050 case OMPD_target_teams_distribute_simd:
12051 case OMPD_target_teams_distribute_parallel_for:
12052 case OMPD_target_teams_distribute_parallel_for_simd:
12053 CaptureRegion = OMPD_target;
12055 case OMPD_teams_distribute_parallel_for:
12056 case OMPD_teams_distribute_parallel_for_simd:
12058 case OMPD_teams_distribute:
12059 case OMPD_teams_distribute_simd:
12060 // Do not capture thread_limit-clause expressions.
12062 case OMPD_distribute_parallel_for:
12063 case OMPD_distribute_parallel_for_simd:
12065 case OMPD_taskloop:
12066 case OMPD_taskloop_simd:
12067 case OMPD_master_taskloop:
12068 case OMPD_master_taskloop_simd:
12069 case OMPD_parallel_master_taskloop:
12070 case OMPD_parallel_master_taskloop_simd:
12071 case OMPD_target_data:
12072 case OMPD_target_enter_data:
12073 case OMPD_target_exit_data:
12074 case OMPD_target_update:
12076 case OMPD_parallel:
12077 case OMPD_parallel_master:
12078 case OMPD_parallel_sections:
12079 case OMPD_parallel_for:
12080 case OMPD_parallel_for_simd:
12082 case OMPD_target_simd:
12083 case OMPD_target_parallel:
12084 case OMPD_target_parallel_for:
12085 case OMPD_target_parallel_for_simd:
12086 case OMPD_threadprivate:
12087 case OMPD_allocate:
12088 case OMPD_taskyield:
12090 case OMPD_taskwait:
12091 case OMPD_cancellation_point:
12095 case OMPD_declare_reduction:
12096 case OMPD_declare_mapper:
12097 case OMPD_declare_simd:
12098 case OMPD_declare_variant:
12099 case OMPD_begin_declare_variant:
12100 case OMPD_end_declare_variant:
12101 case OMPD_declare_target:
12102 case OMPD_end_declare_target:
12105 case OMPD_for_simd:
12106 case OMPD_sections:
12110 case OMPD_critical:
12111 case OMPD_taskgroup:
12112 case OMPD_distribute:
12115 case OMPD_distribute_simd:
12116 case OMPD_requires:
12117 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12120 llvm_unreachable("Unknown OpenMP directive");
12123 case OMPC_schedule:
12125 case OMPD_parallel_for:
12126 case OMPD_parallel_for_simd:
12127 case OMPD_distribute_parallel_for:
12128 case OMPD_distribute_parallel_for_simd:
12129 case OMPD_teams_distribute_parallel_for:
12130 case OMPD_teams_distribute_parallel_for_simd:
12131 case OMPD_target_parallel_for:
12132 case OMPD_target_parallel_for_simd:
12133 case OMPD_target_teams_distribute_parallel_for:
12134 case OMPD_target_teams_distribute_parallel_for_simd:
12135 CaptureRegion = OMPD_parallel;
12138 case OMPD_for_simd:
12139 // Do not capture schedule-clause expressions.
12142 case OMPD_taskloop:
12143 case OMPD_taskloop_simd:
12144 case OMPD_master_taskloop:
12145 case OMPD_master_taskloop_simd:
12146 case OMPD_parallel_master_taskloop:
12147 case OMPD_parallel_master_taskloop_simd:
12148 case OMPD_target_data:
12149 case OMPD_target_enter_data:
12150 case OMPD_target_exit_data:
12151 case OMPD_target_update:
12153 case OMPD_teams_distribute:
12154 case OMPD_teams_distribute_simd:
12155 case OMPD_target_teams_distribute:
12156 case OMPD_target_teams_distribute_simd:
12158 case OMPD_target_simd:
12159 case OMPD_target_parallel:
12161 case OMPD_parallel:
12162 case OMPD_parallel_master:
12163 case OMPD_parallel_sections:
12164 case OMPD_threadprivate:
12165 case OMPD_allocate:
12166 case OMPD_taskyield:
12168 case OMPD_taskwait:
12169 case OMPD_cancellation_point:
12173 case OMPD_declare_reduction:
12174 case OMPD_declare_mapper:
12175 case OMPD_declare_simd:
12176 case OMPD_declare_variant:
12177 case OMPD_begin_declare_variant:
12178 case OMPD_end_declare_variant:
12179 case OMPD_declare_target:
12180 case OMPD_end_declare_target:
12182 case OMPD_sections:
12186 case OMPD_critical:
12187 case OMPD_taskgroup:
12188 case OMPD_distribute:
12191 case OMPD_distribute_simd:
12192 case OMPD_target_teams:
12193 case OMPD_requires:
12194 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12197 llvm_unreachable("Unknown OpenMP directive");
12200 case OMPC_dist_schedule:
12202 case OMPD_teams_distribute_parallel_for:
12203 case OMPD_teams_distribute_parallel_for_simd:
12204 case OMPD_teams_distribute:
12205 case OMPD_teams_distribute_simd:
12206 case OMPD_target_teams_distribute_parallel_for:
12207 case OMPD_target_teams_distribute_parallel_for_simd:
12208 case OMPD_target_teams_distribute:
12209 case OMPD_target_teams_distribute_simd:
12210 CaptureRegion = OMPD_teams;
12212 case OMPD_distribute_parallel_for:
12213 case OMPD_distribute_parallel_for_simd:
12214 case OMPD_distribute:
12215 case OMPD_distribute_simd:
12216 // Do not capture thread_limit-clause expressions.
12218 case OMPD_parallel_for:
12219 case OMPD_parallel_for_simd:
12220 case OMPD_target_parallel_for_simd:
12221 case OMPD_target_parallel_for:
12223 case OMPD_taskloop:
12224 case OMPD_taskloop_simd:
12225 case OMPD_master_taskloop:
12226 case OMPD_master_taskloop_simd:
12227 case OMPD_parallel_master_taskloop:
12228 case OMPD_parallel_master_taskloop_simd:
12229 case OMPD_target_data:
12230 case OMPD_target_enter_data:
12231 case OMPD_target_exit_data:
12232 case OMPD_target_update:
12235 case OMPD_target_simd:
12236 case OMPD_target_parallel:
12238 case OMPD_parallel:
12239 case OMPD_parallel_master:
12240 case OMPD_parallel_sections:
12241 case OMPD_threadprivate:
12242 case OMPD_allocate:
12243 case OMPD_taskyield:
12245 case OMPD_taskwait:
12246 case OMPD_cancellation_point:
12250 case OMPD_declare_reduction:
12251 case OMPD_declare_mapper:
12252 case OMPD_declare_simd:
12253 case OMPD_declare_variant:
12254 case OMPD_begin_declare_variant:
12255 case OMPD_end_declare_variant:
12256 case OMPD_declare_target:
12257 case OMPD_end_declare_target:
12260 case OMPD_for_simd:
12261 case OMPD_sections:
12265 case OMPD_critical:
12266 case OMPD_taskgroup:
12269 case OMPD_target_teams:
12270 case OMPD_requires:
12271 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12274 llvm_unreachable("Unknown OpenMP directive");
12279 case OMPD_target_update:
12280 case OMPD_target_enter_data:
12281 case OMPD_target_exit_data:
12283 case OMPD_target_simd:
12284 case OMPD_target_teams:
12285 case OMPD_target_parallel:
12286 case OMPD_target_teams_distribute:
12287 case OMPD_target_teams_distribute_simd:
12288 case OMPD_target_parallel_for:
12289 case OMPD_target_parallel_for_simd:
12290 case OMPD_target_teams_distribute_parallel_for:
12291 case OMPD_target_teams_distribute_parallel_for_simd:
12292 CaptureRegion = OMPD_task;
12294 case OMPD_target_data:
12295 // Do not capture device-clause expressions.
12297 case OMPD_teams_distribute_parallel_for:
12298 case OMPD_teams_distribute_parallel_for_simd:
12300 case OMPD_teams_distribute:
12301 case OMPD_teams_distribute_simd:
12302 case OMPD_distribute_parallel_for:
12303 case OMPD_distribute_parallel_for_simd:
12305 case OMPD_taskloop:
12306 case OMPD_taskloop_simd:
12307 case OMPD_master_taskloop:
12308 case OMPD_master_taskloop_simd:
12309 case OMPD_parallel_master_taskloop:
12310 case OMPD_parallel_master_taskloop_simd:
12312 case OMPD_parallel:
12313 case OMPD_parallel_master:
12314 case OMPD_parallel_sections:
12315 case OMPD_parallel_for:
12316 case OMPD_parallel_for_simd:
12317 case OMPD_threadprivate:
12318 case OMPD_allocate:
12319 case OMPD_taskyield:
12321 case OMPD_taskwait:
12322 case OMPD_cancellation_point:
12326 case OMPD_declare_reduction:
12327 case OMPD_declare_mapper:
12328 case OMPD_declare_simd:
12329 case OMPD_declare_variant:
12330 case OMPD_begin_declare_variant:
12331 case OMPD_end_declare_variant:
12332 case OMPD_declare_target:
12333 case OMPD_end_declare_target:
12336 case OMPD_for_simd:
12337 case OMPD_sections:
12341 case OMPD_critical:
12342 case OMPD_taskgroup:
12343 case OMPD_distribute:
12346 case OMPD_distribute_simd:
12347 case OMPD_requires:
12348 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12351 llvm_unreachable("Unknown OpenMP directive");
12354 case OMPC_grainsize:
12355 case OMPC_num_tasks:
12357 case OMPC_priority:
12360 case OMPD_taskloop:
12361 case OMPD_taskloop_simd:
12362 case OMPD_master_taskloop:
12363 case OMPD_master_taskloop_simd:
12365 case OMPD_parallel_master_taskloop:
12366 case OMPD_parallel_master_taskloop_simd:
12367 CaptureRegion = OMPD_parallel;
12369 case OMPD_target_update:
12370 case OMPD_target_enter_data:
12371 case OMPD_target_exit_data:
12373 case OMPD_target_simd:
12374 case OMPD_target_teams:
12375 case OMPD_target_parallel:
12376 case OMPD_target_teams_distribute:
12377 case OMPD_target_teams_distribute_simd:
12378 case OMPD_target_parallel_for:
12379 case OMPD_target_parallel_for_simd:
12380 case OMPD_target_teams_distribute_parallel_for:
12381 case OMPD_target_teams_distribute_parallel_for_simd:
12382 case OMPD_target_data:
12383 case OMPD_teams_distribute_parallel_for:
12384 case OMPD_teams_distribute_parallel_for_simd:
12386 case OMPD_teams_distribute:
12387 case OMPD_teams_distribute_simd:
12388 case OMPD_distribute_parallel_for:
12389 case OMPD_distribute_parallel_for_simd:
12391 case OMPD_parallel:
12392 case OMPD_parallel_master:
12393 case OMPD_parallel_sections:
12394 case OMPD_parallel_for:
12395 case OMPD_parallel_for_simd:
12396 case OMPD_threadprivate:
12397 case OMPD_allocate:
12398 case OMPD_taskyield:
12400 case OMPD_taskwait:
12401 case OMPD_cancellation_point:
12405 case OMPD_declare_reduction:
12406 case OMPD_declare_mapper:
12407 case OMPD_declare_simd:
12408 case OMPD_declare_variant:
12409 case OMPD_begin_declare_variant:
12410 case OMPD_end_declare_variant:
12411 case OMPD_declare_target:
12412 case OMPD_end_declare_target:
12415 case OMPD_for_simd:
12416 case OMPD_sections:
12420 case OMPD_critical:
12421 case OMPD_taskgroup:
12422 case OMPD_distribute:
12425 case OMPD_distribute_simd:
12426 case OMPD_requires:
12427 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12430 llvm_unreachable("Unknown OpenMP directive");
12433 case OMPC_firstprivate:
12434 case OMPC_lastprivate:
12435 case OMPC_reduction:
12436 case OMPC_task_reduction:
12437 case OMPC_in_reduction:
12440 case OMPC_proc_bind:
12443 case OMPC_allocator:
12444 case OMPC_collapse:
12449 case OMPC_copyprivate:
12453 case OMPC_mergeable:
12454 case OMPC_threadprivate:
12455 case OMPC_allocate:
12473 case OMPC_defaultmap:
12478 case OMPC_use_device_ptr:
12479 case OMPC_use_device_addr:
12480 case OMPC_is_device_ptr:
12481 case OMPC_unified_address:
12482 case OMPC_unified_shared_memory:
12483 case OMPC_reverse_offload:
12484 case OMPC_dynamic_allocators:
12485 case OMPC_atomic_default_mem_order:
12486 case OMPC_device_type:
12488 case OMPC_nontemporal:
12492 case OMPC_inclusive:
12493 case OMPC_exclusive:
12494 case OMPC_uses_allocators:
12495 case OMPC_affinity:
12497 llvm_unreachable("Unexpected OpenMP clause.");
12499 return CaptureRegion;
12502 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12503 Expr *Condition, SourceLocation StartLoc,
12504 SourceLocation LParenLoc,
12505 SourceLocation NameModifierLoc,
12506 SourceLocation ColonLoc,
12507 SourceLocation EndLoc) {
12508 Expr *ValExpr = Condition;
12509 Stmt *HelperValStmt = nullptr;
12510 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12511 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12512 !Condition->isInstantiationDependent() &&
12513 !Condition->containsUnexpandedParameterPack()) {
12514 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12515 if (Val.isInvalid())
12518 ValExpr = Val.get();
12520 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12521 CaptureRegion = getOpenMPCaptureRegionForClause(
12522 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12523 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12524 ValExpr = MakeFullExpr(ValExpr).get();
12525 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12526 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12527 HelperValStmt = buildPreInits(Context, Captures);
12531 return new (Context)
12532 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12533 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12536 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12537 SourceLocation StartLoc,
12538 SourceLocation LParenLoc,
12539 SourceLocation EndLoc) {
12540 Expr *ValExpr = Condition;
12541 Stmt *HelperValStmt = nullptr;
12542 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12543 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12544 !Condition->isInstantiationDependent() &&
12545 !Condition->containsUnexpandedParameterPack()) {
12546 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12547 if (Val.isInvalid())
12550 ValExpr = MakeFullExpr(Val.get()).get();
12552 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12554 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12555 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12556 ValExpr = MakeFullExpr(ValExpr).get();
12557 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12558 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12559 HelperValStmt = buildPreInits(Context, Captures);
12563 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12564 StartLoc, LParenLoc, EndLoc);
12567 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12570 return ExprError();
12572 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12574 IntConvertDiagnoser()
12575 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12576 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12577 QualType T) override {
12578 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12580 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12581 QualType T) override {
12582 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12584 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12586 QualType ConvTy) override {
12587 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12589 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12590 QualType ConvTy) override {
12591 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12592 << ConvTy->isEnumeralType() << ConvTy;
12594 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12595 QualType T) override {
12596 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12598 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12599 QualType ConvTy) override {
12600 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12601 << ConvTy->isEnumeralType() << ConvTy;
12603 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12604 QualType) override {
12605 llvm_unreachable("conversion functions are permitted");
12607 } ConvertDiagnoser;
12608 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12612 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12613 bool StrictlyPositive, bool BuildCapture = false,
12614 OpenMPDirectiveKind DKind = OMPD_unknown,
12615 OpenMPDirectiveKind *CaptureRegion = nullptr,
12616 Stmt **HelperValStmt = nullptr) {
12617 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12618 !ValExpr->isInstantiationDependent()) {
12619 SourceLocation Loc = ValExpr->getExprLoc();
12621 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12622 if (Value.isInvalid())
12625 ValExpr = Value.get();
12626 // The expression must evaluate to a non-negative integer value.
12627 llvm::APSInt Result;
12628 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
12629 Result.isSigned() &&
12630 !((!StrictlyPositive && Result.isNonNegative()) ||
12631 (StrictlyPositive && Result.isStrictlyPositive()))) {
12632 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12633 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12634 << ValExpr->getSourceRange();
12640 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12641 if (*CaptureRegion != OMPD_unknown &&
12642 !SemaRef.CurContext->isDependentContext()) {
12643 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12644 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12645 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12646 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12652 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12653 SourceLocation StartLoc,
12654 SourceLocation LParenLoc,
12655 SourceLocation EndLoc) {
12656 Expr *ValExpr = NumThreads;
12657 Stmt *HelperValStmt = nullptr;
12659 // OpenMP [2.5, Restrictions]
12660 // The num_threads expression must evaluate to a positive integer value.
12661 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12662 /*StrictlyPositive=*/true))
12665 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12666 OpenMPDirectiveKind CaptureRegion =
12667 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12668 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12669 ValExpr = MakeFullExpr(ValExpr).get();
12670 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12671 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12672 HelperValStmt = buildPreInits(Context, Captures);
12675 return new (Context) OMPNumThreadsClause(
12676 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12679 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12680 OpenMPClauseKind CKind,
12681 bool StrictlyPositive) {
12683 return ExprError();
12684 if (E->isValueDependent() || E->isTypeDependent() ||
12685 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12687 llvm::APSInt Result;
12688 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
12689 if (ICE.isInvalid())
12690 return ExprError();
12691 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12692 (!StrictlyPositive && !Result.isNonNegative())) {
12693 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12694 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12695 << E->getSourceRange();
12696 return ExprError();
12698 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12699 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12700 << E->getSourceRange();
12701 return ExprError();
12703 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12704 DSAStack->setAssociatedLoops(Result.getExtValue());
12705 else if (CKind == OMPC_ordered)
12706 DSAStack->setAssociatedLoops(Result.getExtValue());
12710 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12711 SourceLocation LParenLoc,
12712 SourceLocation EndLoc) {
12713 // OpenMP [2.8.1, simd construct, Description]
12714 // The parameter of the safelen clause must be a constant
12715 // positive integer expression.
12716 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12717 if (Safelen.isInvalid())
12719 return new (Context)
12720 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12723 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12724 SourceLocation LParenLoc,
12725 SourceLocation EndLoc) {
12726 // OpenMP [2.8.1, simd construct, Description]
12727 // The parameter of the simdlen clause must be a constant
12728 // positive integer expression.
12729 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12730 if (Simdlen.isInvalid())
12732 return new (Context)
12733 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12736 /// Tries to find omp_allocator_handle_t type.
12737 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12738 DSAStackTy *Stack) {
12739 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12740 if (!OMPAllocatorHandleT.isNull())
12742 // Build the predefined allocator expressions.
12743 bool ErrorFound = false;
12744 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12745 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12746 StringRef Allocator =
12747 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12748 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12749 auto *VD = dyn_cast_or_null<ValueDecl>(
12750 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12755 QualType AllocatorType =
12756 VD->getType().getNonLValueExprType(S.getASTContext());
12757 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12758 if (!Res.isUsable()) {
12762 if (OMPAllocatorHandleT.isNull())
12763 OMPAllocatorHandleT = AllocatorType;
12764 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12768 Stack->setAllocator(AllocatorKind, Res.get());
12771 S.Diag(Loc, diag::err_omp_implied_type_not_found)
12772 << "omp_allocator_handle_t";
12775 OMPAllocatorHandleT.addConst();
12776 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12780 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12781 SourceLocation LParenLoc,
12782 SourceLocation EndLoc) {
12783 // OpenMP [2.11.3, allocate Directive, Description]
12784 // allocator is an expression of omp_allocator_handle_t type.
12785 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
12788 ExprResult Allocator = DefaultLvalueConversion(A);
12789 if (Allocator.isInvalid())
12791 Allocator = PerformImplicitConversion(Allocator.get(),
12792 DSAStack->getOMPAllocatorHandleT(),
12793 Sema::AA_Initializing,
12794 /*AllowExplicit=*/true);
12795 if (Allocator.isInvalid())
12797 return new (Context)
12798 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12801 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12802 SourceLocation StartLoc,
12803 SourceLocation LParenLoc,
12804 SourceLocation EndLoc) {
12805 // OpenMP [2.7.1, loop construct, Description]
12806 // OpenMP [2.8.1, simd construct, Description]
12807 // OpenMP [2.9.6, distribute construct, Description]
12808 // The parameter of the collapse clause must be a constant
12809 // positive integer expression.
12810 ExprResult NumForLoopsResult =
12811 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12812 if (NumForLoopsResult.isInvalid())
12814 return new (Context)
12815 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12818 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12819 SourceLocation EndLoc,
12820 SourceLocation LParenLoc,
12821 Expr *NumForLoops) {
12822 // OpenMP [2.7.1, loop construct, Description]
12823 // OpenMP [2.8.1, simd construct, Description]
12824 // OpenMP [2.9.6, distribute construct, Description]
12825 // The parameter of the ordered clause must be a constant
12826 // positive integer expression if any.
12827 if (NumForLoops && LParenLoc.isValid()) {
12828 ExprResult NumForLoopsResult =
12829 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12830 if (NumForLoopsResult.isInvalid())
12832 NumForLoops = NumForLoopsResult.get();
12834 NumForLoops = nullptr;
12836 auto *Clause = OMPOrderedClause::Create(
12837 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
12838 StartLoc, LParenLoc, EndLoc);
12839 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12843 OMPClause *Sema::ActOnOpenMPSimpleClause(
12844 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12845 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12846 OMPClause *Res = nullptr;
12849 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12850 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12852 case OMPC_proc_bind:
12853 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12854 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12856 case OMPC_atomic_default_mem_order:
12857 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12858 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12859 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12862 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
12863 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12866 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
12867 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12871 case OMPC_num_threads:
12874 case OMPC_allocator:
12875 case OMPC_collapse:
12876 case OMPC_schedule:
12878 case OMPC_firstprivate:
12879 case OMPC_lastprivate:
12881 case OMPC_reduction:
12882 case OMPC_task_reduction:
12883 case OMPC_in_reduction:
12887 case OMPC_copyprivate:
12891 case OMPC_mergeable:
12892 case OMPC_threadprivate:
12893 case OMPC_allocate:
12909 case OMPC_num_teams:
12910 case OMPC_thread_limit:
12911 case OMPC_priority:
12912 case OMPC_grainsize:
12914 case OMPC_num_tasks:
12916 case OMPC_dist_schedule:
12917 case OMPC_defaultmap:
12922 case OMPC_use_device_ptr:
12923 case OMPC_use_device_addr:
12924 case OMPC_is_device_ptr:
12925 case OMPC_unified_address:
12926 case OMPC_unified_shared_memory:
12927 case OMPC_reverse_offload:
12928 case OMPC_dynamic_allocators:
12929 case OMPC_device_type:
12931 case OMPC_nontemporal:
12934 case OMPC_inclusive:
12935 case OMPC_exclusive:
12936 case OMPC_uses_allocators:
12937 case OMPC_affinity:
12939 llvm_unreachable("Clause is not allowed.");
12945 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
12946 ArrayRef<unsigned> Exclude = llvm::None) {
12947 SmallString<256> Buffer;
12948 llvm::raw_svector_ostream Out(Buffer);
12949 unsigned Skipped = Exclude.size();
12950 auto S = Exclude.begin(), E = Exclude.end();
12951 for (unsigned I = First; I < Last; ++I) {
12952 if (std::find(S, E, I) != E) {
12956 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
12957 if (I + Skipped + 2 == Last)
12959 else if (I + Skipped + 1 != Last)
12962 return std::string(Out.str());
12965 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
12966 SourceLocation KindKwLoc,
12967 SourceLocation StartLoc,
12968 SourceLocation LParenLoc,
12969 SourceLocation EndLoc) {
12970 if (Kind == OMP_DEFAULT_unknown) {
12971 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12972 << getListOfPossibleValues(OMPC_default, /*First=*/0,
12973 /*Last=*/unsigned(OMP_DEFAULT_unknown))
12974 << getOpenMPClauseName(OMPC_default);
12979 case OMP_DEFAULT_none:
12980 DSAStack->setDefaultDSANone(KindKwLoc);
12982 case OMP_DEFAULT_shared:
12983 DSAStack->setDefaultDSAShared(KindKwLoc);
12985 case OMP_DEFAULT_firstprivate:
12986 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
12989 llvm_unreachable("DSA unexpected in OpenMP default clause");
12992 return new (Context)
12993 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
12996 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
12997 SourceLocation KindKwLoc,
12998 SourceLocation StartLoc,
12999 SourceLocation LParenLoc,
13000 SourceLocation EndLoc) {
13001 if (Kind == OMP_PROC_BIND_unknown) {
13002 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13003 << getListOfPossibleValues(OMPC_proc_bind,
13004 /*First=*/unsigned(OMP_PROC_BIND_master),
13006 << getOpenMPClauseName(OMPC_proc_bind);
13009 return new (Context)
13010 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13013 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13014 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13015 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13016 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13017 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13018 << getListOfPossibleValues(
13019 OMPC_atomic_default_mem_order, /*First=*/0,
13020 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13021 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13024 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13025 LParenLoc, EndLoc);
13028 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13029 SourceLocation KindKwLoc,
13030 SourceLocation StartLoc,
13031 SourceLocation LParenLoc,
13032 SourceLocation EndLoc) {
13033 if (Kind == OMPC_ORDER_unknown) {
13034 static_assert(OMPC_ORDER_unknown > 0,
13035 "OMPC_ORDER_unknown not greater than 0");
13036 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13037 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13038 /*Last=*/OMPC_ORDER_unknown)
13039 << getOpenMPClauseName(OMPC_order);
13042 return new (Context)
13043 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13046 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13047 SourceLocation KindKwLoc,
13048 SourceLocation StartLoc,
13049 SourceLocation LParenLoc,
13050 SourceLocation EndLoc) {
13051 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13052 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13053 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13054 OMPC_DEPEND_depobj};
13055 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13056 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13057 /*Last=*/OMPC_DEPEND_unknown, Except)
13058 << getOpenMPClauseName(OMPC_update);
13061 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13065 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13066 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13067 SourceLocation StartLoc, SourceLocation LParenLoc,
13068 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13069 SourceLocation EndLoc) {
13070 OMPClause *Res = nullptr;
13072 case OMPC_schedule:
13073 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13074 assert(Argument.size() == NumberOfElements &&
13075 ArgumentLoc.size() == NumberOfElements);
13076 Res = ActOnOpenMPScheduleClause(
13077 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13078 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13079 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13080 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13081 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13084 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13085 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13086 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13089 case OMPC_dist_schedule:
13090 Res = ActOnOpenMPDistScheduleClause(
13091 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13092 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13094 case OMPC_defaultmap:
13095 enum { Modifier, DefaultmapKind };
13096 Res = ActOnOpenMPDefaultmapClause(
13097 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13098 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13099 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13103 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13104 Res = ActOnOpenMPDeviceClause(
13105 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13106 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13109 case OMPC_num_threads:
13112 case OMPC_allocator:
13113 case OMPC_collapse:
13115 case OMPC_proc_bind:
13117 case OMPC_firstprivate:
13118 case OMPC_lastprivate:
13120 case OMPC_reduction:
13121 case OMPC_task_reduction:
13122 case OMPC_in_reduction:
13126 case OMPC_copyprivate:
13130 case OMPC_mergeable:
13131 case OMPC_threadprivate:
13132 case OMPC_allocate:
13148 case OMPC_num_teams:
13149 case OMPC_thread_limit:
13150 case OMPC_priority:
13151 case OMPC_grainsize:
13153 case OMPC_num_tasks:
13159 case OMPC_use_device_ptr:
13160 case OMPC_use_device_addr:
13161 case OMPC_is_device_ptr:
13162 case OMPC_unified_address:
13163 case OMPC_unified_shared_memory:
13164 case OMPC_reverse_offload:
13165 case OMPC_dynamic_allocators:
13166 case OMPC_atomic_default_mem_order:
13167 case OMPC_device_type:
13169 case OMPC_nontemporal:
13173 case OMPC_inclusive:
13174 case OMPC_exclusive:
13175 case OMPC_uses_allocators:
13176 case OMPC_affinity:
13178 llvm_unreachable("Clause is not allowed.");
13183 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13184 OpenMPScheduleClauseModifier M2,
13185 SourceLocation M1Loc, SourceLocation M2Loc) {
13186 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13187 SmallVector<unsigned, 2> Excluded;
13188 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13189 Excluded.push_back(M2);
13190 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13191 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13192 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13193 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13194 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13195 << getListOfPossibleValues(OMPC_schedule,
13196 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13197 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13199 << getOpenMPClauseName(OMPC_schedule);
13205 OMPClause *Sema::ActOnOpenMPScheduleClause(
13206 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13207 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13208 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13209 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13210 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13211 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13213 // OpenMP, 2.7.1, Loop Construct, Restrictions
13214 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13216 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13217 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13218 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13219 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13220 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13221 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13222 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13223 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13226 if (Kind == OMPC_SCHEDULE_unknown) {
13227 std::string Values;
13228 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13229 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13230 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13231 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13234 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13235 /*Last=*/OMPC_SCHEDULE_unknown);
13237 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13238 << Values << getOpenMPClauseName(OMPC_schedule);
13241 // OpenMP, 2.7.1, Loop Construct, Restrictions
13242 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13243 // schedule(guided).
13244 // OpenMP 5.0 does not have this restriction.
13245 if (LangOpts.OpenMP < 50 &&
13246 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13247 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13248 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13249 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13250 diag::err_omp_schedule_nonmonotonic_static);
13253 Expr *ValExpr = ChunkSize;
13254 Stmt *HelperValStmt = nullptr;
13256 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13257 !ChunkSize->isInstantiationDependent() &&
13258 !ChunkSize->containsUnexpandedParameterPack()) {
13259 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13261 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13262 if (Val.isInvalid())
13265 ValExpr = Val.get();
13267 // OpenMP [2.7.1, Restrictions]
13268 // chunk_size must be a loop invariant integer expression with a positive
13270 llvm::APSInt Result;
13271 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
13272 if (Result.isSigned() && !Result.isStrictlyPositive()) {
13273 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13274 << "schedule" << 1 << ChunkSize->getSourceRange();
13277 } else if (getOpenMPCaptureRegionForClause(
13278 DSAStack->getCurrentDirective(), OMPC_schedule,
13279 LangOpts.OpenMP) != OMPD_unknown &&
13280 !CurContext->isDependentContext()) {
13281 ValExpr = MakeFullExpr(ValExpr).get();
13282 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13283 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13284 HelperValStmt = buildPreInits(Context, Captures);
13289 return new (Context)
13290 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13291 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13294 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13295 SourceLocation StartLoc,
13296 SourceLocation EndLoc) {
13297 OMPClause *Res = nullptr;
13300 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13303 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13306 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13308 case OMPC_mergeable:
13309 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13312 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13315 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13318 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13321 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13324 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13327 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13330 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13333 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13336 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13339 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13342 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13345 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13347 case OMPC_unified_address:
13348 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13350 case OMPC_unified_shared_memory:
13351 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13353 case OMPC_reverse_offload:
13354 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13356 case OMPC_dynamic_allocators:
13357 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13360 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13364 case OMPC_num_threads:
13367 case OMPC_allocator:
13368 case OMPC_collapse:
13369 case OMPC_schedule:
13371 case OMPC_firstprivate:
13372 case OMPC_lastprivate:
13374 case OMPC_reduction:
13375 case OMPC_task_reduction:
13376 case OMPC_in_reduction:
13380 case OMPC_copyprivate:
13382 case OMPC_proc_bind:
13383 case OMPC_threadprivate:
13384 case OMPC_allocate:
13390 case OMPC_num_teams:
13391 case OMPC_thread_limit:
13392 case OMPC_priority:
13393 case OMPC_grainsize:
13394 case OMPC_num_tasks:
13396 case OMPC_dist_schedule:
13397 case OMPC_defaultmap:
13402 case OMPC_use_device_ptr:
13403 case OMPC_use_device_addr:
13404 case OMPC_is_device_ptr:
13405 case OMPC_atomic_default_mem_order:
13406 case OMPC_device_type:
13408 case OMPC_nontemporal:
13411 case OMPC_inclusive:
13412 case OMPC_exclusive:
13413 case OMPC_uses_allocators:
13414 case OMPC_affinity:
13416 llvm_unreachable("Clause is not allowed.");
13421 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13422 SourceLocation EndLoc) {
13423 DSAStack->setNowaitRegion();
13424 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13427 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13428 SourceLocation EndLoc) {
13429 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13432 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13433 SourceLocation EndLoc) {
13434 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13437 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13438 SourceLocation EndLoc) {
13439 return new (Context) OMPReadClause(StartLoc, EndLoc);
13442 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13443 SourceLocation EndLoc) {
13444 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13447 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13448 SourceLocation EndLoc) {
13449 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13452 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13453 SourceLocation EndLoc) {
13454 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13457 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13458 SourceLocation EndLoc) {
13459 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13462 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13463 SourceLocation EndLoc) {
13464 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13467 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13468 SourceLocation EndLoc) {
13469 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13472 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13473 SourceLocation EndLoc) {
13474 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13477 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13478 SourceLocation EndLoc) {
13479 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13482 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13483 SourceLocation EndLoc) {
13484 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13487 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13488 SourceLocation EndLoc) {
13489 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13492 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13493 SourceLocation EndLoc) {
13494 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13497 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13498 SourceLocation EndLoc) {
13499 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13502 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13503 SourceLocation EndLoc) {
13504 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13507 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13508 SourceLocation EndLoc) {
13509 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13512 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13513 SourceLocation EndLoc) {
13514 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13517 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13518 SourceLocation EndLoc) {
13519 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13522 OMPClause *Sema::ActOnOpenMPVarListClause(
13523 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13524 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13525 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13526 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13527 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13528 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13529 SourceLocation ExtraModifierLoc) {
13530 SourceLocation StartLoc = Locs.StartLoc;
13531 SourceLocation LParenLoc = Locs.LParenLoc;
13532 SourceLocation EndLoc = Locs.EndLoc;
13533 OMPClause *Res = nullptr;
13536 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13538 case OMPC_firstprivate:
13539 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13541 case OMPC_lastprivate:
13542 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13543 "Unexpected lastprivate modifier.");
13544 Res = ActOnOpenMPLastprivateClause(
13545 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13546 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13549 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13551 case OMPC_reduction:
13552 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13553 "Unexpected lastprivate modifier.");
13554 Res = ActOnOpenMPReductionClause(
13555 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13556 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13557 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13559 case OMPC_task_reduction:
13560 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13561 EndLoc, ReductionOrMapperIdScopeSpec,
13562 ReductionOrMapperId);
13564 case OMPC_in_reduction:
13565 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13566 EndLoc, ReductionOrMapperIdScopeSpec,
13567 ReductionOrMapperId);
13570 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13571 "Unexpected linear modifier.");
13572 Res = ActOnOpenMPLinearClause(
13573 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13574 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13578 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13579 LParenLoc, ColonLoc, EndLoc);
13582 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13584 case OMPC_copyprivate:
13585 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13588 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13591 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13592 "Unexpected depend modifier.");
13593 Res = ActOnOpenMPDependClause(
13594 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13595 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13598 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13599 "Unexpected map modifier.");
13600 Res = ActOnOpenMPMapClause(
13601 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13602 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13603 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13606 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
13607 ReductionOrMapperId, Locs);
13610 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
13611 ReductionOrMapperId, Locs);
13613 case OMPC_use_device_ptr:
13614 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13616 case OMPC_use_device_addr:
13617 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13619 case OMPC_is_device_ptr:
13620 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13622 case OMPC_allocate:
13623 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13624 LParenLoc, ColonLoc, EndLoc);
13626 case OMPC_nontemporal:
13627 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13629 case OMPC_inclusive:
13630 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13632 case OMPC_exclusive:
13633 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13635 case OMPC_affinity:
13636 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13637 DepModOrTailExpr, VarList);
13642 case OMPC_num_threads:
13645 case OMPC_allocator:
13646 case OMPC_collapse:
13648 case OMPC_proc_bind:
13649 case OMPC_schedule:
13653 case OMPC_mergeable:
13654 case OMPC_threadprivate:
13667 case OMPC_num_teams:
13668 case OMPC_thread_limit:
13669 case OMPC_priority:
13670 case OMPC_grainsize:
13672 case OMPC_num_tasks:
13674 case OMPC_dist_schedule:
13675 case OMPC_defaultmap:
13678 case OMPC_unified_address:
13679 case OMPC_unified_shared_memory:
13680 case OMPC_reverse_offload:
13681 case OMPC_dynamic_allocators:
13682 case OMPC_atomic_default_mem_order:
13683 case OMPC_device_type:
13688 case OMPC_uses_allocators:
13690 llvm_unreachable("Clause is not allowed.");
13695 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13696 ExprObjectKind OK, SourceLocation Loc) {
13697 ExprResult Res = BuildDeclRefExpr(
13698 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13699 if (!Res.isUsable())
13700 return ExprError();
13701 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13702 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13703 if (!Res.isUsable())
13704 return ExprError();
13706 if (VK != VK_LValue && Res.get()->isGLValue()) {
13707 Res = DefaultLvalueConversion(Res.get());
13708 if (!Res.isUsable())
13709 return ExprError();
13714 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13715 SourceLocation StartLoc,
13716 SourceLocation LParenLoc,
13717 SourceLocation EndLoc) {
13718 SmallVector<Expr *, 8> Vars;
13719 SmallVector<Expr *, 8> PrivateCopies;
13720 for (Expr *RefExpr : VarList) {
13721 assert(RefExpr && "NULL expr in OpenMP private clause.");
13722 SourceLocation ELoc;
13723 SourceRange ERange;
13724 Expr *SimpleRefExpr = RefExpr;
13725 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13727 // It will be analyzed later.
13728 Vars.push_back(RefExpr);
13729 PrivateCopies.push_back(nullptr);
13731 ValueDecl *D = Res.first;
13735 QualType Type = D->getType();
13736 auto *VD = dyn_cast<VarDecl>(D);
13738 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13739 // A variable that appears in a private clause must not have an incomplete
13740 // type or a reference type.
13741 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13743 Type = Type.getNonReferenceType();
13745 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13746 // A variable that is privatized must not have a const-qualified type
13747 // unless it is of class type with a mutable member. This restriction does
13748 // not apply to the firstprivate clause.
13750 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13751 // A variable that appears in a private clause must not have a
13752 // const-qualified type unless it is of class type with a mutable member.
13753 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13756 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13758 // Variables with the predetermined data-sharing attributes may not be
13759 // listed in data-sharing attributes clauses, except for the cases
13760 // listed below. For these exceptions only, listing a predetermined
13761 // variable in a data-sharing attribute clause is allowed and overrides
13762 // the variable's predetermined data-sharing attributes.
13763 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13764 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13765 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13766 << getOpenMPClauseName(OMPC_private);
13767 reportOriginalDsa(*this, DSAStack, D, DVar);
13771 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13772 // Variably modified types are not supported for tasks.
13773 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13774 isOpenMPTaskingDirective(CurrDir)) {
13775 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13776 << getOpenMPClauseName(OMPC_private) << Type
13777 << getOpenMPDirectiveName(CurrDir);
13780 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13781 Diag(D->getLocation(),
13782 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13787 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13788 // A list item cannot appear in both a map clause and a data-sharing
13789 // attribute clause on the same construct
13791 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13792 // A list item cannot appear in both a map clause and a data-sharing
13793 // attribute clause on the same construct unless the construct is a
13794 // combined construct.
13795 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13796 CurrDir == OMPD_target) {
13797 OpenMPClauseKind ConflictKind;
13798 if (DSAStack->checkMappableExprComponentListsForDecl(
13799 VD, /*CurrentRegionOnly=*/true,
13800 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13801 OpenMPClauseKind WhereFoundClauseKind) -> bool {
13802 ConflictKind = WhereFoundClauseKind;
13805 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13806 << getOpenMPClauseName(OMPC_private)
13807 << getOpenMPClauseName(ConflictKind)
13808 << getOpenMPDirectiveName(CurrDir);
13809 reportOriginalDsa(*this, DSAStack, D, DVar);
13814 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13815 // A variable of class type (or array thereof) that appears in a private
13816 // clause requires an accessible, unambiguous default constructor for the
13818 // Generate helper private variable and initialize it with the default
13819 // value. The address of the original variable is replaced by the address of
13820 // the new private variable in CodeGen. This new variable is not added to
13821 // IdResolver, so the code in the OpenMP region uses original variable for
13822 // proper diagnostics.
13823 Type = Type.getUnqualifiedType();
13824 VarDecl *VDPrivate =
13825 buildVarDecl(*this, ELoc, Type, D->getName(),
13826 D->hasAttrs() ? &D->getAttrs() : nullptr,
13827 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13828 ActOnUninitializedDecl(VDPrivate);
13829 if (VDPrivate->isInvalidDecl())
13831 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13832 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13834 DeclRefExpr *Ref = nullptr;
13835 if (!VD && !CurContext->isDependentContext())
13836 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13837 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13838 Vars.push_back((VD || CurContext->isDependentContext())
13839 ? RefExpr->IgnoreParens()
13841 PrivateCopies.push_back(VDPrivateRefExpr);
13847 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13852 class DiagsUninitializedSeveretyRAII {
13854 DiagnosticsEngine &Diags;
13855 SourceLocation SavedLoc;
13856 bool IsIgnored = false;
13859 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
13861 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
13863 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
13864 /*Map*/ diag::Severity::Ignored, Loc);
13867 ~DiagsUninitializedSeveretyRAII() {
13869 Diags.popMappings(SavedLoc);
13874 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
13875 SourceLocation StartLoc,
13876 SourceLocation LParenLoc,
13877 SourceLocation EndLoc) {
13878 SmallVector<Expr *, 8> Vars;
13879 SmallVector<Expr *, 8> PrivateCopies;
13880 SmallVector<Expr *, 8> Inits;
13881 SmallVector<Decl *, 4> ExprCaptures;
13882 bool IsImplicitClause =
13883 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
13884 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
13886 for (Expr *RefExpr : VarList) {
13887 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
13888 SourceLocation ELoc;
13889 SourceRange ERange;
13890 Expr *SimpleRefExpr = RefExpr;
13891 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13893 // It will be analyzed later.
13894 Vars.push_back(RefExpr);
13895 PrivateCopies.push_back(nullptr);
13896 Inits.push_back(nullptr);
13898 ValueDecl *D = Res.first;
13902 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
13903 QualType Type = D->getType();
13904 auto *VD = dyn_cast<VarDecl>(D);
13906 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13907 // A variable that appears in a private clause must not have an incomplete
13908 // type or a reference type.
13909 if (RequireCompleteType(ELoc, Type,
13910 diag::err_omp_firstprivate_incomplete_type))
13912 Type = Type.getNonReferenceType();
13914 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
13915 // A variable of class type (or array thereof) that appears in a private
13916 // clause requires an accessible, unambiguous copy constructor for the
13918 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
13920 // If an implicit firstprivate variable found it was checked already.
13921 DSAStackTy::DSAVarData TopDVar;
13922 if (!IsImplicitClause) {
13923 DSAStackTy::DSAVarData DVar =
13924 DSAStack->getTopDSA(D, /*FromParent=*/false);
13926 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13927 bool IsConstant = ElemType.isConstant(Context);
13928 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
13929 // A list item that specifies a given variable may not appear in more
13930 // than one clause on the same directive, except that a variable may be
13931 // specified in both firstprivate and lastprivate clauses.
13932 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13933 // A list item may appear in a firstprivate or lastprivate clause but not
13935 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
13936 (isOpenMPDistributeDirective(CurrDir) ||
13937 DVar.CKind != OMPC_lastprivate) &&
13939 Diag(ELoc, diag::err_omp_wrong_dsa)
13940 << getOpenMPClauseName(DVar.CKind)
13941 << getOpenMPClauseName(OMPC_firstprivate);
13942 reportOriginalDsa(*this, DSAStack, D, DVar);
13946 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13948 // Variables with the predetermined data-sharing attributes may not be
13949 // listed in data-sharing attributes clauses, except for the cases
13950 // listed below. For these exceptions only, listing a predetermined
13951 // variable in a data-sharing attribute clause is allowed and overrides
13952 // the variable's predetermined data-sharing attributes.
13953 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13954 // in a Construct, C/C++, p.2]
13955 // Variables with const-qualified type having no mutable member may be
13956 // listed in a firstprivate clause, even if they are static data members.
13957 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
13958 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
13959 Diag(ELoc, diag::err_omp_wrong_dsa)
13960 << getOpenMPClauseName(DVar.CKind)
13961 << getOpenMPClauseName(OMPC_firstprivate);
13962 reportOriginalDsa(*this, DSAStack, D, DVar);
13966 // OpenMP [2.9.3.4, Restrictions, p.2]
13967 // A list item that is private within a parallel region must not appear
13968 // in a firstprivate clause on a worksharing construct if any of the
13969 // worksharing regions arising from the worksharing construct ever bind
13970 // to any of the parallel regions arising from the parallel construct.
13971 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13972 // A list item that is private within a teams region must not appear in a
13973 // firstprivate clause on a distribute construct if any of the distribute
13974 // regions arising from the distribute construct ever bind to any of the
13975 // teams regions arising from the teams construct.
13976 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13977 // A list item that appears in a reduction clause of a teams construct
13978 // must not appear in a firstprivate clause on a distribute construct if
13979 // any of the distribute regions arising from the distribute construct
13980 // ever bind to any of the teams regions arising from the teams construct.
13981 if ((isOpenMPWorksharingDirective(CurrDir) ||
13982 isOpenMPDistributeDirective(CurrDir)) &&
13983 !isOpenMPParallelDirective(CurrDir) &&
13984 !isOpenMPTeamsDirective(CurrDir)) {
13985 DVar = DSAStack->getImplicitDSA(D, true);
13986 if (DVar.CKind != OMPC_shared &&
13987 (isOpenMPParallelDirective(DVar.DKind) ||
13988 isOpenMPTeamsDirective(DVar.DKind) ||
13989 DVar.DKind == OMPD_unknown)) {
13990 Diag(ELoc, diag::err_omp_required_access)
13991 << getOpenMPClauseName(OMPC_firstprivate)
13992 << getOpenMPClauseName(OMPC_shared);
13993 reportOriginalDsa(*this, DSAStack, D, DVar);
13997 // OpenMP [2.9.3.4, Restrictions, p.3]
13998 // A list item that appears in a reduction clause of a parallel construct
13999 // must not appear in a firstprivate clause on a worksharing or task
14000 // construct if any of the worksharing or task regions arising from the
14001 // worksharing or task construct ever bind to any of the parallel regions
14002 // arising from the parallel construct.
14003 // OpenMP [2.9.3.4, Restrictions, p.4]
14004 // A list item that appears in a reduction clause in worksharing
14005 // construct must not appear in a firstprivate clause in a task construct
14006 // encountered during execution of any of the worksharing regions arising
14007 // from the worksharing construct.
14008 if (isOpenMPTaskingDirective(CurrDir)) {
14009 DVar = DSAStack->hasInnermostDSA(
14010 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
14011 [](OpenMPDirectiveKind K) {
14012 return isOpenMPParallelDirective(K) ||
14013 isOpenMPWorksharingDirective(K) ||
14014 isOpenMPTeamsDirective(K);
14016 /*FromParent=*/true);
14017 if (DVar.CKind == OMPC_reduction &&
14018 (isOpenMPParallelDirective(DVar.DKind) ||
14019 isOpenMPWorksharingDirective(DVar.DKind) ||
14020 isOpenMPTeamsDirective(DVar.DKind))) {
14021 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14022 << getOpenMPDirectiveName(DVar.DKind);
14023 reportOriginalDsa(*this, DSAStack, D, DVar);
14028 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14029 // A list item cannot appear in both a map clause and a data-sharing
14030 // attribute clause on the same construct
14032 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14033 // A list item cannot appear in both a map clause and a data-sharing
14034 // attribute clause on the same construct unless the construct is a
14035 // combined construct.
14036 if ((LangOpts.OpenMP <= 45 &&
14037 isOpenMPTargetExecutionDirective(CurrDir)) ||
14038 CurrDir == OMPD_target) {
14039 OpenMPClauseKind ConflictKind;
14040 if (DSAStack->checkMappableExprComponentListsForDecl(
14041 VD, /*CurrentRegionOnly=*/true,
14043 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14044 OpenMPClauseKind WhereFoundClauseKind) {
14045 ConflictKind = WhereFoundClauseKind;
14048 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14049 << getOpenMPClauseName(OMPC_firstprivate)
14050 << getOpenMPClauseName(ConflictKind)
14051 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14052 reportOriginalDsa(*this, DSAStack, D, DVar);
14058 // Variably modified types are not supported for tasks.
14059 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14060 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14061 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14062 << getOpenMPClauseName(OMPC_firstprivate) << Type
14063 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14066 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14067 Diag(D->getLocation(),
14068 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14073 Type = Type.getUnqualifiedType();
14074 VarDecl *VDPrivate =
14075 buildVarDecl(*this, ELoc, Type, D->getName(),
14076 D->hasAttrs() ? &D->getAttrs() : nullptr,
14077 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14078 // Generate helper private variable and initialize it with the value of the
14079 // original variable. The address of the original variable is replaced by
14080 // the address of the new private variable in the CodeGen. This new variable
14081 // is not added to IdResolver, so the code in the OpenMP region uses
14082 // original variable for proper diagnostics and variable capturing.
14083 Expr *VDInitRefExpr = nullptr;
14084 // For arrays generate initializer for single element and replace it by the
14085 // original array element in CodeGen.
14086 if (Type->isArrayType()) {
14088 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14089 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14090 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14091 ElemType = ElemType.getUnqualifiedType();
14092 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14093 ".firstprivate.temp");
14094 InitializedEntity Entity =
14095 InitializedEntity::InitializeVariable(VDInitTemp);
14096 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14098 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14099 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14100 if (Result.isInvalid())
14101 VDPrivate->setInvalidDecl();
14103 VDPrivate->setInit(Result.getAs<Expr>());
14104 // Remove temp variable declaration.
14105 Context.Deallocate(VDInitTemp);
14107 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14108 ".firstprivate.temp");
14109 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14110 RefExpr->getExprLoc());
14111 AddInitializerToDecl(VDPrivate,
14112 DefaultLvalueConversion(VDInitRefExpr).get(),
14113 /*DirectInit=*/false);
14115 if (VDPrivate->isInvalidDecl()) {
14116 if (IsImplicitClause) {
14117 Diag(RefExpr->getExprLoc(),
14118 diag::note_omp_task_predetermined_firstprivate_here);
14122 CurContext->addDecl(VDPrivate);
14123 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14124 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14125 RefExpr->getExprLoc());
14126 DeclRefExpr *Ref = nullptr;
14127 if (!VD && !CurContext->isDependentContext()) {
14128 if (TopDVar.CKind == OMPC_lastprivate) {
14129 Ref = TopDVar.PrivateCopy;
14131 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14132 if (!isOpenMPCapturedDecl(D))
14133 ExprCaptures.push_back(Ref->getDecl());
14136 if (!IsImplicitClause)
14137 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14138 Vars.push_back((VD || CurContext->isDependentContext())
14139 ? RefExpr->IgnoreParens()
14141 PrivateCopies.push_back(VDPrivateRefExpr);
14142 Inits.push_back(VDInitRefExpr);
14148 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14149 Vars, PrivateCopies, Inits,
14150 buildPreInits(Context, ExprCaptures));
14153 OMPClause *Sema::ActOnOpenMPLastprivateClause(
14154 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14155 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14156 SourceLocation LParenLoc, SourceLocation EndLoc) {
14157 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14158 assert(ColonLoc.isValid() && "Colon location must be valid.");
14159 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14160 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14161 /*Last=*/OMPC_LASTPRIVATE_unknown)
14162 << getOpenMPClauseName(OMPC_lastprivate);
14166 SmallVector<Expr *, 8> Vars;
14167 SmallVector<Expr *, 8> SrcExprs;
14168 SmallVector<Expr *, 8> DstExprs;
14169 SmallVector<Expr *, 8> AssignmentOps;
14170 SmallVector<Decl *, 4> ExprCaptures;
14171 SmallVector<Expr *, 4> ExprPostUpdates;
14172 for (Expr *RefExpr : VarList) {
14173 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14174 SourceLocation ELoc;
14175 SourceRange ERange;
14176 Expr *SimpleRefExpr = RefExpr;
14177 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14179 // It will be analyzed later.
14180 Vars.push_back(RefExpr);
14181 SrcExprs.push_back(nullptr);
14182 DstExprs.push_back(nullptr);
14183 AssignmentOps.push_back(nullptr);
14185 ValueDecl *D = Res.first;
14189 QualType Type = D->getType();
14190 auto *VD = dyn_cast<VarDecl>(D);
14192 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14193 // A variable that appears in a lastprivate clause must not have an
14194 // incomplete type or a reference type.
14195 if (RequireCompleteType(ELoc, Type,
14196 diag::err_omp_lastprivate_incomplete_type))
14198 Type = Type.getNonReferenceType();
14200 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14201 // A variable that is privatized must not have a const-qualified type
14202 // unless it is of class type with a mutable member. This restriction does
14203 // not apply to the firstprivate clause.
14205 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14206 // A variable that appears in a lastprivate clause must not have a
14207 // const-qualified type unless it is of class type with a mutable member.
14208 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14211 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14212 // A list item that appears in a lastprivate clause with the conditional
14213 // modifier must be a scalar variable.
14214 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14215 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14216 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14217 VarDecl::DeclarationOnly;
14218 Diag(D->getLocation(),
14219 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14224 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14225 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14227 // Variables with the predetermined data-sharing attributes may not be
14228 // listed in data-sharing attributes clauses, except for the cases
14230 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14231 // A list item may appear in a firstprivate or lastprivate clause but not
14233 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14234 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14235 (isOpenMPDistributeDirective(CurrDir) ||
14236 DVar.CKind != OMPC_firstprivate) &&
14237 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14238 Diag(ELoc, diag::err_omp_wrong_dsa)
14239 << getOpenMPClauseName(DVar.CKind)
14240 << getOpenMPClauseName(OMPC_lastprivate);
14241 reportOriginalDsa(*this, DSAStack, D, DVar);
14245 // OpenMP [2.14.3.5, Restrictions, p.2]
14246 // A list item that is private within a parallel region, or that appears in
14247 // the reduction clause of a parallel construct, must not appear in a
14248 // lastprivate clause on a worksharing construct if any of the corresponding
14249 // worksharing regions ever binds to any of the corresponding parallel
14251 DSAStackTy::DSAVarData TopDVar = DVar;
14252 if (isOpenMPWorksharingDirective(CurrDir) &&
14253 !isOpenMPParallelDirective(CurrDir) &&
14254 !isOpenMPTeamsDirective(CurrDir)) {
14255 DVar = DSAStack->getImplicitDSA(D, true);
14256 if (DVar.CKind != OMPC_shared) {
14257 Diag(ELoc, diag::err_omp_required_access)
14258 << getOpenMPClauseName(OMPC_lastprivate)
14259 << getOpenMPClauseName(OMPC_shared);
14260 reportOriginalDsa(*this, DSAStack, D, DVar);
14265 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14266 // A variable of class type (or array thereof) that appears in a
14267 // lastprivate clause requires an accessible, unambiguous default
14268 // constructor for the class type, unless the list item is also specified
14269 // in a firstprivate clause.
14270 // A variable of class type (or array thereof) that appears in a
14271 // lastprivate clause requires an accessible, unambiguous copy assignment
14272 // operator for the class type.
14273 Type = Context.getBaseElementType(Type).getNonReferenceType();
14274 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14275 Type.getUnqualifiedType(), ".lastprivate.src",
14276 D->hasAttrs() ? &D->getAttrs() : nullptr);
14277 DeclRefExpr *PseudoSrcExpr =
14278 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14280 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14281 D->hasAttrs() ? &D->getAttrs() : nullptr);
14282 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14283 // For arrays generate assignment operation for single element and replace
14284 // it by the original array element in CodeGen.
14285 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14286 PseudoDstExpr, PseudoSrcExpr);
14287 if (AssignmentOp.isInvalid())
14290 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14291 if (AssignmentOp.isInvalid())
14294 DeclRefExpr *Ref = nullptr;
14295 if (!VD && !CurContext->isDependentContext()) {
14296 if (TopDVar.CKind == OMPC_firstprivate) {
14297 Ref = TopDVar.PrivateCopy;
14299 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14300 if (!isOpenMPCapturedDecl(D))
14301 ExprCaptures.push_back(Ref->getDecl());
14303 if (TopDVar.CKind == OMPC_firstprivate ||
14304 (!isOpenMPCapturedDecl(D) &&
14305 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14306 ExprResult RefRes = DefaultLvalueConversion(Ref);
14307 if (!RefRes.isUsable())
14309 ExprResult PostUpdateRes =
14310 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14312 if (!PostUpdateRes.isUsable())
14314 ExprPostUpdates.push_back(
14315 IgnoredValueConversions(PostUpdateRes.get()).get());
14318 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14319 Vars.push_back((VD || CurContext->isDependentContext())
14320 ? RefExpr->IgnoreParens()
14322 SrcExprs.push_back(PseudoSrcExpr);
14323 DstExprs.push_back(PseudoDstExpr);
14324 AssignmentOps.push_back(AssignmentOp.get());
14330 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14331 Vars, SrcExprs, DstExprs, AssignmentOps,
14332 LPKind, LPKindLoc, ColonLoc,
14333 buildPreInits(Context, ExprCaptures),
14334 buildPostUpdate(*this, ExprPostUpdates));
14337 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14338 SourceLocation StartLoc,
14339 SourceLocation LParenLoc,
14340 SourceLocation EndLoc) {
14341 SmallVector<Expr *, 8> Vars;
14342 for (Expr *RefExpr : VarList) {
14343 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14344 SourceLocation ELoc;
14345 SourceRange ERange;
14346 Expr *SimpleRefExpr = RefExpr;
14347 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14349 // It will be analyzed later.
14350 Vars.push_back(RefExpr);
14352 ValueDecl *D = Res.first;
14356 auto *VD = dyn_cast<VarDecl>(D);
14357 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14359 // Variables with the predetermined data-sharing attributes may not be
14360 // listed in data-sharing attributes clauses, except for the cases
14361 // listed below. For these exceptions only, listing a predetermined
14362 // variable in a data-sharing attribute clause is allowed and overrides
14363 // the variable's predetermined data-sharing attributes.
14364 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14365 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14367 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14368 << getOpenMPClauseName(OMPC_shared);
14369 reportOriginalDsa(*this, DSAStack, D, DVar);
14373 DeclRefExpr *Ref = nullptr;
14374 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14375 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14376 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14377 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14378 ? RefExpr->IgnoreParens()
14385 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14389 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14393 bool VisitDeclRefExpr(DeclRefExpr *E) {
14394 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14395 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14396 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14398 if (DVar.CKind != OMPC_unknown)
14400 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14401 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
14402 /*FromParent=*/true);
14403 return DVarPrivate.CKind != OMPC_unknown;
14407 bool VisitStmt(Stmt *S) {
14408 for (Stmt *Child : S->children()) {
14409 if (Child && Visit(Child))
14414 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14419 // Transform MemberExpression for specified FieldDecl of current class to
14420 // DeclRefExpr to specified OMPCapturedExprDecl.
14421 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14422 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14423 ValueDecl *Field = nullptr;
14424 DeclRefExpr *CapturedExpr = nullptr;
14427 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14428 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14430 ExprResult TransformMemberExpr(MemberExpr *E) {
14431 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14432 E->getMemberDecl() == Field) {
14433 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14434 return CapturedExpr;
14436 return BaseTransform::TransformMemberExpr(E);
14438 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14442 template <typename T, typename U>
14443 static T filterLookupForUDReductionAndMapper(
14444 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14445 for (U &Set : Lookups) {
14446 for (auto *D : Set) {
14447 if (T Res = Gen(cast<ValueDecl>(D)))
14454 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14455 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14457 for (auto RD : D->redecls()) {
14458 // Don't bother with extra checks if we already know this one isn't visible.
14462 auto ND = cast<NamedDecl>(RD);
14463 if (LookupResult::isVisible(SemaRef, ND))
14471 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14472 SourceLocation Loc, QualType Ty,
14473 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14474 // Find all of the associated namespaces and classes based on the
14475 // arguments we have.
14476 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14477 Sema::AssociatedClassSet AssociatedClasses;
14478 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14479 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14480 AssociatedClasses);
14482 // C++ [basic.lookup.argdep]p3:
14483 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14484 // and let Y be the lookup set produced by argument dependent
14485 // lookup (defined as follows). If X contains [...] then Y is
14486 // empty. Otherwise Y is the set of declarations found in the
14487 // namespaces associated with the argument types as described
14488 // below. The set of declarations found by the lookup of the name
14489 // is the union of X and Y.
14491 // Here, we compute Y and add its members to the overloaded
14493 for (auto *NS : AssociatedNamespaces) {
14494 // When considering an associated namespace, the lookup is the
14495 // same as the lookup performed when the associated namespace is
14496 // used as a qualifier (3.4.3.2) except that:
14498 // -- Any using-directives in the associated namespace are
14501 // -- Any namespace-scope friend functions declared in
14502 // associated classes are visible within their respective
14503 // namespaces even if they are not visible during an ordinary
14505 DeclContext::lookup_result R = NS->lookup(Id.getName());
14506 for (auto *D : R) {
14507 auto *Underlying = D;
14508 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14509 Underlying = USD->getTargetDecl();
14511 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14512 !isa<OMPDeclareMapperDecl>(Underlying))
14515 if (!SemaRef.isVisible(D)) {
14516 D = findAcceptableDecl(SemaRef, D);
14519 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14520 Underlying = USD->getTargetDecl();
14522 Lookups.emplace_back();
14523 Lookups.back().addDecl(Underlying);
14529 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14530 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14531 const DeclarationNameInfo &ReductionId, QualType Ty,
14532 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14533 if (ReductionIdScopeSpec.isInvalid())
14534 return ExprError();
14535 SmallVector<UnresolvedSet<8>, 4> Lookups;
14537 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14538 Lookup.suppressDiagnostics();
14539 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14540 NamedDecl *D = Lookup.getRepresentativeDecl();
14542 S = S->getParent();
14543 } while (S && !S->isDeclScope(D));
14545 S = S->getParent();
14546 Lookups.emplace_back();
14547 Lookups.back().append(Lookup.begin(), Lookup.end());
14550 } else if (auto *ULE =
14551 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14552 Lookups.push_back(UnresolvedSet<8>());
14553 Decl *PrevD = nullptr;
14554 for (NamedDecl *D : ULE->decls()) {
14556 Lookups.push_back(UnresolvedSet<8>());
14557 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14558 Lookups.back().addDecl(DRD);
14562 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14563 Ty->isInstantiationDependentType() ||
14564 Ty->containsUnexpandedParameterPack() ||
14565 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14566 return !D->isInvalidDecl() &&
14567 (D->getType()->isDependentType() ||
14568 D->getType()->isInstantiationDependentType() ||
14569 D->getType()->containsUnexpandedParameterPack());
14571 UnresolvedSet<8> ResSet;
14572 for (const UnresolvedSet<8> &Set : Lookups) {
14575 ResSet.append(Set.begin(), Set.end());
14576 // The last item marks the end of all declarations at the specified scope.
14577 ResSet.addDecl(Set[Set.size() - 1]);
14579 return UnresolvedLookupExpr::Create(
14580 SemaRef.Context, /*NamingClass=*/nullptr,
14581 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14582 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14584 // Lookup inside the classes.
14585 // C++ [over.match.oper]p3:
14586 // For a unary operator @ with an operand of a type whose
14587 // cv-unqualified version is T1, and for a binary operator @ with
14588 // a left operand of a type whose cv-unqualified version is T1 and
14589 // a right operand of a type whose cv-unqualified version is T2,
14590 // three sets of candidate functions, designated member
14591 // candidates, non-member candidates and built-in candidates, are
14592 // constructed as follows:
14593 // -- If T1 is a complete class type or a class currently being
14594 // defined, the set of member candidates is the result of the
14595 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14596 // the set of member candidates is empty.
14597 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14598 Lookup.suppressDiagnostics();
14599 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14600 // Complete the type if it can be completed.
14601 // If the type is neither complete nor being defined, bail out now.
14602 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14603 TyRec->getDecl()->getDefinition()) {
14605 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14606 if (Lookup.empty()) {
14607 Lookups.emplace_back();
14608 Lookups.back().append(Lookup.begin(), Lookup.end());
14613 if (SemaRef.getLangOpts().CPlusPlus)
14614 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14615 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14616 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14617 if (!D->isInvalidDecl() &&
14618 SemaRef.Context.hasSameType(D->getType(), Ty))
14622 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14624 if (SemaRef.getLangOpts().CPlusPlus) {
14625 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14626 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14627 if (!D->isInvalidDecl() &&
14628 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14629 !Ty.isMoreQualifiedThan(D->getType()))
14633 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14634 /*DetectVirtual=*/false);
14635 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14636 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14637 VD->getType().getUnqualifiedType()))) {
14638 if (SemaRef.CheckBaseClassAccess(
14639 Loc, VD->getType(), Ty, Paths.front(),
14640 /*DiagID=*/0) != Sema::AR_inaccessible) {
14641 SemaRef.BuildBasePathArray(Paths, BasePath);
14642 return SemaRef.BuildDeclRefExpr(
14643 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14649 if (ReductionIdScopeSpec.isSet()) {
14650 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14652 return ExprError();
14654 return ExprEmpty();
14658 /// Data for the reduction-based clauses.
14659 struct ReductionData {
14660 /// List of original reduction items.
14661 SmallVector<Expr *, 8> Vars;
14662 /// List of private copies of the reduction items.
14663 SmallVector<Expr *, 8> Privates;
14664 /// LHS expressions for the reduction_op expressions.
14665 SmallVector<Expr *, 8> LHSs;
14666 /// RHS expressions for the reduction_op expressions.
14667 SmallVector<Expr *, 8> RHSs;
14668 /// Reduction operation expression.
14669 SmallVector<Expr *, 8> ReductionOps;
14670 /// inscan copy operation expressions.
14671 SmallVector<Expr *, 8> InscanCopyOps;
14672 /// inscan copy temp array expressions for prefix sums.
14673 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14674 /// inscan copy temp array element expressions for prefix sums.
14675 SmallVector<Expr *, 8> InscanCopyArrayElems;
14676 /// Taskgroup descriptors for the corresponding reduction items in
14677 /// in_reduction clauses.
14678 SmallVector<Expr *, 8> TaskgroupDescriptors;
14679 /// List of captures for clause.
14680 SmallVector<Decl *, 4> ExprCaptures;
14681 /// List of postupdate expressions.
14682 SmallVector<Expr *, 4> ExprPostUpdates;
14683 /// Reduction modifier.
14684 unsigned RedModifier = 0;
14685 ReductionData() = delete;
14686 /// Reserves required memory for the reduction data.
14687 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14688 Vars.reserve(Size);
14689 Privates.reserve(Size);
14690 LHSs.reserve(Size);
14691 RHSs.reserve(Size);
14692 ReductionOps.reserve(Size);
14693 if (RedModifier == OMPC_REDUCTION_inscan) {
14694 InscanCopyOps.reserve(Size);
14695 InscanCopyArrayTemps.reserve(Size);
14696 InscanCopyArrayElems.reserve(Size);
14698 TaskgroupDescriptors.reserve(Size);
14699 ExprCaptures.reserve(Size);
14700 ExprPostUpdates.reserve(Size);
14702 /// Stores reduction item and reduction operation only (required for dependent
14703 /// reduction item).
14704 void push(Expr *Item, Expr *ReductionOp) {
14705 Vars.emplace_back(Item);
14706 Privates.emplace_back(nullptr);
14707 LHSs.emplace_back(nullptr);
14708 RHSs.emplace_back(nullptr);
14709 ReductionOps.emplace_back(ReductionOp);
14710 TaskgroupDescriptors.emplace_back(nullptr);
14711 if (RedModifier == OMPC_REDUCTION_inscan) {
14712 InscanCopyOps.push_back(nullptr);
14713 InscanCopyArrayTemps.push_back(nullptr);
14714 InscanCopyArrayElems.push_back(nullptr);
14717 /// Stores reduction data.
14718 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14719 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14720 Expr *CopyArrayElem) {
14721 Vars.emplace_back(Item);
14722 Privates.emplace_back(Private);
14723 LHSs.emplace_back(LHS);
14724 RHSs.emplace_back(RHS);
14725 ReductionOps.emplace_back(ReductionOp);
14726 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14727 if (RedModifier == OMPC_REDUCTION_inscan) {
14728 InscanCopyOps.push_back(CopyOp);
14729 InscanCopyArrayTemps.push_back(CopyArrayTemp);
14730 InscanCopyArrayElems.push_back(CopyArrayElem);
14732 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
14733 CopyArrayElem == nullptr &&
14734 "Copy operation must be used for inscan reductions only.");
14740 static bool checkOMPArraySectionConstantForReduction(
14741 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14742 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14743 const Expr *Length = OASE->getLength();
14744 if (Length == nullptr) {
14745 // For array sections of the form [1:] or [:], we would need to analyze
14746 // the lower bound...
14747 if (OASE->getColonLocFirst().isValid())
14750 // This is an array subscript which has implicit length 1!
14751 SingleElement = true;
14752 ArraySizes.push_back(llvm::APSInt::get(1));
14754 Expr::EvalResult Result;
14755 if (!Length->EvaluateAsInt(Result, Context))
14758 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14759 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14760 ArraySizes.push_back(ConstantLengthValue);
14763 // Get the base of this array section and walk up from there.
14764 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14766 // We require length = 1 for all array sections except the right-most to
14767 // guarantee that the memory region is contiguous and has no holes in it.
14768 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14769 Length = TempOASE->getLength();
14770 if (Length == nullptr) {
14771 // For array sections of the form [1:] or [:], we would need to analyze
14772 // the lower bound...
14773 if (OASE->getColonLocFirst().isValid())
14776 // This is an array subscript which has implicit length 1!
14777 ArraySizes.push_back(llvm::APSInt::get(1));
14779 Expr::EvalResult Result;
14780 if (!Length->EvaluateAsInt(Result, Context))
14783 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14784 if (ConstantLengthValue.getSExtValue() != 1)
14787 ArraySizes.push_back(ConstantLengthValue);
14789 Base = TempOASE->getBase()->IgnoreParenImpCasts();
14792 // If we have a single element, we don't need to add the implicit lengths.
14793 if (!SingleElement) {
14794 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14795 // Has implicit length 1!
14796 ArraySizes.push_back(llvm::APSInt::get(1));
14797 Base = TempASE->getBase()->IgnoreParenImpCasts();
14801 // This array section can be privatized as a single value or as a constant
14806 static bool actOnOMPReductionKindClause(
14807 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14808 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14809 SourceLocation ColonLoc, SourceLocation EndLoc,
14810 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14811 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14812 DeclarationName DN = ReductionId.getName();
14813 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14814 BinaryOperatorKind BOK = BO_Comma;
14816 ASTContext &Context = S.Context;
14817 // OpenMP [2.14.3.6, reduction clause]
14819 // reduction-identifier is either an identifier or one of the following
14820 // operators: +, -, *, &, |, ^, && and ||
14822 // reduction-identifier is either an id-expression or one of the following
14823 // operators: +, -, *, &, |, ^, && and ||
14850 case OO_Array_Delete:
14859 case OO_GreaterEqual:
14861 case OO_MinusEqual:
14863 case OO_SlashEqual:
14864 case OO_PercentEqual:
14865 case OO_CaretEqual:
14869 case OO_GreaterGreater:
14870 case OO_LessLessEqual:
14871 case OO_GreaterGreaterEqual:
14872 case OO_EqualEqual:
14873 case OO_ExclaimEqual:
14876 case OO_MinusMinus:
14882 case OO_Conditional:
14884 case NUM_OVERLOADED_OPERATORS:
14885 llvm_unreachable("Unexpected reduction identifier");
14887 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
14888 if (II->isStr("max"))
14890 else if (II->isStr("min"))
14895 SourceRange ReductionIdRange;
14896 if (ReductionIdScopeSpec.isValid())
14897 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
14899 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
14900 ReductionIdRange.setEnd(ReductionId.getEndLoc());
14902 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
14903 bool FirstIter = true;
14904 for (Expr *RefExpr : VarList) {
14905 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
14906 // OpenMP [2.1, C/C++]
14907 // A list item is a variable or array section, subject to the restrictions
14908 // specified in Section 2.4 on page 42 and in each of the sections
14909 // describing clauses and directives for which a list appears.
14910 // OpenMP [2.14.3.3, Restrictions, p.1]
14911 // A variable that is part of another variable (as an array or
14912 // structure element) cannot appear in a private clause.
14913 if (!FirstIter && IR != ER)
14916 SourceLocation ELoc;
14917 SourceRange ERange;
14918 Expr *SimpleRefExpr = RefExpr;
14919 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
14920 /*AllowArraySection=*/true);
14922 // Try to find 'declare reduction' corresponding construct before using
14923 // builtin/overloaded operators.
14924 QualType Type = Context.DependentTy;
14925 CXXCastPath BasePath;
14926 ExprResult DeclareReductionRef = buildDeclareReductionRef(
14927 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
14928 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
14929 Expr *ReductionOp = nullptr;
14930 if (S.CurContext->isDependentContext() &&
14931 (DeclareReductionRef.isUnset() ||
14932 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
14933 ReductionOp = DeclareReductionRef.get();
14934 // It will be analyzed later.
14935 RD.push(RefExpr, ReductionOp);
14937 ValueDecl *D = Res.first;
14941 Expr *TaskgroupDescriptor = nullptr;
14943 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
14944 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
14946 Type = ASE->getType().getNonReferenceType();
14948 QualType BaseType =
14949 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
14950 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
14951 Type = ATy->getElementType();
14953 Type = BaseType->getPointeeType();
14954 Type = Type.getNonReferenceType();
14956 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
14958 auto *VD = dyn_cast<VarDecl>(D);
14960 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14961 // A variable that appears in a private clause must not have an incomplete
14962 // type or a reference type.
14963 if (S.RequireCompleteType(ELoc, D->getType(),
14964 diag::err_omp_reduction_incomplete_type))
14966 // OpenMP [2.14.3.6, reduction clause, Restrictions]
14967 // A list item that appears in a reduction clause must not be
14968 // const-qualified.
14969 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
14970 /*AcceptIfMutable*/ false, ASE || OASE))
14973 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
14974 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
14975 // If a list-item is a reference type then it must bind to the same object
14976 // for all threads of the team.
14977 if (!ASE && !OASE) {
14979 VarDecl *VDDef = VD->getDefinition();
14980 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
14981 DSARefChecker Check(Stack);
14982 if (Check.Visit(VDDef->getInit())) {
14983 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
14984 << getOpenMPClauseName(ClauseKind) << ERange;
14985 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
14991 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14993 // Variables with the predetermined data-sharing attributes may not be
14994 // listed in data-sharing attributes clauses, except for the cases
14995 // listed below. For these exceptions only, listing a predetermined
14996 // variable in a data-sharing attribute clause is allowed and overrides
14997 // the variable's predetermined data-sharing attributes.
14998 // OpenMP [2.14.3.6, Restrictions, p.3]
14999 // Any number of reduction clauses can be specified on the directive,
15000 // but a list item can appear only once in the reduction clauses for that
15002 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
15003 if (DVar.CKind == OMPC_reduction) {
15004 S.Diag(ELoc, diag::err_omp_once_referenced)
15005 << getOpenMPClauseName(ClauseKind);
15007 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15010 if (DVar.CKind != OMPC_unknown) {
15011 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15012 << getOpenMPClauseName(DVar.CKind)
15013 << getOpenMPClauseName(OMPC_reduction);
15014 reportOriginalDsa(S, Stack, D, DVar);
15018 // OpenMP [2.14.3.6, Restrictions, p.1]
15019 // A list item that appears in a reduction clause of a worksharing
15020 // construct must be shared in the parallel regions to which any of the
15021 // worksharing regions arising from the worksharing construct bind.
15022 if (isOpenMPWorksharingDirective(CurrDir) &&
15023 !isOpenMPParallelDirective(CurrDir) &&
15024 !isOpenMPTeamsDirective(CurrDir)) {
15025 DVar = Stack->getImplicitDSA(D, true);
15026 if (DVar.CKind != OMPC_shared) {
15027 S.Diag(ELoc, diag::err_omp_required_access)
15028 << getOpenMPClauseName(OMPC_reduction)
15029 << getOpenMPClauseName(OMPC_shared);
15030 reportOriginalDsa(S, Stack, D, DVar);
15036 // Try to find 'declare reduction' corresponding construct before using
15037 // builtin/overloaded operators.
15038 CXXCastPath BasePath;
15039 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15040 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15041 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15042 if (DeclareReductionRef.isInvalid())
15044 if (S.CurContext->isDependentContext() &&
15045 (DeclareReductionRef.isUnset() ||
15046 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15047 RD.push(RefExpr, DeclareReductionRef.get());
15050 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15051 // Not allowed reduction identifier is found.
15052 S.Diag(ReductionId.getBeginLoc(),
15053 diag::err_omp_unknown_reduction_identifier)
15054 << Type << ReductionIdRange;
15058 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15059 // The type of a list item that appears in a reduction clause must be valid
15060 // for the reduction-identifier. For a max or min reduction in C, the type
15061 // of the list item must be an allowed arithmetic data type: char, int,
15062 // float, double, or _Bool, possibly modified with long, short, signed, or
15063 // unsigned. For a max or min reduction in C++, the type of the list item
15064 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15065 // double, or bool, possibly modified with long, short, signed, or unsigned.
15066 if (DeclareReductionRef.isUnset()) {
15067 if ((BOK == BO_GT || BOK == BO_LT) &&
15068 !(Type->isScalarType() ||
15069 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15070 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15071 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15072 if (!ASE && !OASE) {
15073 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15074 VarDecl::DeclarationOnly;
15075 S.Diag(D->getLocation(),
15076 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15081 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15082 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15083 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15084 << getOpenMPClauseName(ClauseKind);
15085 if (!ASE && !OASE) {
15086 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15087 VarDecl::DeclarationOnly;
15088 S.Diag(D->getLocation(),
15089 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15096 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15097 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15098 D->hasAttrs() ? &D->getAttrs() : nullptr);
15099 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15100 D->hasAttrs() ? &D->getAttrs() : nullptr);
15101 QualType PrivateTy = Type;
15103 // Try if we can determine constant lengths for all array sections and avoid
15105 bool ConstantLengthOASE = false;
15107 bool SingleElement;
15108 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15109 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15110 Context, OASE, SingleElement, ArraySizes);
15112 // If we don't have a single element, we must emit a constant array type.
15113 if (ConstantLengthOASE && !SingleElement) {
15114 for (llvm::APSInt &Size : ArraySizes)
15115 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15117 /*IndexTypeQuals=*/0);
15121 if ((OASE && !ConstantLengthOASE) ||
15123 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15124 if (!Context.getTargetInfo().isVLASupported()) {
15125 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15126 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15127 S.Diag(ELoc, diag::note_vla_unsupported);
15130 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15131 S.targetDiag(ELoc, diag::note_vla_unsupported);
15134 // For arrays/array sections only:
15135 // Create pseudo array type for private copy. The size for this array will
15136 // be generated during codegen.
15137 // For array subscripts or single variables Private Ty is the same as Type
15138 // (type of the variable or single array element).
15139 PrivateTy = Context.getVariableArrayType(
15141 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15142 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15143 } else if (!ASE && !OASE &&
15144 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15145 PrivateTy = D->getType().getNonReferenceType();
15148 VarDecl *PrivateVD =
15149 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15150 D->hasAttrs() ? &D->getAttrs() : nullptr,
15151 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15152 // Add initializer for private variable.
15153 Expr *Init = nullptr;
15154 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15155 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15156 if (DeclareReductionRef.isUsable()) {
15157 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15158 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15159 if (DRD->getInitializer()) {
15160 S.ActOnUninitializedDecl(PrivateVD);
15162 RHSVD->setInit(DRDRef);
15163 RHSVD->setInitStyle(VarDecl::CallInit);
15171 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15172 if (Type->isScalarType() || Type->isAnyComplexType())
15173 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15177 if (Type->isScalarType() || Type->isAnyComplexType()) {
15178 // '*' and '&&' reduction ops - initializer is '1'.
15179 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15183 // '&' reduction op - initializer is '~0'.
15184 QualType OrigType = Type;
15185 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15186 Type = ComplexTy->getElementType();
15187 if (Type->isRealFloatingType()) {
15188 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15189 Context.getFloatTypeSemantics(Type),
15190 Context.getTypeSize(Type));
15191 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15193 } else if (Type->isScalarType()) {
15194 uint64_t Size = Context.getTypeSize(Type);
15195 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15196 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15197 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15199 if (Init && OrigType->isAnyComplexType()) {
15200 // Init = 0xFFFF + 0xFFFFi;
15201 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15202 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15209 // 'min' reduction op - initializer is 'Largest representable number in
15210 // the reduction list item type'.
15211 // 'max' reduction op - initializer is 'Least representable number in
15212 // the reduction list item type'.
15213 if (Type->isIntegerType() || Type->isPointerType()) {
15214 bool IsSigned = Type->hasSignedIntegerRepresentation();
15215 uint64_t Size = Context.getTypeSize(Type);
15217 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15218 llvm::APInt InitValue =
15219 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15220 : llvm::APInt::getMinValue(Size)
15221 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15222 : llvm::APInt::getMaxValue(Size);
15223 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15224 if (Type->isPointerType()) {
15225 // Cast to pointer type.
15226 ExprResult CastExpr = S.BuildCStyleCastExpr(
15227 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15228 if (CastExpr.isInvalid())
15230 Init = CastExpr.get();
15232 } else if (Type->isRealFloatingType()) {
15233 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15234 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15235 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15264 llvm_unreachable("Unexpected reduction operation");
15267 if (Init && DeclareReductionRef.isUnset()) {
15268 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15269 // Store initializer for single element in private copy. Will be used
15271 PrivateVD->setInit(RHSVD->getInit());
15272 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15273 } else if (!Init) {
15274 S.ActOnUninitializedDecl(RHSVD);
15275 // Store initializer for single element in private copy. Will be used
15277 PrivateVD->setInit(RHSVD->getInit());
15278 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15280 if (RHSVD->isInvalidDecl())
15282 if (!RHSVD->hasInit() &&
15283 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15284 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15285 << Type << ReductionIdRange;
15286 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15287 VarDecl::DeclarationOnly;
15288 S.Diag(D->getLocation(),
15289 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15293 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15294 ExprResult ReductionOp;
15295 if (DeclareReductionRef.isUsable()) {
15296 QualType RedTy = DeclareReductionRef.get()->getType();
15297 QualType PtrRedTy = Context.getPointerType(RedTy);
15298 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15299 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15300 if (!BasePath.empty()) {
15301 LHS = S.DefaultLvalueConversion(LHS.get());
15302 RHS = S.DefaultLvalueConversion(RHS.get());
15303 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15304 CK_UncheckedDerivedToBase, LHS.get(),
15305 &BasePath, LHS.get()->getValueKind());
15306 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15307 CK_UncheckedDerivedToBase, RHS.get(),
15308 &BasePath, RHS.get()->getValueKind());
15310 FunctionProtoType::ExtProtoInfo EPI;
15311 QualType Params[] = {PtrRedTy, PtrRedTy};
15312 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15313 auto *OVE = new (Context) OpaqueValueExpr(
15314 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15315 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15316 Expr *Args[] = {LHS.get(), RHS.get()};
15318 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
15320 ReductionOp = S.BuildBinOp(
15321 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15322 if (ReductionOp.isUsable()) {
15323 if (BOK != BO_LT && BOK != BO_GT) {
15325 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15326 BO_Assign, LHSDRE, ReductionOp.get());
15328 auto *ConditionalOp = new (Context)
15329 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15330 Type, VK_LValue, OK_Ordinary);
15332 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15333 BO_Assign, LHSDRE, ConditionalOp);
15335 if (ReductionOp.isUsable())
15336 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15337 /*DiscardedValue*/ false);
15339 if (!ReductionOp.isUsable())
15343 // Add copy operations for inscan reductions.
15345 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15346 if (ClauseKind == OMPC_reduction &&
15347 RD.RedModifier == OMPC_REDUCTION_inscan) {
15348 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15349 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15351 if (!CopyOpRes.isUsable())
15354 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15355 if (!CopyOpRes.isUsable())
15357 // For simd directive and simd-based directives in simd mode no need to
15358 // construct temp array, need just a single temp element.
15359 if (Stack->getCurrentDirective() == OMPD_simd ||
15360 (S.getLangOpts().OpenMPSimd &&
15361 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15362 VarDecl *TempArrayVD =
15363 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15364 D->hasAttrs() ? &D->getAttrs() : nullptr);
15365 // Add a constructor to the temp decl.
15366 S.ActOnUninitializedDecl(TempArrayVD);
15367 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15369 // Build temp array for prefix sum.
15370 auto *Dim = new (S.Context)
15371 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15373 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15374 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15375 VarDecl *TempArrayVD =
15376 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15377 D->hasAttrs() ? &D->getAttrs() : nullptr);
15378 // Add a constructor to the temp decl.
15379 S.ActOnUninitializedDecl(TempArrayVD);
15380 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15382 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15383 auto *Idx = new (S.Context)
15384 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15385 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15390 // OpenMP [2.15.4.6, Restrictions, p.2]
15391 // A list item that appears in an in_reduction clause of a task construct
15392 // must appear in a task_reduction clause of a construct associated with a
15393 // taskgroup region that includes the participating task in its taskgroup
15394 // set. The construct associated with the innermost region that meets this
15395 // condition must specify the same reduction-identifier as the in_reduction
15397 if (ClauseKind == OMPC_in_reduction) {
15398 SourceRange ParentSR;
15399 BinaryOperatorKind ParentBOK;
15400 const Expr *ParentReductionOp = nullptr;
15401 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15402 DSAStackTy::DSAVarData ParentBOKDSA =
15403 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15405 DSAStackTy::DSAVarData ParentReductionOpDSA =
15406 Stack->getTopMostTaskgroupReductionData(
15407 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15408 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15409 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15410 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15411 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15412 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15413 bool EmitError = true;
15414 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15415 llvm::FoldingSetNodeID RedId, ParentRedId;
15416 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15417 DeclareReductionRef.get()->Profile(RedId, Context,
15418 /*Canonical=*/true);
15419 EmitError = RedId != ParentRedId;
15422 S.Diag(ReductionId.getBeginLoc(),
15423 diag::err_omp_reduction_identifier_mismatch)
15424 << ReductionIdRange << RefExpr->getSourceRange();
15425 S.Diag(ParentSR.getBegin(),
15426 diag::note_omp_previous_reduction_identifier)
15428 << (IsParentBOK ? ParentBOKDSA.RefExpr
15429 : ParentReductionOpDSA.RefExpr)
15430 ->getSourceRange();
15434 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15437 DeclRefExpr *Ref = nullptr;
15438 Expr *VarsExpr = RefExpr->IgnoreParens();
15439 if (!VD && !S.CurContext->isDependentContext()) {
15441 TransformExprToCaptures RebuildToCapture(S, D);
15443 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15444 Ref = RebuildToCapture.getCapturedExpr();
15446 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15448 if (!S.isOpenMPCapturedDecl(D)) {
15449 RD.ExprCaptures.emplace_back(Ref->getDecl());
15450 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15451 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15452 if (!RefRes.isUsable())
15454 ExprResult PostUpdateRes =
15455 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15457 if (!PostUpdateRes.isUsable())
15459 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15460 Stack->getCurrentDirective() == OMPD_taskgroup) {
15461 S.Diag(RefExpr->getExprLoc(),
15462 diag::err_omp_reduction_non_addressable_expression)
15463 << RefExpr->getSourceRange();
15466 RD.ExprPostUpdates.emplace_back(
15467 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15471 // All reduction items are still marked as reduction (to do not increase
15472 // code base size).
15473 unsigned Modifier = RD.RedModifier;
15474 // Consider task_reductions as reductions with task modifier. Required for
15475 // correct analysis of in_reduction clauses.
15476 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15477 Modifier = OMPC_REDUCTION_task;
15478 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier);
15479 if (Modifier == OMPC_REDUCTION_task &&
15480 (CurrDir == OMPD_taskgroup ||
15481 ((isOpenMPParallelDirective(CurrDir) ||
15482 isOpenMPWorksharingDirective(CurrDir)) &&
15483 !isOpenMPSimdDirective(CurrDir)))) {
15484 if (DeclareReductionRef.isUsable())
15485 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15486 DeclareReductionRef.get());
15488 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15490 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15491 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15492 TempArrayElem.get());
15494 return RD.Vars.empty();
15497 OMPClause *Sema::ActOnOpenMPReductionClause(
15498 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15499 SourceLocation StartLoc, SourceLocation LParenLoc,
15500 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15501 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15502 ArrayRef<Expr *> UnresolvedReductions) {
15503 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15504 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15505 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15506 /*Last=*/OMPC_REDUCTION_unknown)
15507 << getOpenMPClauseName(OMPC_reduction);
15510 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15511 // A reduction clause with the inscan reduction-modifier may only appear on a
15512 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15513 // construct, a parallel worksharing-loop construct or a parallel
15514 // worksharing-loop SIMD construct.
15515 if (Modifier == OMPC_REDUCTION_inscan &&
15516 (DSAStack->getCurrentDirective() != OMPD_for &&
15517 DSAStack->getCurrentDirective() != OMPD_for_simd &&
15518 DSAStack->getCurrentDirective() != OMPD_simd &&
15519 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15520 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15521 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15525 ReductionData RD(VarList.size(), Modifier);
15526 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15527 StartLoc, LParenLoc, ColonLoc, EndLoc,
15528 ReductionIdScopeSpec, ReductionId,
15529 UnresolvedReductions, RD))
15532 return OMPReductionClause::Create(
15533 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15534 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15535 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15536 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15537 buildPreInits(Context, RD.ExprCaptures),
15538 buildPostUpdate(*this, RD.ExprPostUpdates));
15541 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15542 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15543 SourceLocation ColonLoc, SourceLocation EndLoc,
15544 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15545 ArrayRef<Expr *> UnresolvedReductions) {
15546 ReductionData RD(VarList.size());
15547 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15548 StartLoc, LParenLoc, ColonLoc, EndLoc,
15549 ReductionIdScopeSpec, ReductionId,
15550 UnresolvedReductions, RD))
15553 return OMPTaskReductionClause::Create(
15554 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15555 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15556 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15557 buildPreInits(Context, RD.ExprCaptures),
15558 buildPostUpdate(*this, RD.ExprPostUpdates));
15561 OMPClause *Sema::ActOnOpenMPInReductionClause(
15562 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15563 SourceLocation ColonLoc, SourceLocation EndLoc,
15564 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15565 ArrayRef<Expr *> UnresolvedReductions) {
15566 ReductionData RD(VarList.size());
15567 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15568 StartLoc, LParenLoc, ColonLoc, EndLoc,
15569 ReductionIdScopeSpec, ReductionId,
15570 UnresolvedReductions, RD))
15573 return OMPInReductionClause::Create(
15574 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15575 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15576 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15577 buildPreInits(Context, RD.ExprCaptures),
15578 buildPostUpdate(*this, RD.ExprPostUpdates));
15581 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15582 SourceLocation LinLoc) {
15583 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15584 LinKind == OMPC_LINEAR_unknown) {
15585 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15591 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15592 OpenMPLinearClauseKind LinKind, QualType Type,
15593 bool IsDeclareSimd) {
15594 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15595 // A variable must not have an incomplete type or a reference type.
15596 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15598 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15599 !Type->isReferenceType()) {
15600 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15601 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15604 Type = Type.getNonReferenceType();
15606 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15607 // A variable that is privatized must not have a const-qualified type
15608 // unless it is of class type with a mutable member. This restriction does
15609 // not apply to the firstprivate clause, nor to the linear clause on
15610 // declarative directives (like declare simd).
15611 if (!IsDeclareSimd &&
15612 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15615 // A list item must be of integral or pointer type.
15616 Type = Type.getUnqualifiedType().getCanonicalType();
15617 const auto *Ty = Type.getTypePtrOrNull();
15618 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15619 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15620 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15624 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15625 Diag(D->getLocation(),
15626 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15634 OMPClause *Sema::ActOnOpenMPLinearClause(
15635 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15636 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15637 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15638 SmallVector<Expr *, 8> Vars;
15639 SmallVector<Expr *, 8> Privates;
15640 SmallVector<Expr *, 8> Inits;
15641 SmallVector<Decl *, 4> ExprCaptures;
15642 SmallVector<Expr *, 4> ExprPostUpdates;
15643 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15644 LinKind = OMPC_LINEAR_val;
15645 for (Expr *RefExpr : VarList) {
15646 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15647 SourceLocation ELoc;
15648 SourceRange ERange;
15649 Expr *SimpleRefExpr = RefExpr;
15650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15652 // It will be analyzed later.
15653 Vars.push_back(RefExpr);
15654 Privates.push_back(nullptr);
15655 Inits.push_back(nullptr);
15657 ValueDecl *D = Res.first;
15661 QualType Type = D->getType();
15662 auto *VD = dyn_cast<VarDecl>(D);
15664 // OpenMP [2.14.3.7, linear clause]
15665 // A list-item cannot appear in more than one linear clause.
15666 // A list-item that appears in a linear clause cannot appear in any
15667 // other data-sharing attribute clause.
15668 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15669 if (DVar.RefExpr) {
15670 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15671 << getOpenMPClauseName(OMPC_linear);
15672 reportOriginalDsa(*this, DSAStack, D, DVar);
15676 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15678 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15680 // Build private copy of original var.
15682 buildVarDecl(*this, ELoc, Type, D->getName(),
15683 D->hasAttrs() ? &D->getAttrs() : nullptr,
15684 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15685 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15686 // Build var to save initial value.
15687 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15689 DeclRefExpr *Ref = nullptr;
15690 if (!VD && !CurContext->isDependentContext()) {
15691 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15692 if (!isOpenMPCapturedDecl(D)) {
15693 ExprCaptures.push_back(Ref->getDecl());
15694 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15695 ExprResult RefRes = DefaultLvalueConversion(Ref);
15696 if (!RefRes.isUsable())
15698 ExprResult PostUpdateRes =
15699 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
15700 SimpleRefExpr, RefRes.get());
15701 if (!PostUpdateRes.isUsable())
15703 ExprPostUpdates.push_back(
15704 IgnoredValueConversions(PostUpdateRes.get()).get());
15708 if (LinKind == OMPC_LINEAR_uval)
15709 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15711 InitExpr = VD ? SimpleRefExpr : Ref;
15712 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15713 /*DirectInit=*/false);
15714 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15716 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15717 Vars.push_back((VD || CurContext->isDependentContext())
15718 ? RefExpr->IgnoreParens()
15720 Privates.push_back(PrivateRef);
15721 Inits.push_back(InitRef);
15727 Expr *StepExpr = Step;
15728 Expr *CalcStepExpr = nullptr;
15729 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15730 !Step->isInstantiationDependent() &&
15731 !Step->containsUnexpandedParameterPack()) {
15732 SourceLocation StepLoc = Step->getBeginLoc();
15733 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15734 if (Val.isInvalid())
15736 StepExpr = Val.get();
15738 // Build var to save the step value.
15740 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15741 ExprResult SaveRef =
15742 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15743 ExprResult CalcStep =
15744 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15745 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15747 // Warn about zero linear step (it would be probably better specified as
15748 // making corresponding variables 'const').
15749 llvm::APSInt Result;
15750 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
15751 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
15752 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
15753 << (Vars.size() > 1);
15754 if (!IsConstant && CalcStep.isUsable()) {
15755 // Calculate the step beforehand instead of doing this on each iteration.
15756 // (This is not used if the number of iterations may be kfold-ed).
15757 CalcStepExpr = CalcStep.get();
15761 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15762 ColonLoc, EndLoc, Vars, Privates, Inits,
15763 StepExpr, CalcStepExpr,
15764 buildPreInits(Context, ExprCaptures),
15765 buildPostUpdate(*this, ExprPostUpdates));
15768 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15769 Expr *NumIterations, Sema &SemaRef,
15770 Scope *S, DSAStackTy *Stack) {
15771 // Walk the vars and build update/final expressions for the CodeGen.
15772 SmallVector<Expr *, 8> Updates;
15773 SmallVector<Expr *, 8> Finals;
15774 SmallVector<Expr *, 8> UsedExprs;
15775 Expr *Step = Clause.getStep();
15776 Expr *CalcStep = Clause.getCalcStep();
15777 // OpenMP [2.14.3.7, linear clause]
15778 // If linear-step is not specified it is assumed to be 1.
15780 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15782 Step = cast<BinaryOperator>(CalcStep)->getLHS();
15783 bool HasErrors = false;
15784 auto CurInit = Clause.inits().begin();
15785 auto CurPrivate = Clause.privates().begin();
15786 OpenMPLinearClauseKind LinKind = Clause.getModifier();
15787 for (Expr *RefExpr : Clause.varlists()) {
15788 SourceLocation ELoc;
15789 SourceRange ERange;
15790 Expr *SimpleRefExpr = RefExpr;
15791 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15792 ValueDecl *D = Res.first;
15793 if (Res.second || !D) {
15794 Updates.push_back(nullptr);
15795 Finals.push_back(nullptr);
15799 auto &&Info = Stack->isLoopControlVariable(D);
15800 // OpenMP [2.15.11, distribute simd Construct]
15801 // A list item may not appear in a linear clause, unless it is the loop
15802 // iteration variable.
15803 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15804 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15806 diag::err_omp_linear_distribute_var_non_loop_iteration);
15807 Updates.push_back(nullptr);
15808 Finals.push_back(nullptr);
15812 Expr *InitExpr = *CurInit;
15814 // Build privatized reference to the current linear var.
15815 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15817 if (LinKind == OMPC_LINEAR_uval)
15818 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15821 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15822 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15823 /*RefersToCapture=*/true);
15825 // Build update: Var = InitExpr + IV * Step
15828 Update = buildCounterUpdate(
15829 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15830 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15832 Update = *CurPrivate;
15833 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15834 /*DiscardedValue*/ false);
15836 // Build final: Var = InitExpr + NumIterations * Step
15840 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
15841 InitExpr, NumIterations, Step, /*Subtract=*/false,
15842 /*IsNonRectangularLB=*/false);
15844 Final = *CurPrivate;
15845 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
15846 /*DiscardedValue*/ false);
15848 if (!Update.isUsable() || !Final.isUsable()) {
15849 Updates.push_back(nullptr);
15850 Finals.push_back(nullptr);
15851 UsedExprs.push_back(nullptr);
15854 Updates.push_back(Update.get());
15855 Finals.push_back(Final.get());
15857 UsedExprs.push_back(SimpleRefExpr);
15862 if (Expr *S = Clause.getStep())
15863 UsedExprs.push_back(S);
15864 // Fill the remaining part with the nullptr.
15865 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
15866 Clause.setUpdates(Updates);
15867 Clause.setFinals(Finals);
15868 Clause.setUsedExprs(UsedExprs);
15872 OMPClause *Sema::ActOnOpenMPAlignedClause(
15873 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
15874 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15875 SmallVector<Expr *, 8> Vars;
15876 for (Expr *RefExpr : VarList) {
15877 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15878 SourceLocation ELoc;
15879 SourceRange ERange;
15880 Expr *SimpleRefExpr = RefExpr;
15881 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15883 // It will be analyzed later.
15884 Vars.push_back(RefExpr);
15886 ValueDecl *D = Res.first;
15890 QualType QType = D->getType();
15891 auto *VD = dyn_cast<VarDecl>(D);
15893 // OpenMP [2.8.1, simd construct, Restrictions]
15894 // The type of list items appearing in the aligned clause must be
15895 // array, pointer, reference to array, or reference to pointer.
15896 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15897 const Type *Ty = QType.getTypePtrOrNull();
15898 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
15899 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
15900 << QType << getLangOpts().CPlusPlus << ERange;
15903 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15904 Diag(D->getLocation(),
15905 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15910 // OpenMP [2.8.1, simd construct, Restrictions]
15911 // A list-item cannot appear in more than one aligned clause.
15912 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
15913 Diag(ELoc, diag::err_omp_used_in_clause_twice)
15914 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
15915 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
15916 << getOpenMPClauseName(OMPC_aligned);
15920 DeclRefExpr *Ref = nullptr;
15921 if (!VD && isOpenMPCapturedDecl(D))
15922 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15923 Vars.push_back(DefaultFunctionArrayConversion(
15924 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
15928 // OpenMP [2.8.1, simd construct, Description]
15929 // The parameter of the aligned clause, alignment, must be a constant
15930 // positive integer expression.
15931 // If no optional parameter is specified, implementation-defined default
15932 // alignments for SIMD instructions on the target platforms are assumed.
15933 if (Alignment != nullptr) {
15934 ExprResult AlignResult =
15935 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
15936 if (AlignResult.isInvalid())
15938 Alignment = AlignResult.get();
15943 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
15944 EndLoc, Vars, Alignment);
15947 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
15948 SourceLocation StartLoc,
15949 SourceLocation LParenLoc,
15950 SourceLocation EndLoc) {
15951 SmallVector<Expr *, 8> Vars;
15952 SmallVector<Expr *, 8> SrcExprs;
15953 SmallVector<Expr *, 8> DstExprs;
15954 SmallVector<Expr *, 8> AssignmentOps;
15955 for (Expr *RefExpr : VarList) {
15956 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
15957 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
15958 // It will be analyzed later.
15959 Vars.push_back(RefExpr);
15960 SrcExprs.push_back(nullptr);
15961 DstExprs.push_back(nullptr);
15962 AssignmentOps.push_back(nullptr);
15966 SourceLocation ELoc = RefExpr->getExprLoc();
15967 // OpenMP [2.1, C/C++]
15968 // A list item is a variable name.
15969 // OpenMP [2.14.4.1, Restrictions, p.1]
15970 // A list item that appears in a copyin clause must be threadprivate.
15971 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
15972 if (!DE || !isa<VarDecl>(DE->getDecl())) {
15973 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
15974 << 0 << RefExpr->getSourceRange();
15978 Decl *D = DE->getDecl();
15979 auto *VD = cast<VarDecl>(D);
15981 QualType Type = VD->getType();
15982 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
15983 // It will be analyzed later.
15984 Vars.push_back(DE);
15985 SrcExprs.push_back(nullptr);
15986 DstExprs.push_back(nullptr);
15987 AssignmentOps.push_back(nullptr);
15991 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
15992 // A list item that appears in a copyin clause must be threadprivate.
15993 if (!DSAStack->isThreadPrivate(VD)) {
15994 Diag(ELoc, diag::err_omp_required_access)
15995 << getOpenMPClauseName(OMPC_copyin)
15996 << getOpenMPDirectiveName(OMPD_threadprivate);
16000 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16001 // A variable of class type (or array thereof) that appears in a
16002 // copyin clause requires an accessible, unambiguous copy assignment
16003 // operator for the class type.
16004 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16006 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16007 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16008 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16009 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16011 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16012 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16013 DeclRefExpr *PseudoDstExpr =
16014 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16015 // For arrays generate assignment operation for single element and replace
16016 // it by the original array element in CodeGen.
16017 ExprResult AssignmentOp =
16018 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16020 if (AssignmentOp.isInvalid())
16022 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16023 /*DiscardedValue*/ false);
16024 if (AssignmentOp.isInvalid())
16027 DSAStack->addDSA(VD, DE, OMPC_copyin);
16028 Vars.push_back(DE);
16029 SrcExprs.push_back(PseudoSrcExpr);
16030 DstExprs.push_back(PseudoDstExpr);
16031 AssignmentOps.push_back(AssignmentOp.get());
16037 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16038 SrcExprs, DstExprs, AssignmentOps);
16041 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16042 SourceLocation StartLoc,
16043 SourceLocation LParenLoc,
16044 SourceLocation EndLoc) {
16045 SmallVector<Expr *, 8> Vars;
16046 SmallVector<Expr *, 8> SrcExprs;
16047 SmallVector<Expr *, 8> DstExprs;
16048 SmallVector<Expr *, 8> AssignmentOps;
16049 for (Expr *RefExpr : VarList) {
16050 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16051 SourceLocation ELoc;
16052 SourceRange ERange;
16053 Expr *SimpleRefExpr = RefExpr;
16054 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16056 // It will be analyzed later.
16057 Vars.push_back(RefExpr);
16058 SrcExprs.push_back(nullptr);
16059 DstExprs.push_back(nullptr);
16060 AssignmentOps.push_back(nullptr);
16062 ValueDecl *D = Res.first;
16066 QualType Type = D->getType();
16067 auto *VD = dyn_cast<VarDecl>(D);
16069 // OpenMP [2.14.4.2, Restrictions, p.2]
16070 // A list item that appears in a copyprivate clause may not appear in a
16071 // private or firstprivate clause on the single construct.
16072 if (!VD || !DSAStack->isThreadPrivate(VD)) {
16073 DSAStackTy::DSAVarData DVar =
16074 DSAStack->getTopDSA(D, /*FromParent=*/false);
16075 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16077 Diag(ELoc, diag::err_omp_wrong_dsa)
16078 << getOpenMPClauseName(DVar.CKind)
16079 << getOpenMPClauseName(OMPC_copyprivate);
16080 reportOriginalDsa(*this, DSAStack, D, DVar);
16084 // OpenMP [2.11.4.2, Restrictions, p.1]
16085 // All list items that appear in a copyprivate clause must be either
16086 // threadprivate or private in the enclosing context.
16087 if (DVar.CKind == OMPC_unknown) {
16088 DVar = DSAStack->getImplicitDSA(D, false);
16089 if (DVar.CKind == OMPC_shared) {
16090 Diag(ELoc, diag::err_omp_required_access)
16091 << getOpenMPClauseName(OMPC_copyprivate)
16092 << "threadprivate or private in the enclosing context";
16093 reportOriginalDsa(*this, DSAStack, D, DVar);
16099 // Variably modified types are not supported.
16100 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16101 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16102 << getOpenMPClauseName(OMPC_copyprivate) << Type
16103 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16106 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16107 Diag(D->getLocation(),
16108 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16113 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16114 // A variable of class type (or array thereof) that appears in a
16115 // copyin clause requires an accessible, unambiguous copy assignment
16116 // operator for the class type.
16117 Type = Context.getBaseElementType(Type.getNonReferenceType())
16118 .getUnqualifiedType();
16120 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16121 D->hasAttrs() ? &D->getAttrs() : nullptr);
16122 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16124 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16125 D->hasAttrs() ? &D->getAttrs() : nullptr);
16126 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16127 ExprResult AssignmentOp = BuildBinOp(
16128 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16129 if (AssignmentOp.isInvalid())
16132 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16133 if (AssignmentOp.isInvalid())
16136 // No need to mark vars as copyprivate, they are already threadprivate or
16137 // implicitly private.
16138 assert(VD || isOpenMPCapturedDecl(D));
16140 VD ? RefExpr->IgnoreParens()
16141 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16142 SrcExprs.push_back(PseudoSrcExpr);
16143 DstExprs.push_back(PseudoDstExpr);
16144 AssignmentOps.push_back(AssignmentOp.get());
16150 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16151 Vars, SrcExprs, DstExprs, AssignmentOps);
16154 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16155 SourceLocation StartLoc,
16156 SourceLocation LParenLoc,
16157 SourceLocation EndLoc) {
16158 if (VarList.empty())
16161 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16164 /// Tries to find omp_depend_t. type.
16165 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16166 bool Diagnose = true) {
16167 QualType OMPDependT = Stack->getOMPDependT();
16168 if (!OMPDependT.isNull())
16170 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16171 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16172 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16174 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16177 Stack->setOMPDependT(PT.get());
16181 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16182 SourceLocation LParenLoc,
16183 SourceLocation EndLoc) {
16187 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16189 // OpenMP 5.0, 2.17.10.1 depobj Construct
16190 // depobj is an lvalue expression of type omp_depend_t.
16191 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16192 !Depobj->isInstantiationDependent() &&
16193 !Depobj->containsUnexpandedParameterPack() &&
16194 (OMPDependTFound &&
16195 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16196 /*CompareUnqualified=*/true))) {
16197 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16198 << 0 << Depobj->getType() << Depobj->getSourceRange();
16201 if (!Depobj->isLValue()) {
16202 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16203 << 1 << Depobj->getSourceRange();
16206 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16210 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16211 SourceLocation DepLoc, SourceLocation ColonLoc,
16212 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16213 SourceLocation LParenLoc, SourceLocation EndLoc) {
16214 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16215 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16216 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16217 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16220 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16221 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16222 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16223 DepKind == OMPC_DEPEND_sink ||
16224 ((LangOpts.OpenMP < 50 ||
16225 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16226 DepKind == OMPC_DEPEND_depobj))) {
16227 SmallVector<unsigned, 3> Except;
16228 Except.push_back(OMPC_DEPEND_source);
16229 Except.push_back(OMPC_DEPEND_sink);
16230 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16231 Except.push_back(OMPC_DEPEND_depobj);
16232 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16233 ? "depend modifier(iterator) or "
16235 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16236 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16237 /*Last=*/OMPC_DEPEND_unknown,
16239 << getOpenMPClauseName(OMPC_depend);
16243 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16244 Diag(DepModifier->getExprLoc(),
16245 diag::err_omp_depend_sink_source_with_modifier);
16249 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16250 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16252 SmallVector<Expr *, 8> Vars;
16253 DSAStackTy::OperatorOffsetTy OpsOffs;
16254 llvm::APSInt DepCounter(/*BitWidth=*/32);
16255 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16256 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16257 if (const Expr *OrderedCountExpr =
16258 DSAStack->getParentOrderedRegionParam().first) {
16259 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16260 TotalDepCount.setIsUnsigned(/*Val=*/true);
16263 for (Expr *RefExpr : VarList) {
16264 assert(RefExpr && "NULL expr in OpenMP shared clause.");
16265 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16266 // It will be analyzed later.
16267 Vars.push_back(RefExpr);
16271 SourceLocation ELoc = RefExpr->getExprLoc();
16272 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16273 if (DepKind == OMPC_DEPEND_sink) {
16274 if (DSAStack->getParentOrderedRegionParam().first &&
16275 DepCounter >= TotalDepCount) {
16276 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16280 // OpenMP [2.13.9, Summary]
16281 // depend(dependence-type : vec), where dependence-type is:
16282 // 'sink' and where vec is the iteration vector, which has the form:
16283 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16284 // where n is the value specified by the ordered clause in the loop
16285 // directive, xi denotes the loop iteration variable of the i-th nested
16286 // loop associated with the loop directive, and di is a constant
16287 // non-negative integer.
16288 if (CurContext->isDependentContext()) {
16289 // It will be analyzed later.
16290 Vars.push_back(RefExpr);
16293 SimpleExpr = SimpleExpr->IgnoreImplicit();
16294 OverloadedOperatorKind OOK = OO_None;
16295 SourceLocation OOLoc;
16296 Expr *LHS = SimpleExpr;
16297 Expr *RHS = nullptr;
16298 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16299 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16300 OOLoc = BO->getOperatorLoc();
16301 LHS = BO->getLHS()->IgnoreParenImpCasts();
16302 RHS = BO->getRHS()->IgnoreParenImpCasts();
16303 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16304 OOK = OCE->getOperator();
16305 OOLoc = OCE->getOperatorLoc();
16306 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16307 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16308 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16309 OOK = MCE->getMethodDecl()
16312 .getCXXOverloadedOperator();
16313 OOLoc = MCE->getCallee()->getExprLoc();
16314 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16315 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16317 SourceLocation ELoc;
16318 SourceRange ERange;
16319 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16321 // It will be analyzed later.
16322 Vars.push_back(RefExpr);
16324 ValueDecl *D = Res.first;
16328 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16329 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16333 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16334 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16335 if (RHSRes.isInvalid())
16338 if (!CurContext->isDependentContext() &&
16339 DSAStack->getParentOrderedRegionParam().first &&
16340 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16341 const ValueDecl *VD =
16342 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16344 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16347 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16350 OpsOffs.emplace_back(RHS, OOK);
16352 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16353 if (OMPDependTFound)
16354 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16355 DepKind == OMPC_DEPEND_depobj);
16356 if (DepKind == OMPC_DEPEND_depobj) {
16357 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16358 // List items used in depend clauses with the depobj dependence type
16359 // must be expressions of the omp_depend_t type.
16360 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16361 !RefExpr->isInstantiationDependent() &&
16362 !RefExpr->containsUnexpandedParameterPack() &&
16363 (OMPDependTFound &&
16364 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16365 RefExpr->getType()))) {
16366 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16367 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16370 if (!RefExpr->isLValue()) {
16371 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16372 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16376 // OpenMP 5.0 [2.17.11, Restrictions]
16377 // List items used in depend clauses cannot be zero-length array
16379 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16380 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16382 QualType BaseType =
16383 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16384 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16385 ExprTy = ATy->getElementType();
16387 ExprTy = BaseType->getPointeeType();
16388 ExprTy = ExprTy.getNonReferenceType();
16389 const Expr *Length = OASE->getLength();
16390 Expr::EvalResult Result;
16391 if (Length && !Length->isValueDependent() &&
16392 Length->EvaluateAsInt(Result, Context) &&
16393 Result.Val.getInt().isNullValue()) {
16395 diag::err_omp_depend_zero_length_array_section_not_allowed)
16396 << SimpleExpr->getSourceRange();
16401 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16402 // List items used in depend clauses with the in, out, inout or
16403 // mutexinoutset dependence types cannot be expressions of the
16404 // omp_depend_t type.
16405 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16406 !RefExpr->isInstantiationDependent() &&
16407 !RefExpr->containsUnexpandedParameterPack() &&
16408 (OMPDependTFound &&
16409 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16410 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16411 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16412 << RefExpr->getSourceRange();
16416 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16417 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16418 (ASE && !ASE->getBase()->isTypeDependent() &&
16421 .getNonReferenceType()
16422 ->isPointerType() &&
16423 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16424 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16425 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16426 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16432 Sema::TentativeAnalysisScope Trap(*this);
16433 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16434 RefExpr->IgnoreParenImpCasts());
16436 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16437 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16438 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16439 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16440 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16445 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16448 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16449 TotalDepCount > VarList.size() &&
16450 DSAStack->getParentOrderedRegionParam().first &&
16451 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16452 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16453 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16455 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16459 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16460 DepModifier, DepKind, DepLoc, ColonLoc,
16461 Vars, TotalDepCount.getZExtValue());
16462 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16463 DSAStack->isParentOrderedRegion())
16464 DSAStack->addDoacrossDependClause(C, OpsOffs);
16468 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16469 Expr *Device, SourceLocation StartLoc,
16470 SourceLocation LParenLoc,
16471 SourceLocation ModifierLoc,
16472 SourceLocation EndLoc) {
16473 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16474 "Unexpected device modifier in OpenMP < 50.");
16476 bool ErrorFound = false;
16477 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16478 std::string Values =
16479 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16480 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16481 << Values << getOpenMPClauseName(OMPC_device);
16485 Expr *ValExpr = Device;
16486 Stmt *HelperValStmt = nullptr;
16488 // OpenMP [2.9.1, Restrictions]
16489 // The device expression must evaluate to a non-negative integer value.
16490 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16491 /*StrictlyPositive=*/false) ||
16496 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16497 OpenMPDirectiveKind CaptureRegion =
16498 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16499 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16500 ValExpr = MakeFullExpr(ValExpr).get();
16501 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16502 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16503 HelperValStmt = buildPreInits(Context, Captures);
16506 return new (Context)
16507 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16508 LParenLoc, ModifierLoc, EndLoc);
16511 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16512 DSAStackTy *Stack, QualType QTy,
16513 bool FullCheck = true) {
16515 if (QTy->isIncompleteType(&ND)) {
16516 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16519 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16520 !QTy.isTriviallyCopyableType(SemaRef.Context))
16521 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16525 /// Return true if it can be proven that the provided array expression
16526 /// (array section or array subscript) does NOT specify the whole size of the
16527 /// array whose base type is \a BaseQTy.
16528 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16530 QualType BaseQTy) {
16531 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16533 // If this is an array subscript, it refers to the whole size if the size of
16534 // the dimension is constant and equals 1. Also, an array section assumes the
16535 // format of an array subscript if no colon is used.
16536 if (isa<ArraySubscriptExpr>(E) ||
16537 (OASE && OASE->getColonLocFirst().isInvalid())) {
16538 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16539 return ATy->getSize().getSExtValue() != 1;
16540 // Size can't be evaluated statically.
16544 assert(OASE && "Expecting array section if not an array subscript.");
16545 const Expr *LowerBound = OASE->getLowerBound();
16546 const Expr *Length = OASE->getLength();
16548 // If there is a lower bound that does not evaluates to zero, we are not
16549 // covering the whole dimension.
16551 Expr::EvalResult Result;
16552 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16553 return false; // Can't get the integer value as a constant.
16555 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16556 if (ConstLowerBound.getSExtValue())
16560 // If we don't have a length we covering the whole dimension.
16564 // If the base is a pointer, we don't have a way to get the size of the
16566 if (BaseQTy->isPointerType())
16569 // We can only check if the length is the same as the size of the dimension
16570 // if we have a constant array.
16571 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16575 Expr::EvalResult Result;
16576 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16577 return false; // Can't get the integer value as a constant.
16579 llvm::APSInt ConstLength = Result.Val.getInt();
16580 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16583 // Return true if it can be proven that the provided array expression (array
16584 // section or array subscript) does NOT specify a single element of the array
16585 // whose base type is \a BaseQTy.
16586 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16588 QualType BaseQTy) {
16589 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16591 // An array subscript always refer to a single element. Also, an array section
16592 // assumes the format of an array subscript if no colon is used.
16593 if (isa<ArraySubscriptExpr>(E) ||
16594 (OASE && OASE->getColonLocFirst().isInvalid()))
16597 assert(OASE && "Expecting array section if not an array subscript.");
16598 const Expr *Length = OASE->getLength();
16600 // If we don't have a length we have to check if the array has unitary size
16601 // for this dimension. Also, we should always expect a length if the base type
16604 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16605 return ATy->getSize().getSExtValue() != 1;
16606 // We cannot assume anything.
16610 // Check if the length evaluates to 1.
16611 Expr::EvalResult Result;
16612 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16613 return false; // Can't get the integer value as a constant.
16615 llvm::APSInt ConstLength = Result.Val.getInt();
16616 return ConstLength.getSExtValue() != 1;
16619 // The base of elements of list in a map clause have to be either:
16620 // - a reference to variable or field.
16621 // - a member expression.
16622 // - an array expression.
16624 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16625 // reference to 'r'.
16632 // #pragma omp target map (S.Arr[:12]);
16636 // We want to retrieve the member expression 'this->S';
16638 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16639 // If a list item is an array section, it must specify contiguous storage.
16641 // For this restriction it is sufficient that we make sure only references
16642 // to variables or fields and array expressions, and that no array sections
16643 // exist except in the rightmost expression (unless they cover the whole
16644 // dimension of the array). E.g. these would be invalid:
16646 // r.ArrS[3:5].Arr[6:7]
16650 // but these would be valid:
16651 // r.ArrS[3].Arr[6:7]
16655 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16657 OpenMPClauseKind CKind = OMPC_unknown;
16658 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16659 bool NoDiagnose = false;
16660 const Expr *RelevantExpr = nullptr;
16661 bool AllowUnitySizeArraySection = true;
16662 bool AllowWholeSizeArraySection = true;
16663 SourceLocation ELoc;
16664 SourceRange ERange;
16666 void emitErrorMsg() {
16667 // If nothing else worked, this is not a valid map clause expression.
16668 if (SemaRef.getLangOpts().OpenMP < 50) {
16670 diag::err_omp_expected_named_var_member_or_array_expression)
16673 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16674 << getOpenMPClauseName(CKind) << ERange;
16679 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16680 if (!isa<VarDecl>(DRE->getDecl())) {
16684 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16685 RelevantExpr = DRE;
16686 // Record the component.
16687 Components.emplace_back(DRE, DRE->getDecl());
16691 bool VisitMemberExpr(MemberExpr *ME) {
16693 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16695 if (isa<CXXThisExpr>(BaseE)) {
16696 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16697 // We found a base expression: this->Val.
16703 if (!isa<FieldDecl>(ME->getMemberDecl())) {
16705 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16706 << ME->getSourceRange();
16714 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16717 // A bit-field cannot appear in a map clause.
16719 if (FD->isBitField()) {
16721 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16722 << ME->getSourceRange() << getOpenMPClauseName(CKind);
16730 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16731 // If the type of a list item is a reference to a type T then the type
16732 // will be considered to be T for all purposes of this clause.
16733 QualType CurType = BaseE->getType().getNonReferenceType();
16735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16736 // A list item cannot be a variable that is a member of a structure with
16739 if (CurType->isUnionType()) {
16741 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16742 << ME->getSourceRange();
16745 return RelevantExpr || Visit(E);
16748 // If we got a member expression, we should not expect any array section
16751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16752 // If a list item is an element of a structure, only the rightmost symbol
16753 // of the variable reference can be an array section.
16755 AllowUnitySizeArraySection = false;
16756 AllowWholeSizeArraySection = false;
16758 // Record the component.
16759 Components.emplace_back(ME, FD);
16760 return RelevantExpr || Visit(E);
16763 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16764 Expr *E = AE->getBase()->IgnoreParenImpCasts();
16766 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16768 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16769 << 0 << AE->getSourceRange();
16772 return RelevantExpr || Visit(E);
16775 // If we got an array subscript that express the whole dimension we
16776 // can have any array expressions before. If it only expressing part of
16777 // the dimension, we can only have unitary-size array expressions.
16778 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16780 AllowWholeSizeArraySection = false;
16782 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16783 Expr::EvalResult Result;
16784 if (!AE->getIdx()->isValueDependent() &&
16785 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16786 !Result.Val.getInt().isNullValue()) {
16787 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16788 diag::err_omp_invalid_map_this_expr);
16789 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16790 diag::note_omp_invalid_subscript_on_this_ptr_map);
16792 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16796 // Record the component - we don't have any declaration associated.
16797 Components.emplace_back(AE, nullptr);
16799 return RelevantExpr || Visit(E);
16802 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16803 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
16804 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16806 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16808 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16809 // If the type of a list item is a reference to a type T then the type
16810 // will be considered to be T for all purposes of this clause.
16811 if (CurType->isReferenceType())
16812 CurType = CurType->getPointeeType();
16814 bool IsPointer = CurType->isAnyPointerType();
16816 if (!IsPointer && !CurType->isArrayType()) {
16817 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16818 << 0 << OASE->getSourceRange();
16823 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16825 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16827 if (AllowWholeSizeArraySection) {
16828 // Any array section is currently allowed. Allowing a whole size array
16829 // section implies allowing a unity array section as well.
16831 // If this array section refers to the whole dimension we can still
16832 // accept other array sections before this one, except if the base is a
16833 // pointer. Otherwise, only unitary sections are accepted.
16834 if (NotWhole || IsPointer)
16835 AllowWholeSizeArraySection = false;
16836 } else if (AllowUnitySizeArraySection && NotUnity) {
16837 // A unity or whole array section is not allowed and that is not
16838 // compatible with the properties of the current array section.
16840 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
16841 << OASE->getSourceRange();
16845 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
16846 Expr::EvalResult ResultR;
16847 Expr::EvalResult ResultL;
16848 if (!OASE->getLength()->isValueDependent() &&
16849 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
16850 !ResultR.Val.getInt().isOneValue()) {
16851 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16852 diag::err_omp_invalid_map_this_expr);
16853 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16854 diag::note_omp_invalid_length_on_this_ptr_mapping);
16856 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
16857 OASE->getLowerBound()->EvaluateAsInt(ResultL,
16858 SemaRef.getASTContext()) &&
16859 !ResultL.Val.getInt().isNullValue()) {
16860 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16861 diag::err_omp_invalid_map_this_expr);
16862 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16863 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
16865 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16869 // Record the component - we don't have any declaration associated.
16870 Components.emplace_back(OASE, nullptr);
16871 return RelevantExpr || Visit(E);
16873 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
16874 Expr *Base = E->getBase();
16876 // Record the component - we don't have any declaration associated.
16877 Components.emplace_back(E, nullptr);
16879 return Visit(Base->IgnoreParenImpCasts());
16882 bool VisitUnaryOperator(UnaryOperator *UO) {
16883 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
16884 UO->getOpcode() != UO_Deref) {
16888 if (!RelevantExpr) {
16889 // Record the component if haven't found base decl.
16890 Components.emplace_back(UO, nullptr);
16892 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
16894 bool VisitBinaryOperator(BinaryOperator *BO) {
16895 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
16900 // Pointer arithmetic is the only thing we expect to happen here so after we
16901 // make sure the binary operator is a pointer type, the we only thing need
16902 // to to is to visit the subtree that has the same type as root (so that we
16903 // know the other subtree is just an offset)
16904 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
16905 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
16906 Components.emplace_back(BO, nullptr);
16907 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
16908 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
16909 "Either LHS or RHS have base decl inside");
16910 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
16911 return RelevantExpr || Visit(LE);
16912 return RelevantExpr || Visit(RE);
16914 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
16915 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16916 RelevantExpr = CTE;
16917 Components.emplace_back(CTE, nullptr);
16920 bool VisitStmt(Stmt *) {
16924 const Expr *getFoundBase() const {
16925 return RelevantExpr;
16927 explicit MapBaseChecker(
16928 Sema &SemaRef, OpenMPClauseKind CKind,
16929 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
16930 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
16931 : SemaRef(SemaRef), CKind(CKind), Components(Components),
16932 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
16936 /// Return the expression of the base of the mappable expression or null if it
16937 /// cannot be determined and do all the necessary checks to see if the expression
16938 /// is valid as a standalone mappable expression. In the process, record all the
16939 /// components of the expression.
16940 static const Expr *checkMapClauseExpressionBase(
16941 Sema &SemaRef, Expr *E,
16942 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
16943 OpenMPClauseKind CKind, bool NoDiagnose) {
16944 SourceLocation ELoc = E->getExprLoc();
16945 SourceRange ERange = E->getSourceRange();
16946 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
16948 if (Checker.Visit(E->IgnoreParens()))
16949 return Checker.getFoundBase();
16953 // Return true if expression E associated with value VD has conflicts with other
16954 // map information.
16955 static bool checkMapConflicts(
16956 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
16957 bool CurrentRegionOnly,
16958 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
16959 OpenMPClauseKind CKind) {
16961 SourceLocation ELoc = E->getExprLoc();
16962 SourceRange ERange = E->getSourceRange();
16964 // In order to easily check the conflicts we need to match each component of
16965 // the expression under test with the components of the expressions that are
16966 // already in the stack.
16968 assert(!CurComponents.empty() && "Map clause expression with no components!");
16969 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
16970 "Map clause expression with unexpected base!");
16972 // Variables to help detecting enclosing problems in data environment nests.
16973 bool IsEnclosedByDataEnvironmentExpr = false;
16974 const Expr *EnclosingExpr = nullptr;
16976 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
16977 VD, CurrentRegionOnly,
16978 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
16979 ERange, CKind, &EnclosingExpr,
16980 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
16982 OpenMPClauseKind) {
16983 assert(!StackComponents.empty() &&
16984 "Map clause expression with no components!");
16985 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
16986 "Map clause expression with unexpected base!");
16989 // The whole expression in the stack.
16990 const Expr *RE = StackComponents.front().getAssociatedExpression();
16992 // Expressions must start from the same base. Here we detect at which
16993 // point both expressions diverge from each other and see if we can
16994 // detect if the memory referred to both expressions is contiguous and
16996 auto CI = CurComponents.rbegin();
16997 auto CE = CurComponents.rend();
16998 auto SI = StackComponents.rbegin();
16999 auto SE = StackComponents.rend();
17000 for (; CI != CE && SI != SE; ++CI, ++SI) {
17002 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
17003 // At most one list item can be an array item derived from a given
17004 // variable in map clauses of the same construct.
17005 if (CurrentRegionOnly &&
17006 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17007 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17008 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17009 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17010 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17011 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17012 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17013 diag::err_omp_multiple_array_items_in_map_clause)
17014 << CI->getAssociatedExpression()->getSourceRange();
17015 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17016 diag::note_used_here)
17017 << SI->getAssociatedExpression()->getSourceRange();
17021 // Do both expressions have the same kind?
17022 if (CI->getAssociatedExpression()->getStmtClass() !=
17023 SI->getAssociatedExpression()->getStmtClass())
17026 // Are we dealing with different variables/fields?
17027 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17030 // Check if the extra components of the expressions in the enclosing
17031 // data environment are redundant for the current base declaration.
17032 // If they are, the maps completely overlap, which is legal.
17033 for (; SI != SE; ++SI) {
17035 if (const auto *ASE =
17036 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17037 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17038 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17039 SI->getAssociatedExpression())) {
17040 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17042 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17043 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17044 SI->getAssociatedExpression())) {
17045 Type = OASE->getBase()->getType()->getPointeeType();
17047 if (Type.isNull() || Type->isAnyPointerType() ||
17048 checkArrayExpressionDoesNotReferToWholeSize(
17049 SemaRef, SI->getAssociatedExpression(), Type))
17053 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17054 // List items of map clauses in the same construct must not share
17055 // original storage.
17057 // If the expressions are exactly the same or one is a subset of the
17058 // other, it means they are sharing storage.
17059 if (CI == CE && SI == SE) {
17060 if (CurrentRegionOnly) {
17061 if (CKind == OMPC_map) {
17062 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17064 assert(CKind == OMPC_to || CKind == OMPC_from);
17065 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17068 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17069 << RE->getSourceRange();
17072 // If we find the same expression in the enclosing data environment,
17074 IsEnclosedByDataEnvironmentExpr = true;
17078 QualType DerivedType =
17079 std::prev(CI)->getAssociatedDeclaration()->getType();
17080 SourceLocation DerivedLoc =
17081 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17083 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17084 // If the type of a list item is a reference to a type T then the type
17085 // will be considered to be T for all purposes of this clause.
17086 DerivedType = DerivedType.getNonReferenceType();
17088 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17089 // A variable for which the type is pointer and an array section
17090 // derived from that variable must not appear as list items of map
17091 // clauses of the same construct.
17093 // Also, cover one of the cases in:
17094 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17095 // If any part of the original storage of a list item has corresponding
17096 // storage in the device data environment, all of the original storage
17097 // must have corresponding storage in the device data environment.
17099 if (DerivedType->isAnyPointerType()) {
17100 if (CI == CE || SI == SE) {
17103 diag::err_omp_pointer_mapped_along_with_derived_section)
17105 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17106 << RE->getSourceRange();
17109 if (CI->getAssociatedExpression()->getStmtClass() !=
17110 SI->getAssociatedExpression()->getStmtClass() ||
17111 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17112 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17113 assert(CI != CE && SI != SE);
17114 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17116 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17117 << RE->getSourceRange();
17122 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17123 // List items of map clauses in the same construct must not share
17124 // original storage.
17126 // An expression is a subset of the other.
17127 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17128 if (CKind == OMPC_map) {
17129 if (CI != CE || SI != SE) {
17130 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17133 CI != CE ? CurComponents.begin() : StackComponents.begin();
17134 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17136 while (It != End && !It->getAssociatedDeclaration())
17137 std::advance(It, 1);
17138 assert(It != End &&
17139 "Expected at least one component with the declaration.");
17140 if (It != Begin && It->getAssociatedDeclaration()
17142 .getCanonicalType()
17143 ->isAnyPointerType()) {
17144 IsEnclosedByDataEnvironmentExpr = false;
17145 EnclosingExpr = nullptr;
17149 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17151 assert(CKind == OMPC_to || CKind == OMPC_from);
17152 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17155 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17156 << RE->getSourceRange();
17160 // The current expression uses the same base as other expression in the
17161 // data environment but does not contain it completely.
17162 if (!CurrentRegionOnly && SI != SE)
17163 EnclosingExpr = RE;
17165 // The current expression is a subset of the expression in the data
17167 IsEnclosedByDataEnvironmentExpr |=
17168 (!CurrentRegionOnly && CI != CE && SI == SE);
17173 if (CurrentRegionOnly)
17176 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17177 // If any part of the original storage of a list item has corresponding
17178 // storage in the device data environment, all of the original storage must
17179 // have corresponding storage in the device data environment.
17180 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17181 // If a list item is an element of a structure, and a different element of
17182 // the structure has a corresponding list item in the device data environment
17183 // prior to a task encountering the construct associated with the map clause,
17184 // then the list item must also have a corresponding list item in the device
17185 // data environment prior to the task encountering the construct.
17187 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17189 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17191 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17192 << EnclosingExpr->getSourceRange();
17199 // Look up the user-defined mapper given the mapper name and mapped type, and
17200 // build a reference to it.
17201 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17202 CXXScopeSpec &MapperIdScopeSpec,
17203 const DeclarationNameInfo &MapperId,
17205 Expr *UnresolvedMapper) {
17206 if (MapperIdScopeSpec.isInvalid())
17207 return ExprError();
17208 // Get the actual type for the array type.
17209 if (Type->isArrayType()) {
17210 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17211 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17213 // Find all user-defined mappers with the given MapperId.
17214 SmallVector<UnresolvedSet<8>, 4> Lookups;
17215 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17216 Lookup.suppressDiagnostics();
17218 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17219 NamedDecl *D = Lookup.getRepresentativeDecl();
17220 while (S && !S->isDeclScope(D))
17221 S = S->getParent();
17223 S = S->getParent();
17224 Lookups.emplace_back();
17225 Lookups.back().append(Lookup.begin(), Lookup.end());
17228 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17229 // Extract the user-defined mappers with the given MapperId.
17230 Lookups.push_back(UnresolvedSet<8>());
17231 for (NamedDecl *D : ULE->decls()) {
17232 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17233 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17234 Lookups.back().addDecl(DMD);
17237 // Defer the lookup for dependent types. The results will be passed through
17238 // UnresolvedMapper on instantiation.
17239 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17240 Type->isInstantiationDependentType() ||
17241 Type->containsUnexpandedParameterPack() ||
17242 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17243 return !D->isInvalidDecl() &&
17244 (D->getType()->isDependentType() ||
17245 D->getType()->isInstantiationDependentType() ||
17246 D->getType()->containsUnexpandedParameterPack());
17248 UnresolvedSet<8> URS;
17249 for (const UnresolvedSet<8> &Set : Lookups) {
17252 URS.append(Set.begin(), Set.end());
17254 return UnresolvedLookupExpr::Create(
17255 SemaRef.Context, /*NamingClass=*/nullptr,
17256 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17257 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17259 SourceLocation Loc = MapperId.getLoc();
17260 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17261 // The type must be of struct, union or class type in C and C++
17262 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17263 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17264 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17265 return ExprError();
17267 // Perform argument dependent lookup.
17268 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17269 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17270 // Return the first user-defined mapper with the desired type.
17271 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17272 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17273 if (!D->isInvalidDecl() &&
17274 SemaRef.Context.hasSameType(D->getType(), Type))
17278 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17279 // Find the first user-defined mapper with a type derived from the desired
17281 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17282 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17283 if (!D->isInvalidDecl() &&
17284 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17285 !Type.isMoreQualifiedThan(D->getType()))
17289 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17290 /*DetectVirtual=*/false);
17291 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17292 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17293 VD->getType().getUnqualifiedType()))) {
17294 if (SemaRef.CheckBaseClassAccess(
17295 Loc, VD->getType(), Type, Paths.front(),
17296 /*DiagID=*/0) != Sema::AR_inaccessible) {
17297 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17302 // Report error if a mapper is specified, but cannot be found.
17303 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17304 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17305 << Type << MapperId.getName();
17306 return ExprError();
17308 return ExprEmpty();
17312 // Utility struct that gathers all the related lists associated with a mappable
17314 struct MappableVarListInfo {
17315 // The list of expressions.
17316 ArrayRef<Expr *> VarList;
17317 // The list of processed expressions.
17318 SmallVector<Expr *, 16> ProcessedVarList;
17319 // The mappble components for each expression.
17320 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17321 // The base declaration of the variable.
17322 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17323 // The reference to the user-defined mapper associated with every expression.
17324 SmallVector<Expr *, 16> UDMapperList;
17326 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17327 // We have a list of components and base declarations for each entry in the
17329 VarComponents.reserve(VarList.size());
17330 VarBaseDeclarations.reserve(VarList.size());
17335 // Check the validity of the provided variable list for the provided clause kind
17336 // \a CKind. In the check process the valid expressions, mappable expression
17337 // components, variables, and user-defined mappers are extracted and used to
17338 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17339 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17340 // and \a MapperId are expected to be valid if the clause kind is 'map'.
17341 static void checkMappableExpressionList(
17342 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17343 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17344 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17345 ArrayRef<Expr *> UnresolvedMappers,
17346 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17347 bool IsMapTypeImplicit = false) {
17348 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17349 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17350 "Unexpected clause kind with mappable expressions!");
17352 // If the identifier of user-defined mapper is not specified, it is "default".
17353 // We do not change the actual name in this clause to distinguish whether a
17354 // mapper is specified explicitly, i.e., it is not explicitly specified when
17355 // MapperId.getName() is empty.
17356 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17357 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17358 MapperId.setName(DeclNames.getIdentifier(
17359 &SemaRef.getASTContext().Idents.get("default")));
17362 // Iterators to find the current unresolved mapper expression.
17363 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17364 bool UpdateUMIt = false;
17365 Expr *UnresolvedMapper = nullptr;
17367 // Keep track of the mappable components and base declarations in this clause.
17368 // Each entry in the list is going to have a list of components associated. We
17369 // record each set of the components so that we can build the clause later on.
17370 // In the end we should have the same amount of declarations and component
17373 for (Expr *RE : MVLI.VarList) {
17374 assert(RE && "Null expr in omp to/from/map clause");
17375 SourceLocation ELoc = RE->getExprLoc();
17377 // Find the current unresolved mapper expression.
17378 if (UpdateUMIt && UMIt != UMEnd) {
17382 "Expect the size of UnresolvedMappers to match with that of VarList");
17386 UnresolvedMapper = *UMIt;
17388 const Expr *VE = RE->IgnoreParenLValueCasts();
17390 if (VE->isValueDependent() || VE->isTypeDependent() ||
17391 VE->isInstantiationDependent() ||
17392 VE->containsUnexpandedParameterPack()) {
17393 // Try to find the associated user-defined mapper.
17394 ExprResult ER = buildUserDefinedMapperRef(
17395 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17396 VE->getType().getCanonicalType(), UnresolvedMapper);
17397 if (ER.isInvalid())
17399 MVLI.UDMapperList.push_back(ER.get());
17400 // We can only analyze this information once the missing information is
17402 MVLI.ProcessedVarList.push_back(RE);
17406 Expr *SimpleExpr = RE->IgnoreParenCasts();
17408 if (!RE->isLValue()) {
17409 if (SemaRef.getLangOpts().OpenMP < 50) {
17411 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17412 << RE->getSourceRange();
17414 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17415 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17420 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17421 ValueDecl *CurDeclaration = nullptr;
17423 // Obtain the array or member expression bases if required. Also, fill the
17424 // components array with all the components identified in the process.
17425 const Expr *BE = checkMapClauseExpressionBase(
17426 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
17430 assert(!CurComponents.empty() &&
17431 "Invalid mappable expression information.");
17433 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17434 // Add store "this" pointer to class in DSAStackTy for future checking
17435 DSAS->addMappedClassesQualTypes(TE->getType());
17436 // Try to find the associated user-defined mapper.
17437 ExprResult ER = buildUserDefinedMapperRef(
17438 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17439 VE->getType().getCanonicalType(), UnresolvedMapper);
17440 if (ER.isInvalid())
17442 MVLI.UDMapperList.push_back(ER.get());
17443 // Skip restriction checking for variable or field declarations
17444 MVLI.ProcessedVarList.push_back(RE);
17445 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17446 MVLI.VarComponents.back().append(CurComponents.begin(),
17447 CurComponents.end());
17448 MVLI.VarBaseDeclarations.push_back(nullptr);
17452 // For the following checks, we rely on the base declaration which is
17453 // expected to be associated with the last component. The declaration is
17454 // expected to be a variable or a field (if 'this' is being mapped).
17455 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17456 assert(CurDeclaration && "Null decl on map clause.");
17458 CurDeclaration->isCanonicalDecl() &&
17459 "Expecting components to have associated only canonical declarations.");
17461 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17462 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17464 assert((VD || FD) && "Only variables or fields are expected here!");
17467 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17468 // threadprivate variables cannot appear in a map clause.
17469 // OpenMP 4.5 [2.10.5, target update Construct]
17470 // threadprivate variables cannot appear in a from clause.
17471 if (VD && DSAS->isThreadPrivate(VD)) {
17472 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17473 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17474 << getOpenMPClauseName(CKind);
17475 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17479 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17480 // A list item cannot appear in both a map clause and a data-sharing
17481 // attribute clause on the same construct.
17483 // Check conflicts with other map clause expressions. We check the conflicts
17484 // with the current construct separately from the enclosing data
17485 // environment, because the restrictions are different. We only have to
17486 // check conflicts across regions for the map clauses.
17487 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17488 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17490 if (CKind == OMPC_map &&
17491 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17492 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17495 // OpenMP 4.5 [2.10.5, target update Construct]
17496 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17497 // If the type of a list item is a reference to a type T then the type will
17498 // be considered to be T for all purposes of this clause.
17499 auto I = llvm::find_if(
17501 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17502 return MC.getAssociatedDeclaration();
17504 assert(I != CurComponents.end() && "Null decl on map clause.");
17506 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17507 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17508 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17510 Type = ASE->getType().getNonReferenceType();
17512 QualType BaseType =
17513 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17514 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17515 Type = ATy->getElementType();
17517 Type = BaseType->getPointeeType();
17518 Type = Type.getNonReferenceType();
17519 } else if (OAShE) {
17520 Type = OAShE->getBase()->getType()->getPointeeType();
17522 Type = VE->getType();
17525 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17526 // A list item in a to or from clause must have a mappable type.
17527 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17528 // A list item must have a mappable type.
17529 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17533 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17535 if (CKind == OMPC_map) {
17536 // target enter data
17537 // OpenMP [2.10.2, Restrictions, p. 99]
17538 // A map-type must be specified in all map clauses and must be either
17540 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17541 if (DKind == OMPD_target_enter_data &&
17542 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17543 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17544 << (IsMapTypeImplicit ? 1 : 0)
17545 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17546 << getOpenMPDirectiveName(DKind);
17550 // target exit_data
17551 // OpenMP [2.10.3, Restrictions, p. 102]
17552 // A map-type must be specified in all map clauses and must be either
17553 // from, release, or delete.
17554 if (DKind == OMPD_target_exit_data &&
17555 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17556 MapType == OMPC_MAP_delete)) {
17557 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17558 << (IsMapTypeImplicit ? 1 : 0)
17559 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17560 << getOpenMPDirectiveName(DKind);
17564 // target, target data
17565 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17566 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17567 // A map-type in a map clause must be to, from, tofrom or alloc
17568 if ((DKind == OMPD_target_data ||
17569 isOpenMPTargetExecutionDirective(DKind)) &&
17570 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17571 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17572 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17573 << (IsMapTypeImplicit ? 1 : 0)
17574 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17575 << getOpenMPDirectiveName(DKind);
17579 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17580 // A list item cannot appear in both a map clause and a data-sharing
17581 // attribute clause on the same construct
17583 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17584 // A list item cannot appear in both a map clause and a data-sharing
17585 // attribute clause on the same construct unless the construct is a
17586 // combined construct.
17587 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17588 isOpenMPTargetExecutionDirective(DKind)) ||
17589 DKind == OMPD_target)) {
17590 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17591 if (isOpenMPPrivate(DVar.CKind)) {
17592 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17593 << getOpenMPClauseName(DVar.CKind)
17594 << getOpenMPClauseName(OMPC_map)
17595 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17596 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17602 // Try to find the associated user-defined mapper.
17603 ExprResult ER = buildUserDefinedMapperRef(
17604 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17605 Type.getCanonicalType(), UnresolvedMapper);
17606 if (ER.isInvalid())
17608 MVLI.UDMapperList.push_back(ER.get());
17610 // Save the current expression.
17611 MVLI.ProcessedVarList.push_back(RE);
17613 // Store the components in the stack so that they can be used to check
17614 // against other clauses later on.
17615 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17616 /*WhereFoundClauseKind=*/OMPC_map);
17618 // Save the components and declaration to create the clause. For purposes of
17619 // the clause creation, any component list that has has base 'this' uses
17620 // null as base declaration.
17621 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17622 MVLI.VarComponents.back().append(CurComponents.begin(),
17623 CurComponents.end());
17624 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17629 OMPClause *Sema::ActOnOpenMPMapClause(
17630 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17631 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17632 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17633 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17634 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17635 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17636 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
17637 OMPC_MAP_MODIFIER_unknown,
17638 OMPC_MAP_MODIFIER_unknown};
17639 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17641 // Process map-type-modifiers, flag errors for duplicate modifiers.
17642 unsigned Count = 0;
17643 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17644 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17645 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17646 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17649 assert(Count < NumberOfOMPMapClauseModifiers &&
17650 "Modifiers exceed the allowed number of map type modifiers");
17651 Modifiers[Count] = MapTypeModifiers[I];
17652 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17656 MappableVarListInfo MVLI(VarList);
17657 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
17658 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17659 MapType, IsMapTypeImplicit);
17661 // We need to produce a map clause even if we don't have variables so that
17662 // other diagnostics related with non-existing map clauses are accurate.
17663 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17664 MVLI.VarBaseDeclarations, MVLI.VarComponents,
17665 MVLI.UDMapperList, Modifiers, ModifiersLoc,
17666 MapperIdScopeSpec.getWithLocInContext(Context),
17667 MapperId, MapType, IsMapTypeImplicit, MapLoc);
17670 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17671 TypeResult ParsedType) {
17672 assert(ParsedType.isUsable());
17674 QualType ReductionType = GetTypeFromParser(ParsedType.get());
17675 if (ReductionType.isNull())
17678 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17679 // A type name in a declare reduction directive cannot be a function type, an
17680 // array type, a reference type, or a type qualified with const, volatile or
17682 if (ReductionType.hasQualifiers()) {
17683 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17687 if (ReductionType->isFunctionType()) {
17688 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17691 if (ReductionType->isReferenceType()) {
17692 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17695 if (ReductionType->isArrayType()) {
17696 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17699 return ReductionType;
17702 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17703 Scope *S, DeclContext *DC, DeclarationName Name,
17704 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17705 AccessSpecifier AS, Decl *PrevDeclInScope) {
17706 SmallVector<Decl *, 8> Decls;
17707 Decls.reserve(ReductionTypes.size());
17709 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17710 forRedeclarationInCurContext());
17711 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17712 // A reduction-identifier may not be re-declared in the current scope for the
17713 // same type or for a type that is compatible according to the base language
17715 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17716 OMPDeclareReductionDecl *PrevDRD = nullptr;
17717 bool InCompoundScope = true;
17718 if (S != nullptr) {
17719 // Find previous declaration with the same name not referenced in other
17721 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17723 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17724 LookupName(Lookup, S);
17725 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17726 /*AllowInlineNamespace=*/false);
17727 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17728 LookupResult::Filter Filter = Lookup.makeFilter();
17729 while (Filter.hasNext()) {
17730 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17731 if (InCompoundScope) {
17732 auto I = UsedAsPrevious.find(PrevDecl);
17733 if (I == UsedAsPrevious.end())
17734 UsedAsPrevious[PrevDecl] = false;
17735 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17736 UsedAsPrevious[D] = true;
17738 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17739 PrevDecl->getLocation();
17742 if (InCompoundScope) {
17743 for (const auto &PrevData : UsedAsPrevious) {
17744 if (!PrevData.second) {
17745 PrevDRD = PrevData.first;
17750 } else if (PrevDeclInScope != nullptr) {
17751 auto *PrevDRDInScope = PrevDRD =
17752 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17754 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17755 PrevDRDInScope->getLocation();
17756 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17757 } while (PrevDRDInScope != nullptr);
17759 for (const auto &TyData : ReductionTypes) {
17760 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17761 bool Invalid = false;
17762 if (I != PreviousRedeclTypes.end()) {
17763 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17765 Diag(I->second, diag::note_previous_definition);
17768 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17769 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17770 Name, TyData.first, PrevDRD);
17772 DRD->setAccess(AS);
17773 Decls.push_back(DRD);
17775 DRD->setInvalidDecl();
17780 return DeclGroupPtrTy::make(
17781 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17784 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17785 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17787 // Enter new function scope.
17788 PushFunctionScope();
17789 setFunctionHasBranchProtectedScope();
17790 getCurFunction()->setHasOMPDeclareReductionCombiner();
17793 PushDeclContext(S, DRD);
17797 PushExpressionEvaluationContext(
17798 ExpressionEvaluationContext::PotentiallyEvaluated);
17800 QualType ReductionType = DRD->getType();
17801 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
17802 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
17803 // uses semantics of argument handles by value, but it should be passed by
17804 // reference. C lang does not support references, so pass all parameters as
17806 // Create 'T omp_in;' variable.
17807 VarDecl *OmpInParm =
17808 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
17809 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
17810 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
17811 // uses semantics of argument handles by value, but it should be passed by
17812 // reference. C lang does not support references, so pass all parameters as
17814 // Create 'T omp_out;' variable.
17815 VarDecl *OmpOutParm =
17816 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
17817 if (S != nullptr) {
17818 PushOnScopeChains(OmpInParm, S);
17819 PushOnScopeChains(OmpOutParm, S);
17821 DRD->addDecl(OmpInParm);
17822 DRD->addDecl(OmpOutParm);
17825 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
17827 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
17828 DRD->setCombinerData(InE, OutE);
17831 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
17832 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17833 DiscardCleanupsInEvaluationContext();
17834 PopExpressionEvaluationContext();
17837 PopFunctionScopeInfo();
17839 if (Combiner != nullptr)
17840 DRD->setCombiner(Combiner);
17842 DRD->setInvalidDecl();
17845 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
17846 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17848 // Enter new function scope.
17849 PushFunctionScope();
17850 setFunctionHasBranchProtectedScope();
17853 PushDeclContext(S, DRD);
17857 PushExpressionEvaluationContext(
17858 ExpressionEvaluationContext::PotentiallyEvaluated);
17860 QualType ReductionType = DRD->getType();
17861 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
17862 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
17863 // uses semantics of argument handles by value, but it should be passed by
17864 // reference. C lang does not support references, so pass all parameters as
17866 // Create 'T omp_priv;' variable.
17867 VarDecl *OmpPrivParm =
17868 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
17869 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
17870 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
17871 // uses semantics of argument handles by value, but it should be passed by
17872 // reference. C lang does not support references, so pass all parameters as
17874 // Create 'T omp_orig;' variable.
17875 VarDecl *OmpOrigParm =
17876 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
17877 if (S != nullptr) {
17878 PushOnScopeChains(OmpPrivParm, S);
17879 PushOnScopeChains(OmpOrigParm, S);
17881 DRD->addDecl(OmpPrivParm);
17882 DRD->addDecl(OmpOrigParm);
17885 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
17887 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
17888 DRD->setInitializerData(OrigE, PrivE);
17889 return OmpPrivParm;
17892 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
17893 VarDecl *OmpPrivParm) {
17894 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17895 DiscardCleanupsInEvaluationContext();
17896 PopExpressionEvaluationContext();
17899 PopFunctionScopeInfo();
17901 if (Initializer != nullptr) {
17902 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
17903 } else if (OmpPrivParm->hasInit()) {
17904 DRD->setInitializer(OmpPrivParm->getInit(),
17905 OmpPrivParm->isDirectInit()
17906 ? OMPDeclareReductionDecl::DirectInit
17907 : OMPDeclareReductionDecl::CopyInit);
17909 DRD->setInvalidDecl();
17913 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
17914 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
17915 for (Decl *D : DeclReductions.get()) {
17918 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
17919 /*AddToContext=*/false);
17921 D->setInvalidDecl();
17924 return DeclReductions;
17927 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
17928 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
17929 QualType T = TInfo->getType();
17930 if (D.isInvalidType())
17933 if (getLangOpts().CPlusPlus) {
17934 // Check that there are no default arguments (C++ only).
17935 CheckExtraCXXDefaultArguments(D);
17938 return CreateParsedType(T, TInfo);
17941 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
17942 TypeResult ParsedType) {
17943 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
17945 QualType MapperType = GetTypeFromParser(ParsedType.get());
17946 assert(!MapperType.isNull() && "Expect valid mapper type");
17948 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17949 // The type must be of struct, union or class type in C and C++
17950 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
17951 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
17957 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
17958 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
17959 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
17960 Decl *PrevDeclInScope) {
17961 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
17962 forRedeclarationInCurContext());
17963 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17964 // A mapper-identifier may not be redeclared in the current scope for the
17965 // same type or for a type that is compatible according to the base language
17967 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17968 OMPDeclareMapperDecl *PrevDMD = nullptr;
17969 bool InCompoundScope = true;
17970 if (S != nullptr) {
17971 // Find previous declaration with the same name not referenced in other
17973 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17975 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17976 LookupName(Lookup, S);
17977 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17978 /*AllowInlineNamespace=*/false);
17979 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
17980 LookupResult::Filter Filter = Lookup.makeFilter();
17981 while (Filter.hasNext()) {
17982 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
17983 if (InCompoundScope) {
17984 auto I = UsedAsPrevious.find(PrevDecl);
17985 if (I == UsedAsPrevious.end())
17986 UsedAsPrevious[PrevDecl] = false;
17987 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
17988 UsedAsPrevious[D] = true;
17990 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17991 PrevDecl->getLocation();
17994 if (InCompoundScope) {
17995 for (const auto &PrevData : UsedAsPrevious) {
17996 if (!PrevData.second) {
17997 PrevDMD = PrevData.first;
18002 } else if (PrevDeclInScope) {
18003 auto *PrevDMDInScope = PrevDMD =
18004 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18006 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18007 PrevDMDInScope->getLocation();
18008 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18009 } while (PrevDMDInScope != nullptr);
18011 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18012 bool Invalid = false;
18013 if (I != PreviousRedeclTypes.end()) {
18014 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18015 << MapperType << Name;
18016 Diag(I->second, diag::note_previous_definition);
18019 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18020 MapperType, VN, PrevDMD);
18022 DMD->setAccess(AS);
18024 DMD->setInvalidDecl();
18026 // Enter new function scope.
18027 PushFunctionScope();
18028 setFunctionHasBranchProtectedScope();
18035 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
18037 QualType MapperType,
18038 SourceLocation StartLoc,
18039 DeclarationName VN) {
18040 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
18042 PushOnScopeChains(VD, S);
18045 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18046 DMD->setMapperVarRef(MapperVarRefExpr);
18049 Sema::DeclGroupPtrTy
18050 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
18051 ArrayRef<OMPClause *> ClauseList) {
18053 PopFunctionScopeInfo();
18057 PushOnScopeChains(D, S, /*AddToContext=*/false);
18058 D->CreateClauses(Context, ClauseList);
18061 return DeclGroupPtrTy::make(DeclGroupRef(D));
18064 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18065 SourceLocation StartLoc,
18066 SourceLocation LParenLoc,
18067 SourceLocation EndLoc) {
18068 Expr *ValExpr = NumTeams;
18069 Stmt *HelperValStmt = nullptr;
18071 // OpenMP [teams Constrcut, Restrictions]
18072 // The num_teams expression must evaluate to a positive integer value.
18073 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18074 /*StrictlyPositive=*/true))
18077 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18078 OpenMPDirectiveKind CaptureRegion =
18079 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18080 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18081 ValExpr = MakeFullExpr(ValExpr).get();
18082 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18083 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18084 HelperValStmt = buildPreInits(Context, Captures);
18087 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18088 StartLoc, LParenLoc, EndLoc);
18091 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18092 SourceLocation StartLoc,
18093 SourceLocation LParenLoc,
18094 SourceLocation EndLoc) {
18095 Expr *ValExpr = ThreadLimit;
18096 Stmt *HelperValStmt = nullptr;
18098 // OpenMP [teams Constrcut, Restrictions]
18099 // The thread_limit expression must evaluate to a positive integer value.
18100 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18101 /*StrictlyPositive=*/true))
18104 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18105 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18106 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18107 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18108 ValExpr = MakeFullExpr(ValExpr).get();
18109 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18110 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18111 HelperValStmt = buildPreInits(Context, Captures);
18114 return new (Context) OMPThreadLimitClause(
18115 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18118 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18119 SourceLocation StartLoc,
18120 SourceLocation LParenLoc,
18121 SourceLocation EndLoc) {
18122 Expr *ValExpr = Priority;
18123 Stmt *HelperValStmt = nullptr;
18124 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18126 // OpenMP [2.9.1, task Constrcut]
18127 // The priority-value is a non-negative numerical scalar expression.
18128 if (!isNonNegativeIntegerValue(
18129 ValExpr, *this, OMPC_priority,
18130 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18131 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18134 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18135 StartLoc, LParenLoc, EndLoc);
18138 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18139 SourceLocation StartLoc,
18140 SourceLocation LParenLoc,
18141 SourceLocation EndLoc) {
18142 Expr *ValExpr = Grainsize;
18143 Stmt *HelperValStmt = nullptr;
18144 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18146 // OpenMP [2.9.2, taskloop Constrcut]
18147 // The parameter of the grainsize clause must be a positive integer
18149 if (!isNonNegativeIntegerValue(
18150 ValExpr, *this, OMPC_grainsize,
18151 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18152 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18155 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18156 StartLoc, LParenLoc, EndLoc);
18159 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18160 SourceLocation StartLoc,
18161 SourceLocation LParenLoc,
18162 SourceLocation EndLoc) {
18163 Expr *ValExpr = NumTasks;
18164 Stmt *HelperValStmt = nullptr;
18165 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18167 // OpenMP [2.9.2, taskloop Constrcut]
18168 // The parameter of the num_tasks clause must be a positive integer
18170 if (!isNonNegativeIntegerValue(
18171 ValExpr, *this, OMPC_num_tasks,
18172 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18173 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18176 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18177 StartLoc, LParenLoc, EndLoc);
18180 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18181 SourceLocation LParenLoc,
18182 SourceLocation EndLoc) {
18183 // OpenMP [2.13.2, critical construct, Description]
18184 // ... where hint-expression is an integer constant expression that evaluates
18185 // to a valid lock hint.
18186 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18187 if (HintExpr.isInvalid())
18189 return new (Context)
18190 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18193 /// Tries to find omp_event_handle_t type.
18194 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18195 DSAStackTy *Stack) {
18196 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18197 if (!OMPEventHandleT.isNull())
18199 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18200 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18201 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18202 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18205 Stack->setOMPEventHandleT(PT.get());
18209 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18210 SourceLocation LParenLoc,
18211 SourceLocation EndLoc) {
18212 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18213 !Evt->isInstantiationDependent() &&
18214 !Evt->containsUnexpandedParameterPack()) {
18215 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18217 // OpenMP 5.0, 2.10.1 task Construct.
18218 // event-handle is a variable of the omp_event_handle_t type.
18219 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18221 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18222 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18225 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18227 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18228 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18231 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18233 VD->getType().isConstant(Context)) {
18234 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18235 << "omp_event_handle_t" << 1 << VD->getType()
18236 << Evt->getSourceRange();
18239 // OpenMP 5.0, 2.10.1 task Construct
18240 // [detach clause]... The event-handle will be considered as if it was
18241 // specified on a firstprivate clause.
18242 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18243 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18245 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18246 << getOpenMPClauseName(DVar.CKind)
18247 << getOpenMPClauseName(OMPC_firstprivate);
18248 reportOriginalDsa(*this, DSAStack, VD, DVar);
18253 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18256 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18257 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18258 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18259 SourceLocation EndLoc) {
18260 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18261 std::string Values;
18263 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18265 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18266 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18269 Expr *ValExpr = ChunkSize;
18270 Stmt *HelperValStmt = nullptr;
18272 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18273 !ChunkSize->isInstantiationDependent() &&
18274 !ChunkSize->containsUnexpandedParameterPack()) {
18275 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18277 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18278 if (Val.isInvalid())
18281 ValExpr = Val.get();
18283 // OpenMP [2.7.1, Restrictions]
18284 // chunk_size must be a loop invariant integer expression with a positive
18286 llvm::APSInt Result;
18287 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
18288 if (Result.isSigned() && !Result.isStrictlyPositive()) {
18289 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18290 << "dist_schedule" << ChunkSize->getSourceRange();
18293 } else if (getOpenMPCaptureRegionForClause(
18294 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18295 LangOpts.OpenMP) != OMPD_unknown &&
18296 !CurContext->isDependentContext()) {
18297 ValExpr = MakeFullExpr(ValExpr).get();
18298 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18299 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18300 HelperValStmt = buildPreInits(Context, Captures);
18305 return new (Context)
18306 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18307 Kind, ValExpr, HelperValStmt);
18310 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18311 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18312 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18313 SourceLocation KindLoc, SourceLocation EndLoc) {
18314 if (getLangOpts().OpenMP < 50) {
18315 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18316 Kind != OMPC_DEFAULTMAP_scalar) {
18318 SourceLocation Loc;
18320 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18321 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18322 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18325 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18326 OMPC_DEFAULTMAP_scalar);
18330 Diag(Loc, diag::err_omp_unexpected_clause_value)
18331 << Value << getOpenMPClauseName(OMPC_defaultmap);
18335 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18336 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18337 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18338 if (!isDefaultmapKind || !isDefaultmapModifier) {
18339 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18340 "'firstprivate', 'none', 'default'";
18341 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18342 if (!isDefaultmapKind && isDefaultmapModifier) {
18343 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18344 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18345 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18346 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18347 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18349 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18350 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18351 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18352 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18357 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18358 // At most one defaultmap clause for each category can appear on the
18360 if (DSAStack->checkDefaultmapCategory(Kind)) {
18361 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18365 if (Kind == OMPC_DEFAULTMAP_unknown) {
18366 // Variable category is not specified - mark all categories.
18367 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18368 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18369 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18371 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18374 return new (Context)
18375 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18378 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18379 DeclContext *CurLexicalContext = getCurLexicalContext();
18380 if (!CurLexicalContext->isFileContext() &&
18381 !CurLexicalContext->isExternCContext() &&
18382 !CurLexicalContext->isExternCXXContext() &&
18383 !isa<CXXRecordDecl>(CurLexicalContext) &&
18384 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18385 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18386 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18387 Diag(Loc, diag::err_omp_region_not_file_context);
18390 ++DeclareTargetNestingLevel;
18394 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18395 assert(DeclareTargetNestingLevel > 0 &&
18396 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18397 --DeclareTargetNestingLevel;
18401 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18402 const DeclarationNameInfo &Id,
18403 NamedDeclSetType &SameDirectiveDecls) {
18404 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18405 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18407 if (Lookup.isAmbiguous())
18409 Lookup.suppressDiagnostics();
18411 if (!Lookup.isSingleResult()) {
18412 VarOrFuncDeclFilterCCC CCC(*this);
18413 if (TypoCorrection Corrected =
18414 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18415 CTK_ErrorRecovery)) {
18416 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18418 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18422 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18426 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18427 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18428 !isa<FunctionTemplateDecl>(ND)) {
18429 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18432 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18433 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18437 void Sema::ActOnOpenMPDeclareTargetName(
18438 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18439 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18440 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18441 isa<FunctionTemplateDecl>(ND)) &&
18442 "Expected variable, function or function template.");
18444 // Diagnose marking after use as it may lead to incorrect diagnosis and
18446 if (LangOpts.OpenMP >= 50 &&
18447 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18448 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18450 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18451 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
18452 if (DevTy.hasValue() && *DevTy != DT) {
18453 Diag(Loc, diag::err_omp_device_type_mismatch)
18454 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18455 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18458 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18459 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
18461 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
18462 SourceRange(Loc, Loc));
18464 if (ASTMutationListener *ML = Context.getASTMutationListener())
18465 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18466 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18467 } else if (*Res != MT) {
18468 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18472 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18473 Sema &SemaRef, Decl *D) {
18474 if (!D || !isa<VarDecl>(D))
18476 auto *VD = cast<VarDecl>(D);
18477 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18478 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18479 if (SemaRef.LangOpts.OpenMP >= 50 &&
18480 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18481 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18482 VD->hasGlobalStorage()) {
18483 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18484 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18485 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18486 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18487 // If a lambda declaration and definition appears between a
18488 // declare target directive and the matching end declare target
18489 // directive, all variables that are captured by the lambda
18490 // expression must also appear in a to clause.
18491 SemaRef.Diag(VD->getLocation(),
18492 diag::err_omp_lambda_capture_in_declare_target_not_to);
18493 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18498 if (MapTy.hasValue())
18500 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18501 SemaRef.Diag(SL, diag::note_used_here) << SR;
18504 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18505 Sema &SemaRef, DSAStackTy *Stack,
18507 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18508 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18509 /*FullCheck=*/false);
18512 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18513 SourceLocation IdLoc) {
18514 if (!D || D->isInvalidDecl())
18516 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18517 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18518 if (auto *VD = dyn_cast<VarDecl>(D)) {
18519 // Only global variables can be marked as declare target.
18520 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18521 !VD->isStaticDataMember())
18523 // 2.10.6: threadprivate variable cannot appear in a declare target
18525 if (DSAStack->isThreadPrivate(VD)) {
18526 Diag(SL, diag::err_omp_threadprivate_in_target);
18527 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18531 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18532 D = FTD->getTemplatedDecl();
18533 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18534 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18535 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18536 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18537 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18538 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18542 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18543 // Problem if any with var declared with incomplete type will be reported
18544 // as normal, so no need to check it here.
18545 if ((E || !VD->getType()->isIncompleteType()) &&
18546 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18548 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18549 // Checking declaration inside declare target region.
18550 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18551 isa<FunctionTemplateDecl>(D)) {
18552 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18553 Context, OMPDeclareTargetDeclAttr::MT_To,
18554 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
18556 if (ASTMutationListener *ML = Context.getASTMutationListener())
18557 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18564 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18567 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
18568 CXXScopeSpec &MapperIdScopeSpec,
18569 DeclarationNameInfo &MapperId,
18570 const OMPVarListLocTy &Locs,
18571 ArrayRef<Expr *> UnresolvedMappers) {
18572 MappableVarListInfo MVLI(VarList);
18573 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18574 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18575 if (MVLI.ProcessedVarList.empty())
18578 return OMPToClause::Create(
18579 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18580 MVLI.VarComponents, MVLI.UDMapperList,
18581 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18584 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
18585 CXXScopeSpec &MapperIdScopeSpec,
18586 DeclarationNameInfo &MapperId,
18587 const OMPVarListLocTy &Locs,
18588 ArrayRef<Expr *> UnresolvedMappers) {
18589 MappableVarListInfo MVLI(VarList);
18590 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
18591 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18592 if (MVLI.ProcessedVarList.empty())
18595 return OMPFromClause::Create(
18596 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18597 MVLI.VarComponents, MVLI.UDMapperList,
18598 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18601 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18602 const OMPVarListLocTy &Locs) {
18603 MappableVarListInfo MVLI(VarList);
18604 SmallVector<Expr *, 8> PrivateCopies;
18605 SmallVector<Expr *, 8> Inits;
18607 for (Expr *RefExpr : VarList) {
18608 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
18609 SourceLocation ELoc;
18610 SourceRange ERange;
18611 Expr *SimpleRefExpr = RefExpr;
18612 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18614 // It will be analyzed later.
18615 MVLI.ProcessedVarList.push_back(RefExpr);
18616 PrivateCopies.push_back(nullptr);
18617 Inits.push_back(nullptr);
18619 ValueDecl *D = Res.first;
18623 QualType Type = D->getType();
18624 Type = Type.getNonReferenceType().getUnqualifiedType();
18626 auto *VD = dyn_cast<VarDecl>(D);
18628 // Item should be a pointer or reference to pointer.
18629 if (!Type->isPointerType()) {
18630 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18631 << 0 << RefExpr->getSourceRange();
18635 // Build the private variable and the expression that refers to it.
18637 buildVarDecl(*this, ELoc, Type, D->getName(),
18638 D->hasAttrs() ? &D->getAttrs() : nullptr,
18639 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18640 if (VDPrivate->isInvalidDecl())
18643 CurContext->addDecl(VDPrivate);
18644 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18645 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18647 // Add temporary variable to initialize the private copy of the pointer.
18649 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18650 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18651 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18652 AddInitializerToDecl(VDPrivate,
18653 DefaultLvalueConversion(VDInitRefExpr).get(),
18654 /*DirectInit=*/false);
18656 // If required, build a capture to implement the privatization initialized
18657 // with the current list item value.
18658 DeclRefExpr *Ref = nullptr;
18660 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18661 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18662 PrivateCopies.push_back(VDPrivateRefExpr);
18663 Inits.push_back(VDInitRefExpr);
18665 // We need to add a data sharing attribute for this variable to make sure it
18666 // is correctly captured. A variable that shows up in a use_device_ptr has
18667 // similar properties of a first private variable.
18668 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18670 // Create a mappable component for the list item. List items in this clause
18671 // only need a component.
18672 MVLI.VarBaseDeclarations.push_back(D);
18673 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18674 MVLI.VarComponents.back().push_back(
18675 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
18678 if (MVLI.ProcessedVarList.empty())
18681 return OMPUseDevicePtrClause::Create(
18682 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18683 MVLI.VarBaseDeclarations, MVLI.VarComponents);
18686 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18687 const OMPVarListLocTy &Locs) {
18688 MappableVarListInfo MVLI(VarList);
18690 for (Expr *RefExpr : VarList) {
18691 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
18692 SourceLocation ELoc;
18693 SourceRange ERange;
18694 Expr *SimpleRefExpr = RefExpr;
18695 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18696 /*AllowArraySection=*/true);
18698 // It will be analyzed later.
18699 MVLI.ProcessedVarList.push_back(RefExpr);
18701 ValueDecl *D = Res.first;
18704 auto *VD = dyn_cast<VarDecl>(D);
18706 // If required, build a capture to implement the privatization initialized
18707 // with the current list item value.
18708 DeclRefExpr *Ref = nullptr;
18710 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18711 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18713 // We need to add a data sharing attribute for this variable to make sure it
18714 // is correctly captured. A variable that shows up in a use_device_addr has
18715 // similar properties of a first private variable.
18716 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18718 // Create a mappable component for the list item. List items in this clause
18719 // only need a component.
18720 MVLI.VarBaseDeclarations.push_back(D);
18721 MVLI.VarComponents.emplace_back();
18722 Expr *Component = SimpleRefExpr;
18723 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18724 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18725 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18726 MVLI.VarComponents.back().push_back(
18727 OMPClauseMappableExprCommon::MappableComponent(Component, D));
18730 if (MVLI.ProcessedVarList.empty())
18733 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18734 MVLI.VarBaseDeclarations,
18735 MVLI.VarComponents);
18738 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18739 const OMPVarListLocTy &Locs) {
18740 MappableVarListInfo MVLI(VarList);
18741 for (Expr *RefExpr : VarList) {
18742 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
18743 SourceLocation ELoc;
18744 SourceRange ERange;
18745 Expr *SimpleRefExpr = RefExpr;
18746 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18748 // It will be analyzed later.
18749 MVLI.ProcessedVarList.push_back(RefExpr);
18751 ValueDecl *D = Res.first;
18755 QualType Type = D->getType();
18756 // item should be a pointer or array or reference to pointer or array
18757 if (!Type.getNonReferenceType()->isPointerType() &&
18758 !Type.getNonReferenceType()->isArrayType()) {
18759 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
18760 << 0 << RefExpr->getSourceRange();
18764 // Check if the declaration in the clause does not show up in any data
18765 // sharing attribute.
18766 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18767 if (isOpenMPPrivate(DVar.CKind)) {
18768 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18769 << getOpenMPClauseName(DVar.CKind)
18770 << getOpenMPClauseName(OMPC_is_device_ptr)
18771 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18772 reportOriginalDsa(*this, DSAStack, D, DVar);
18776 const Expr *ConflictExpr;
18777 if (DSAStack->checkMappableExprComponentListsForDecl(
18778 D, /*CurrentRegionOnly=*/true,
18780 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
18781 OpenMPClauseKind) -> bool {
18782 ConflictExpr = R.front().getAssociatedExpression();
18785 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
18786 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
18787 << ConflictExpr->getSourceRange();
18791 // Store the components in the stack so that they can be used to check
18792 // against other clauses later on.
18793 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
18794 DSAStack->addMappableExpressionComponents(
18795 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
18797 // Record the expression we've just processed.
18798 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
18800 // Create a mappable component for the list item. List items in this clause
18801 // only need a component. We use a null declaration to signal fields in
18803 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
18804 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
18805 "Unexpected device pointer expression!");
18806 MVLI.VarBaseDeclarations.push_back(
18807 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
18808 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18809 MVLI.VarComponents.back().push_back(MC);
18812 if (MVLI.ProcessedVarList.empty())
18815 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18816 MVLI.VarBaseDeclarations,
18817 MVLI.VarComponents);
18820 OMPClause *Sema::ActOnOpenMPAllocateClause(
18821 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18822 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
18824 // OpenMP [2.11.4 allocate Clause, Description]
18825 // allocator is an expression of omp_allocator_handle_t type.
18826 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
18829 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
18830 if (AllocatorRes.isInvalid())
18832 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
18833 DSAStack->getOMPAllocatorHandleT(),
18834 Sema::AA_Initializing,
18835 /*AllowExplicit=*/true);
18836 if (AllocatorRes.isInvalid())
18838 Allocator = AllocatorRes.get();
18840 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
18841 // allocate clauses that appear on a target construct or on constructs in a
18842 // target region must specify an allocator expression unless a requires
18843 // directive with the dynamic_allocators clause is present in the same
18844 // compilation unit.
18845 if (LangOpts.OpenMPIsDevice &&
18846 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
18847 targetDiag(StartLoc, diag::err_expected_allocator_expression);
18849 // Analyze and build list of variables.
18850 SmallVector<Expr *, 8> Vars;
18851 for (Expr *RefExpr : VarList) {
18852 assert(RefExpr && "NULL expr in OpenMP private clause.");
18853 SourceLocation ELoc;
18854 SourceRange ERange;
18855 Expr *SimpleRefExpr = RefExpr;
18856 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18858 // It will be analyzed later.
18859 Vars.push_back(RefExpr);
18861 ValueDecl *D = Res.first;
18865 auto *VD = dyn_cast<VarDecl>(D);
18866 DeclRefExpr *Ref = nullptr;
18867 if (!VD && !CurContext->isDependentContext())
18868 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18869 Vars.push_back((VD || CurContext->isDependentContext())
18870 ? RefExpr->IgnoreParens()
18878 DSAStack->addInnerAllocatorExpr(Allocator);
18879 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
18880 ColonLoc, EndLoc, Vars);
18883 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
18884 SourceLocation StartLoc,
18885 SourceLocation LParenLoc,
18886 SourceLocation EndLoc) {
18887 SmallVector<Expr *, 8> Vars;
18888 for (Expr *RefExpr : VarList) {
18889 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18890 SourceLocation ELoc;
18891 SourceRange ERange;
18892 Expr *SimpleRefExpr = RefExpr;
18893 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18895 // It will be analyzed later.
18896 Vars.push_back(RefExpr);
18897 ValueDecl *D = Res.first;
18901 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
18902 // A list-item cannot appear in more than one nontemporal clause.
18903 if (const Expr *PrevRef =
18904 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
18905 Diag(ELoc, diag::err_omp_used_in_clause_twice)
18906 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
18907 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
18908 << getOpenMPClauseName(OMPC_nontemporal);
18912 Vars.push_back(RefExpr);
18918 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18922 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
18923 SourceLocation StartLoc,
18924 SourceLocation LParenLoc,
18925 SourceLocation EndLoc) {
18926 SmallVector<Expr *, 8> Vars;
18927 for (Expr *RefExpr : VarList) {
18928 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18929 SourceLocation ELoc;
18930 SourceRange ERange;
18931 Expr *SimpleRefExpr = RefExpr;
18932 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18933 /*AllowArraySection=*/true);
18935 // It will be analyzed later.
18936 Vars.push_back(RefExpr);
18937 ValueDecl *D = Res.first;
18941 const DSAStackTy::DSAVarData DVar =
18942 DSAStack->getTopDSA(D, /*FromParent=*/true);
18943 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
18944 // A list item that appears in the inclusive or exclusive clause must appear
18945 // in a reduction clause with the inscan modifier on the enclosing
18946 // worksharing-loop, worksharing-loop SIMD, or simd construct.
18947 if (DVar.CKind != OMPC_reduction ||
18948 DVar.Modifier != OMPC_REDUCTION_inscan)
18949 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
18950 << RefExpr->getSourceRange();
18952 if (DSAStack->getParentDirective() != OMPD_unknown)
18953 DSAStack->markDeclAsUsedInScanDirective(D);
18954 Vars.push_back(RefExpr);
18960 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18963 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
18964 SourceLocation StartLoc,
18965 SourceLocation LParenLoc,
18966 SourceLocation EndLoc) {
18967 SmallVector<Expr *, 8> Vars;
18968 for (Expr *RefExpr : VarList) {
18969 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18970 SourceLocation ELoc;
18971 SourceRange ERange;
18972 Expr *SimpleRefExpr = RefExpr;
18973 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18974 /*AllowArraySection=*/true);
18976 // It will be analyzed later.
18977 Vars.push_back(RefExpr);
18978 ValueDecl *D = Res.first;
18982 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
18983 DSAStackTy::DSAVarData DVar;
18984 if (ParentDirective != OMPD_unknown)
18985 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
18986 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
18987 // A list item that appears in the inclusive or exclusive clause must appear
18988 // in a reduction clause with the inscan modifier on the enclosing
18989 // worksharing-loop, worksharing-loop SIMD, or simd construct.
18990 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
18991 DVar.Modifier != OMPC_REDUCTION_inscan) {
18992 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
18993 << RefExpr->getSourceRange();
18995 DSAStack->markDeclAsUsedInScanDirective(D);
18997 Vars.push_back(RefExpr);
19003 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19006 /// Tries to find omp_alloctrait_t type.
19007 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19008 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19009 if (!OMPAlloctraitT.isNull())
19011 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19012 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19013 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19014 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19017 Stack->setOMPAlloctraitT(PT.get());
19021 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19022 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19023 ArrayRef<UsesAllocatorsData> Data) {
19024 // OpenMP [2.12.5, target Construct]
19025 // allocator is an identifier of omp_allocator_handle_t type.
19026 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19028 // OpenMP [2.12.5, target Construct]
19029 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19032 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19033 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19035 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19036 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19037 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19038 StringRef Allocator =
19039 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19040 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19041 PredefinedAllocators.insert(LookupSingleName(
19042 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19045 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19046 for (const UsesAllocatorsData &D : Data) {
19047 Expr *AllocatorExpr = nullptr;
19048 // Check allocator expression.
19049 if (D.Allocator->isTypeDependent()) {
19050 AllocatorExpr = D.Allocator;
19052 // Traits were specified - need to assign new allocator to the specified
19053 // allocator, so it must be an lvalue.
19054 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19055 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19056 bool IsPredefinedAllocator = false;
19058 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19060 !(Context.hasSameUnqualifiedType(
19061 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19062 Context.typesAreCompatible(AllocatorExpr->getType(),
19063 DSAStack->getOMPAllocatorHandleT(),
19064 /*CompareUnqualified=*/true)) ||
19065 (!IsPredefinedAllocator &&
19066 (AllocatorExpr->getType().isConstant(Context) ||
19067 !AllocatorExpr->isLValue()))) {
19068 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19069 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19070 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19073 // OpenMP [2.12.5, target Construct]
19074 // Predefined allocators appearing in a uses_allocators clause cannot have
19075 // traits specified.
19076 if (IsPredefinedAllocator && D.AllocatorTraits) {
19077 Diag(D.AllocatorTraits->getExprLoc(),
19078 diag::err_omp_predefined_allocator_with_traits)
19079 << D.AllocatorTraits->getSourceRange();
19080 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19081 << cast<NamedDecl>(DRE->getDecl())->getName()
19082 << D.Allocator->getSourceRange();
19085 // OpenMP [2.12.5, target Construct]
19086 // Non-predefined allocators appearing in a uses_allocators clause must
19087 // have traits specified.
19088 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19089 Diag(D.Allocator->getExprLoc(),
19090 diag::err_omp_nonpredefined_allocator_without_traits);
19093 // No allocator traits - just convert it to rvalue.
19094 if (!D.AllocatorTraits)
19095 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19096 DSAStack->addUsesAllocatorsDecl(
19098 IsPredefinedAllocator
19099 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19100 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19102 Expr *AllocatorTraitsExpr = nullptr;
19103 if (D.AllocatorTraits) {
19104 if (D.AllocatorTraits->isTypeDependent()) {
19105 AllocatorTraitsExpr = D.AllocatorTraits;
19107 // OpenMP [2.12.5, target Construct]
19108 // Arrays that contain allocator traits that appear in a uses_allocators
19109 // clause must be constant arrays, have constant values and be defined
19110 // in the same scope as the construct in which the clause appears.
19111 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19112 // Check that traits expr is a constant array.
19114 if (const ArrayType *Ty =
19115 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19116 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19117 TraitTy = ConstArrayTy->getElementType();
19118 if (TraitTy.isNull() ||
19119 !(Context.hasSameUnqualifiedType(TraitTy,
19120 DSAStack->getOMPAlloctraitT()) ||
19121 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19122 /*CompareUnqualified=*/true))) {
19123 Diag(D.AllocatorTraits->getExprLoc(),
19124 diag::err_omp_expected_array_alloctraits)
19125 << AllocatorTraitsExpr->getType();
19128 // Do not map by default allocator traits if it is a standalone
19130 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19131 DSAStack->addUsesAllocatorsDecl(
19133 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19136 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19137 NewD.Allocator = AllocatorExpr;
19138 NewD.AllocatorTraits = AllocatorTraitsExpr;
19139 NewD.LParenLoc = D.LParenLoc;
19140 NewD.RParenLoc = D.RParenLoc;
19142 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19146 OMPClause *Sema::ActOnOpenMPAffinityClause(
19147 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19148 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19149 SmallVector<Expr *, 8> Vars;
19150 for (Expr *RefExpr : Locators) {
19151 assert(RefExpr && "NULL expr in OpenMP shared clause.");
19152 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19153 // It will be analyzed later.
19154 Vars.push_back(RefExpr);
19158 SourceLocation ELoc = RefExpr->getExprLoc();
19159 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19161 if (!SimpleExpr->isLValue()) {
19162 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19163 << 1 << 0 << RefExpr->getSourceRange();
19169 Sema::TentativeAnalysisScope Trap(*this);
19170 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19172 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19173 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19174 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19175 << 1 << 0 << RefExpr->getSourceRange();
19178 Vars.push_back(SimpleExpr);
19181 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19182 EndLoc, Modifier, Vars);