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/ADT/SmallSet.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Frontend/OpenMP/OMPAssume.h"
41 #include "llvm/Frontend/OpenMP/OMPConstants.h"
44 using namespace clang
;
45 using namespace llvm::omp
;
47 //===----------------------------------------------------------------------===//
48 // Stack of data-sharing attributes for variables
49 //===----------------------------------------------------------------------===//
51 static const Expr
*checkMapClauseExpressionBase(
52 Sema
&SemaRef
, Expr
*E
,
53 OMPClauseMappableExprCommon::MappableExprComponentList
&CurComponents
,
54 OpenMPClauseKind CKind
, OpenMPDirectiveKind DKind
, bool NoDiagnose
);
57 /// Default data sharing attributes, which can be applied to directive.
58 enum DefaultDataSharingAttributes
{
59 DSA_unspecified
= 0, /// Data sharing attribute not specified.
60 DSA_none
= 1 << 0, /// Default data sharing attribute 'none'.
61 DSA_shared
= 1 << 1, /// Default data sharing attribute 'shared'.
62 DSA_private
= 1 << 2, /// Default data sharing attribute 'private'.
63 DSA_firstprivate
= 1 << 3, /// Default data sharing attribute 'firstprivate'.
66 /// Stack for tracking declarations used in OpenMP directives and
67 /// clauses and their data-sharing attributes.
71 OpenMPDirectiveKind DKind
= OMPD_unknown
;
72 OpenMPClauseKind CKind
= OMPC_unknown
;
73 unsigned Modifier
= 0;
74 const Expr
*RefExpr
= nullptr;
75 DeclRefExpr
*PrivateCopy
= nullptr;
76 SourceLocation ImplicitDSALoc
;
77 bool AppliedToPointee
= false;
78 DSAVarData() = default;
79 DSAVarData(OpenMPDirectiveKind DKind
, OpenMPClauseKind CKind
,
80 const Expr
*RefExpr
, DeclRefExpr
*PrivateCopy
,
81 SourceLocation ImplicitDSALoc
, unsigned Modifier
,
82 bool AppliedToPointee
)
83 : DKind(DKind
), CKind(CKind
), Modifier(Modifier
), RefExpr(RefExpr
),
84 PrivateCopy(PrivateCopy
), ImplicitDSALoc(ImplicitDSALoc
),
85 AppliedToPointee(AppliedToPointee
) {}
87 using OperatorOffsetTy
=
88 llvm::SmallVector
<std::pair
<Expr
*, OverloadedOperatorKind
>, 4>;
89 using DoacrossDependMapTy
=
90 llvm::DenseMap
<OMPDependClause
*, OperatorOffsetTy
>;
91 /// Kind of the declaration used in the uses_allocators clauses.
92 enum class UsesAllocatorsDeclKind
{
93 /// Predefined allocator
95 /// User-defined allocator
97 /// The declaration that represent allocator trait
103 OpenMPClauseKind Attributes
= OMPC_unknown
;
104 unsigned Modifier
= 0;
105 /// Pointer to a reference expression and a flag which shows that the
106 /// variable is marked as lastprivate(true) or not (false).
107 llvm::PointerIntPair
<const Expr
*, 1, bool> RefExpr
;
108 DeclRefExpr
*PrivateCopy
= nullptr;
109 /// true if the attribute is applied to the pointee, not the variable
111 bool AppliedToPointee
= false;
113 using DeclSAMapTy
= llvm::SmallDenseMap
<const ValueDecl
*, DSAInfo
, 8>;
114 using UsedRefMapTy
= llvm::SmallDenseMap
<const ValueDecl
*, const Expr
*, 8>;
115 using LCDeclInfo
= std::pair
<unsigned, VarDecl
*>;
116 using LoopControlVariablesMapTy
=
117 llvm::SmallDenseMap
<const ValueDecl
*, LCDeclInfo
, 8>;
118 /// Struct that associates a component with the clause kind where they are
120 struct MappedExprComponentTy
{
121 OMPClauseMappableExprCommon::MappableExprComponentLists Components
;
122 OpenMPClauseKind Kind
= OMPC_unknown
;
124 using MappedExprComponentsTy
=
125 llvm::DenseMap
<const ValueDecl
*, MappedExprComponentTy
>;
126 using CriticalsWithHintsTy
=
127 llvm::StringMap
<std::pair
<const OMPCriticalDirective
*, llvm::APSInt
>>;
128 struct ReductionData
{
129 using BOKPtrType
= llvm::PointerEmbeddedInt
<BinaryOperatorKind
, 16>;
130 SourceRange ReductionRange
;
131 llvm::PointerUnion
<const Expr
*, BOKPtrType
> ReductionOp
;
132 ReductionData() = default;
133 void set(BinaryOperatorKind BO
, SourceRange RR
) {
137 void set(const Expr
*RefExpr
, SourceRange RR
) {
139 ReductionOp
= RefExpr
;
142 using DeclReductionMapTy
=
143 llvm::SmallDenseMap
<const ValueDecl
*, ReductionData
, 4>;
144 struct DefaultmapInfo
{
145 OpenMPDefaultmapClauseModifier ImplicitBehavior
=
146 OMPC_DEFAULTMAP_MODIFIER_unknown
;
148 DefaultmapInfo() = default;
149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M
, SourceLocation Loc
)
150 : ImplicitBehavior(M
), SLoc(Loc
) {}
153 struct SharingMapTy
{
154 DeclSAMapTy SharingMap
;
155 DeclReductionMapTy ReductionMap
;
156 UsedRefMapTy AlignedMap
;
157 UsedRefMapTy NontemporalMap
;
158 MappedExprComponentsTy MappedExprComponents
;
159 LoopControlVariablesMapTy LCVMap
;
160 DefaultDataSharingAttributes DefaultAttr
= DSA_unspecified
;
161 SourceLocation DefaultAttrLoc
;
162 DefaultmapInfo DefaultmapMap
[OMPC_DEFAULTMAP_unknown
];
163 OpenMPDirectiveKind Directive
= OMPD_unknown
;
164 DeclarationNameInfo DirectiveName
;
165 Scope
*CurScope
= nullptr;
166 DeclContext
*Context
= nullptr;
167 SourceLocation ConstructLoc
;
168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
169 /// get the data (loop counters etc.) about enclosing loop-based construct.
170 /// This data is required during codegen.
171 DoacrossDependMapTy DoacrossDepends
;
172 /// First argument (Expr *) contains optional argument of the
173 /// 'ordered' clause, the second one is true if the regions has 'ordered'
174 /// clause, false otherwise.
175 llvm::Optional
<std::pair
<const Expr
*, OMPOrderedClause
*>> OrderedRegion
;
176 unsigned AssociatedLoops
= 1;
177 bool HasMutipleLoops
= false;
178 const Decl
*PossiblyLoopCounter
= nullptr;
179 bool NowaitRegion
= false;
180 bool UntiedRegion
= false;
181 bool CancelRegion
= false;
182 bool LoopStart
= false;
183 bool BodyComplete
= false;
184 SourceLocation PrevScanLocation
;
185 SourceLocation PrevOrderedLocation
;
186 SourceLocation InnerTeamsRegionLoc
;
187 /// Reference to the taskgroup task_reduction reference expression.
188 Expr
*TaskgroupReductionRef
= nullptr;
189 llvm::DenseSet
<QualType
> MappedClassesQualTypes
;
190 SmallVector
<Expr
*, 4> InnerUsedAllocators
;
191 llvm::DenseSet
<CanonicalDeclPtr
<Decl
>> ImplicitTaskFirstprivates
;
192 /// List of globals marked as declare target link in this target region
193 /// (isOpenMPTargetExecutionDirective(Directive) == true).
194 llvm::SmallVector
<DeclRefExpr
*, 4> DeclareTargetLinkVarDecls
;
195 /// List of decls used in inclusive/exclusive clauses of the scan directive.
196 llvm::DenseSet
<CanonicalDeclPtr
<Decl
>> UsedInScanDirective
;
197 llvm::DenseMap
<CanonicalDeclPtr
<const Decl
>, UsesAllocatorsDeclKind
>
199 /// Data is required on creating capture fields for implicit
200 /// default first|private clause.
201 struct ImplicitDefaultFDInfoTy
{
203 const FieldDecl
*FD
= nullptr;
204 /// Nesting stack level
205 size_t StackLevel
= 0;
206 /// Capture variable decl.
207 VarDecl
*VD
= nullptr;
208 ImplicitDefaultFDInfoTy(const FieldDecl
*FD
, size_t StackLevel
,
210 : FD(FD
), StackLevel(StackLevel
), VD(VD
) {}
212 /// List of captured fields
213 llvm::SmallVector
<ImplicitDefaultFDInfoTy
, 8>
214 ImplicitDefaultFirstprivateFDs
;
215 Expr
*DeclareMapperVar
= nullptr;
216 SharingMapTy(OpenMPDirectiveKind DKind
, DeclarationNameInfo Name
,
217 Scope
*CurScope
, SourceLocation Loc
)
218 : Directive(DKind
), DirectiveName(Name
), CurScope(CurScope
),
220 SharingMapTy() = default;
223 using StackTy
= SmallVector
<SharingMapTy
, 4>;
225 /// Stack of used declaration and their data-sharing attributes.
226 DeclSAMapTy Threadprivates
;
227 const FunctionScopeInfo
*CurrentNonCapturingFunctionScope
= nullptr;
228 SmallVector
<std::pair
<StackTy
, const FunctionScopeInfo
*>, 4> Stack
;
229 /// true, if check for DSA must be from parent directive, false, if
230 /// from current directive.
231 OpenMPClauseKind ClauseKindMode
= OMPC_unknown
;
233 bool ForceCapturing
= false;
234 /// true if all the variables in the target executable directives must be
235 /// captured by reference.
236 bool ForceCaptureByReferenceInTargetExecutable
= false;
237 CriticalsWithHintsTy Criticals
;
238 unsigned IgnoredStackElements
= 0;
240 /// Iterators over the stack iterate in order from innermost to outermost
242 using const_iterator
= StackTy::const_reverse_iterator
;
243 const_iterator
begin() const {
244 return Stack
.empty() ? const_iterator()
245 : Stack
.back().first
.rbegin() + IgnoredStackElements
;
247 const_iterator
end() const {
248 return Stack
.empty() ? const_iterator() : Stack
.back().first
.rend();
250 using iterator
= StackTy::reverse_iterator
;
252 return Stack
.empty() ? iterator()
253 : Stack
.back().first
.rbegin() + IgnoredStackElements
;
256 return Stack
.empty() ? iterator() : Stack
.back().first
.rend();
259 // Convenience operations to get at the elements of the stack.
261 bool isStackEmpty() const {
262 return Stack
.empty() ||
263 Stack
.back().second
!= CurrentNonCapturingFunctionScope
||
264 Stack
.back().first
.size() <= IgnoredStackElements
;
266 size_t getStackSize() const {
267 return isStackEmpty() ? 0
268 : Stack
.back().first
.size() - IgnoredStackElements
;
271 SharingMapTy
*getTopOfStackOrNull() {
272 size_t Size
= getStackSize();
275 return &Stack
.back().first
[Size
- 1];
277 const SharingMapTy
*getTopOfStackOrNull() const {
278 return const_cast<DSAStackTy
&>(*this).getTopOfStackOrNull();
280 SharingMapTy
&getTopOfStack() {
281 assert(!isStackEmpty() && "no current directive");
282 return *getTopOfStackOrNull();
284 const SharingMapTy
&getTopOfStack() const {
285 return const_cast<DSAStackTy
&>(*this).getTopOfStack();
288 SharingMapTy
*getSecondOnStackOrNull() {
289 size_t Size
= getStackSize();
292 return &Stack
.back().first
[Size
- 2];
294 const SharingMapTy
*getSecondOnStackOrNull() const {
295 return const_cast<DSAStackTy
&>(*this).getSecondOnStackOrNull();
298 /// Get the stack element at a certain level (previously returned by
299 /// \c getNestingLevel).
301 /// Note that nesting levels count from outermost to innermost, and this is
302 /// the reverse of our iteration order where new inner levels are pushed at
303 /// the front of the stack.
304 SharingMapTy
&getStackElemAtLevel(unsigned Level
) {
305 assert(Level
< getStackSize() && "no such stack element");
306 return Stack
.back().first
[Level
];
308 const SharingMapTy
&getStackElemAtLevel(unsigned Level
) const {
309 return const_cast<DSAStackTy
&>(*this).getStackElemAtLevel(Level
);
312 DSAVarData
getDSA(const_iterator
&Iter
, ValueDecl
*D
) const;
314 /// Checks if the variable is a local for OpenMP region.
315 bool isOpenMPLocal(VarDecl
*D
, const_iterator Iter
) const;
317 /// Vector of previously declared requires directives
318 SmallVector
<const OMPRequiresDecl
*, 2> RequiresDecls
;
319 /// omp_allocator_handle_t type.
320 QualType OMPAllocatorHandleT
;
321 /// omp_depend_t type.
323 /// omp_event_handle_t type.
324 QualType OMPEventHandleT
;
325 /// omp_alloctrait_t type.
326 QualType OMPAlloctraitT
;
327 /// Expression for the predefined allocators.
328 Expr
*OMPPredefinedAllocators
[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
] = {
330 /// Vector of previously encountered target directives
331 SmallVector
<SourceLocation
, 2> TargetLocations
;
332 SourceLocation AtomicLocation
;
333 /// Vector of declare variant construct traits.
334 SmallVector
<llvm::omp::TraitProperty
, 8> ConstructTraits
;
337 explicit DSAStackTy(Sema
&S
) : SemaRef(S
) {}
339 /// Sets omp_allocator_handle_t type.
340 void setOMPAllocatorHandleT(QualType Ty
) { OMPAllocatorHandleT
= Ty
; }
341 /// Gets omp_allocator_handle_t type.
342 QualType
getOMPAllocatorHandleT() const { return OMPAllocatorHandleT
; }
343 /// Sets omp_alloctrait_t type.
344 void setOMPAlloctraitT(QualType Ty
) { OMPAlloctraitT
= Ty
; }
345 /// Gets omp_alloctrait_t type.
346 QualType
getOMPAlloctraitT() const { return OMPAlloctraitT
; }
347 /// Sets the given default allocator.
348 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
,
350 OMPPredefinedAllocators
[AllocatorKind
] = Allocator
;
352 /// Returns the specified default allocator.
353 Expr
*getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
) const {
354 return OMPPredefinedAllocators
[AllocatorKind
];
356 /// Sets omp_depend_t type.
357 void setOMPDependT(QualType Ty
) { OMPDependT
= Ty
; }
358 /// Gets omp_depend_t type.
359 QualType
getOMPDependT() const { return OMPDependT
; }
361 /// Sets omp_event_handle_t type.
362 void setOMPEventHandleT(QualType Ty
) { OMPEventHandleT
= Ty
; }
363 /// Gets omp_event_handle_t type.
364 QualType
getOMPEventHandleT() const { return OMPEventHandleT
; }
366 bool isClauseParsingMode() const { return ClauseKindMode
!= OMPC_unknown
; }
367 OpenMPClauseKind
getClauseParsingMode() const {
368 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
369 return ClauseKindMode
;
371 void setClauseParsingMode(OpenMPClauseKind K
) { ClauseKindMode
= K
; }
373 bool isBodyComplete() const {
374 const SharingMapTy
*Top
= getTopOfStackOrNull();
375 return Top
&& Top
->BodyComplete
;
377 void setBodyComplete() { getTopOfStack().BodyComplete
= true; }
379 bool isForceVarCapturing() const { return ForceCapturing
; }
380 void setForceVarCapturing(bool V
) { ForceCapturing
= V
; }
382 void setForceCaptureByReferenceInTargetExecutable(bool V
) {
383 ForceCaptureByReferenceInTargetExecutable
= V
;
385 bool isForceCaptureByReferenceInTargetExecutable() const {
386 return ForceCaptureByReferenceInTargetExecutable
;
389 void push(OpenMPDirectiveKind DKind
, const DeclarationNameInfo
&DirName
,
390 Scope
*CurScope
, SourceLocation Loc
) {
391 assert(!IgnoredStackElements
&&
392 "cannot change stack while ignoring elements");
394 Stack
.back().second
!= CurrentNonCapturingFunctionScope
)
395 Stack
.emplace_back(StackTy(), CurrentNonCapturingFunctionScope
);
396 Stack
.back().first
.emplace_back(DKind
, DirName
, CurScope
, Loc
);
397 Stack
.back().first
.back().DefaultAttrLoc
= Loc
;
401 assert(!IgnoredStackElements
&&
402 "cannot change stack while ignoring elements");
403 assert(!Stack
.back().first
.empty() &&
404 "Data-sharing attributes stack is empty!");
405 Stack
.back().first
.pop_back();
408 /// RAII object to temporarily leave the scope of a directive when we want to
409 /// logically operate in its parent.
410 class ParentDirectiveScope
{
415 ParentDirectiveScope(DSAStackTy
&Self
, bool Activate
)
416 : Self(Self
), Active(false) {
420 ~ParentDirectiveScope() { disable(); }
423 --Self
.IgnoredStackElements
;
429 ++Self
.IgnoredStackElements
;
435 /// Marks that we're started loop parsing.
437 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
438 "Expected loop-based directive.");
439 getTopOfStack().LoopStart
= true;
441 /// Start capturing of the variables in the loop context.
443 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
444 "Expected loop-based directive.");
445 getTopOfStack().LoopStart
= false;
447 /// true, if variables are captured, false otherwise.
448 bool isLoopStarted() const {
449 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
450 "Expected loop-based directive.");
451 return !getTopOfStack().LoopStart
;
453 /// Marks (or clears) declaration as possibly loop counter.
454 void resetPossibleLoopCounter(const Decl
*D
= nullptr) {
455 getTopOfStack().PossiblyLoopCounter
= D
? D
->getCanonicalDecl() : D
;
457 /// Gets the possible loop counter decl.
458 const Decl
*getPossiblyLoopCunter() const {
459 return getTopOfStack().PossiblyLoopCounter
;
461 /// Start new OpenMP region stack in new non-capturing function.
462 void pushFunction() {
463 assert(!IgnoredStackElements
&&
464 "cannot change stack while ignoring elements");
465 const FunctionScopeInfo
*CurFnScope
= SemaRef
.getCurFunction();
466 assert(!isa
<CapturingScopeInfo
>(CurFnScope
));
467 CurrentNonCapturingFunctionScope
= CurFnScope
;
469 /// Pop region stack for non-capturing function.
470 void popFunction(const FunctionScopeInfo
*OldFSI
) {
471 assert(!IgnoredStackElements
&&
472 "cannot change stack while ignoring elements");
473 if (!Stack
.empty() && Stack
.back().second
== OldFSI
) {
474 assert(Stack
.back().first
.empty());
477 CurrentNonCapturingFunctionScope
= nullptr;
478 for (const FunctionScopeInfo
*FSI
: llvm::reverse(SemaRef
.FunctionScopes
)) {
479 if (!isa
<CapturingScopeInfo
>(FSI
)) {
480 CurrentNonCapturingFunctionScope
= FSI
;
486 void addCriticalWithHint(const OMPCriticalDirective
*D
, llvm::APSInt Hint
) {
487 Criticals
.try_emplace(D
->getDirectiveName().getAsString(), D
, Hint
);
489 const std::pair
<const OMPCriticalDirective
*, llvm::APSInt
>
490 getCriticalWithHint(const DeclarationNameInfo
&Name
) const {
491 auto I
= Criticals
.find(Name
.getAsString());
492 if (I
!= Criticals
.end())
494 return std::make_pair(nullptr, llvm::APSInt());
496 /// If 'aligned' declaration for given variable \a D was not seen yet,
497 /// add it and return NULL; otherwise return previous occurrence's expression
499 const Expr
*addUniqueAligned(const ValueDecl
*D
, const Expr
*NewDE
);
500 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
501 /// add it and return NULL; otherwise return previous occurrence's expression
503 const Expr
*addUniqueNontemporal(const ValueDecl
*D
, const Expr
*NewDE
);
505 /// Register specified variable as loop control variable.
506 void addLoopControlVariable(const ValueDecl
*D
, VarDecl
*Capture
);
507 /// Check if the specified variable is a loop control variable for
509 /// \return The index of the loop control variable in the list of associated
510 /// for-loops (from outer to inner).
511 const LCDeclInfo
isLoopControlVariable(const ValueDecl
*D
) const;
512 /// Check if the specified variable is a loop control variable for
514 /// \return The index of the loop control variable in the list of associated
515 /// for-loops (from outer to inner).
516 const LCDeclInfo
isParentLoopControlVariable(const ValueDecl
*D
) const;
517 /// Check if the specified variable is a loop control variable for
519 /// \return The index of the loop control variable in the list of associated
520 /// for-loops (from outer to inner).
521 const LCDeclInfo
isLoopControlVariable(const ValueDecl
*D
,
522 unsigned Level
) const;
523 /// Get the loop control variable for the I-th loop (or nullptr) in
524 /// parent directive.
525 const ValueDecl
*getParentLoopControlVariable(unsigned I
) const;
527 /// Marks the specified decl \p D as used in scan directive.
528 void markDeclAsUsedInScanDirective(ValueDecl
*D
) {
529 if (SharingMapTy
*Stack
= getSecondOnStackOrNull())
530 Stack
->UsedInScanDirective
.insert(D
);
533 /// Checks if the specified declaration was used in the inner scan directive.
534 bool isUsedInScanDirective(ValueDecl
*D
) const {
535 if (const SharingMapTy
*Stack
= getTopOfStackOrNull())
536 return Stack
->UsedInScanDirective
.contains(D
);
540 /// Adds explicit data sharing attribute to the specified declaration.
541 void addDSA(const ValueDecl
*D
, const Expr
*E
, OpenMPClauseKind A
,
542 DeclRefExpr
*PrivateCopy
= nullptr, unsigned Modifier
= 0,
543 bool AppliedToPointee
= false);
545 /// Adds additional information for the reduction items with the reduction id
546 /// represented as an operator.
547 void addTaskgroupReductionData(const ValueDecl
*D
, SourceRange SR
,
548 BinaryOperatorKind BOK
);
549 /// Adds additional information for the reduction items with the reduction id
550 /// represented as reduction identifier.
551 void addTaskgroupReductionData(const ValueDecl
*D
, SourceRange SR
,
552 const Expr
*ReductionRef
);
553 /// Returns the location and reduction operation from the innermost parent
554 /// region for the given \p D.
556 getTopMostTaskgroupReductionData(const ValueDecl
*D
, SourceRange
&SR
,
557 BinaryOperatorKind
&BOK
,
558 Expr
*&TaskgroupDescriptor
) const;
559 /// Returns the location and reduction operation from the innermost parent
560 /// region for the given \p D.
562 getTopMostTaskgroupReductionData(const ValueDecl
*D
, SourceRange
&SR
,
563 const Expr
*&ReductionRef
,
564 Expr
*&TaskgroupDescriptor
) const;
565 /// Return reduction reference expression for the current taskgroup or
566 /// parallel/worksharing directives with task reductions.
567 Expr
*getTaskgroupReductionRef() const {
568 assert((getTopOfStack().Directive
== OMPD_taskgroup
||
569 ((isOpenMPParallelDirective(getTopOfStack().Directive
) ||
570 isOpenMPWorksharingDirective(getTopOfStack().Directive
)) &&
571 !isOpenMPSimdDirective(getTopOfStack().Directive
))) &&
572 "taskgroup reference expression requested for non taskgroup or "
573 "parallel/worksharing directive.");
574 return getTopOfStack().TaskgroupReductionRef
;
576 /// Checks if the given \p VD declaration is actually a taskgroup reduction
577 /// descriptor variable at the \p Level of OpenMP regions.
578 bool isTaskgroupReductionRef(const ValueDecl
*VD
, unsigned Level
) const {
579 return getStackElemAtLevel(Level
).TaskgroupReductionRef
&&
580 cast
<DeclRefExpr
>(getStackElemAtLevel(Level
).TaskgroupReductionRef
)
584 /// Returns data sharing attributes from top of the stack for the
585 /// specified declaration.
586 const DSAVarData
getTopDSA(ValueDecl
*D
, bool FromParent
);
587 /// Returns data-sharing attributes for the specified declaration.
588 const DSAVarData
getImplicitDSA(ValueDecl
*D
, bool FromParent
) const;
589 /// Returns data-sharing attributes for the specified declaration.
590 const DSAVarData
getImplicitDSA(ValueDecl
*D
, unsigned Level
) const;
591 /// Checks if the specified variables has data-sharing attributes which
592 /// match specified \a CPred predicate in any directive which matches \a DPred
596 const llvm::function_ref
<bool(OpenMPClauseKind
, bool,
597 DefaultDataSharingAttributes
)>
599 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
600 bool FromParent
) const;
601 /// Checks if the specified variables has data-sharing attributes which
602 /// match specified \a CPred predicate in any innermost directive which
603 /// matches \a DPred predicate.
605 hasInnermostDSA(ValueDecl
*D
,
606 const llvm::function_ref
<bool(OpenMPClauseKind
, bool)> CPred
,
607 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
608 bool FromParent
) const;
609 /// Checks if the specified variables has explicit data-sharing
610 /// attributes which match specified \a CPred predicate at the specified
613 hasExplicitDSA(const ValueDecl
*D
,
614 const llvm::function_ref
<bool(OpenMPClauseKind
, bool)> CPred
,
615 unsigned Level
, bool NotLastprivate
= false) const;
617 /// Returns true if the directive at level \Level matches in the
618 /// specified \a DPred predicate.
619 bool hasExplicitDirective(
620 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
621 unsigned Level
) const;
623 /// Finds a directive which matches specified \a DPred predicate.
625 const llvm::function_ref
<bool(
626 OpenMPDirectiveKind
, const DeclarationNameInfo
&, SourceLocation
)>
628 bool FromParent
) const;
630 /// Returns currently analyzed directive.
631 OpenMPDirectiveKind
getCurrentDirective() const {
632 const SharingMapTy
*Top
= getTopOfStackOrNull();
633 return Top
? Top
->Directive
: OMPD_unknown
;
635 /// Returns directive kind at specified level.
636 OpenMPDirectiveKind
getDirective(unsigned Level
) const {
637 assert(!isStackEmpty() && "No directive at specified level.");
638 return getStackElemAtLevel(Level
).Directive
;
640 /// Returns the capture region at the specified level.
641 OpenMPDirectiveKind
getCaptureRegion(unsigned Level
,
642 unsigned OpenMPCaptureLevel
) const {
643 SmallVector
<OpenMPDirectiveKind
, 4> CaptureRegions
;
644 getOpenMPCaptureRegions(CaptureRegions
, getDirective(Level
));
645 return CaptureRegions
[OpenMPCaptureLevel
];
647 /// Returns parent directive.
648 OpenMPDirectiveKind
getParentDirective() const {
649 const SharingMapTy
*Parent
= getSecondOnStackOrNull();
650 return Parent
? Parent
->Directive
: OMPD_unknown
;
653 /// Add requires decl to internal vector
654 void addRequiresDecl(OMPRequiresDecl
*RD
) { RequiresDecls
.push_back(RD
); }
656 /// Checks if the defined 'requires' directive has specified type of clause.
657 template <typename ClauseType
> bool hasRequiresDeclWithClause() const {
658 return llvm::any_of(RequiresDecls
, [](const OMPRequiresDecl
*D
) {
659 return llvm::any_of(D
->clauselists(), [](const OMPClause
*C
) {
660 return isa
<ClauseType
>(C
);
665 /// Checks for a duplicate clause amongst previously declared requires
667 bool hasDuplicateRequiresClause(ArrayRef
<OMPClause
*> ClauseList
) const {
668 bool IsDuplicate
= false;
669 for (OMPClause
*CNew
: ClauseList
) {
670 for (const OMPRequiresDecl
*D
: RequiresDecls
) {
671 for (const OMPClause
*CPrev
: D
->clauselists()) {
672 if (CNew
->getClauseKind() == CPrev
->getClauseKind()) {
673 SemaRef
.Diag(CNew
->getBeginLoc(),
674 diag::err_omp_requires_clause_redeclaration
)
675 << getOpenMPClauseName(CNew
->getClauseKind());
676 SemaRef
.Diag(CPrev
->getBeginLoc(),
677 diag::note_omp_requires_previous_clause
)
678 << getOpenMPClauseName(CPrev
->getClauseKind());
687 /// Add location of previously encountered target to internal vector
688 void addTargetDirLocation(SourceLocation LocStart
) {
689 TargetLocations
.push_back(LocStart
);
692 /// Add location for the first encountered atomicc directive.
693 void addAtomicDirectiveLoc(SourceLocation Loc
) {
694 if (AtomicLocation
.isInvalid())
695 AtomicLocation
= Loc
;
698 /// Returns the location of the first encountered atomic directive in the
700 SourceLocation
getAtomicDirectiveLoc() const { return AtomicLocation
; }
702 // Return previously encountered target region locations.
703 ArrayRef
<SourceLocation
> getEncounteredTargetLocs() const {
704 return TargetLocations
;
707 /// Set default data sharing attribute to none.
708 void setDefaultDSANone(SourceLocation Loc
) {
709 getTopOfStack().DefaultAttr
= DSA_none
;
710 getTopOfStack().DefaultAttrLoc
= Loc
;
712 /// Set default data sharing attribute to shared.
713 void setDefaultDSAShared(SourceLocation Loc
) {
714 getTopOfStack().DefaultAttr
= DSA_shared
;
715 getTopOfStack().DefaultAttrLoc
= Loc
;
717 /// Set default data sharing attribute to private.
718 void setDefaultDSAPrivate(SourceLocation Loc
) {
719 getTopOfStack().DefaultAttr
= DSA_private
;
720 getTopOfStack().DefaultAttrLoc
= Loc
;
722 /// Set default data sharing attribute to firstprivate.
723 void setDefaultDSAFirstPrivate(SourceLocation Loc
) {
724 getTopOfStack().DefaultAttr
= DSA_firstprivate
;
725 getTopOfStack().DefaultAttrLoc
= Loc
;
727 /// Set default data mapping attribute to Modifier:Kind
728 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M
,
729 OpenMPDefaultmapClauseKind Kind
, SourceLocation Loc
) {
730 DefaultmapInfo
&DMI
= getTopOfStack().DefaultmapMap
[Kind
];
731 DMI
.ImplicitBehavior
= M
;
734 /// Check whether the implicit-behavior has been set in defaultmap
735 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory
) {
736 if (VariableCategory
== OMPC_DEFAULTMAP_unknown
)
737 return getTopOfStack()
738 .DefaultmapMap
[OMPC_DEFAULTMAP_aggregate
]
739 .ImplicitBehavior
!= OMPC_DEFAULTMAP_MODIFIER_unknown
||
741 .DefaultmapMap
[OMPC_DEFAULTMAP_scalar
]
742 .ImplicitBehavior
!= OMPC_DEFAULTMAP_MODIFIER_unknown
||
744 .DefaultmapMap
[OMPC_DEFAULTMAP_pointer
]
745 .ImplicitBehavior
!= OMPC_DEFAULTMAP_MODIFIER_unknown
;
746 return getTopOfStack().DefaultmapMap
[VariableCategory
].ImplicitBehavior
!=
747 OMPC_DEFAULTMAP_MODIFIER_unknown
;
750 ArrayRef
<llvm::omp::TraitProperty
> getConstructTraits() {
751 return ConstructTraits
;
753 void handleConstructTrait(ArrayRef
<llvm::omp::TraitProperty
> Traits
,
756 ConstructTraits
.append(Traits
.begin(), Traits
.end());
758 for (llvm::omp::TraitProperty Trait
: llvm::reverse(Traits
)) {
759 llvm::omp::TraitProperty Top
= ConstructTraits
.pop_back_val();
760 assert(Top
== Trait
&& "Something left a trait on the stack!");
766 DefaultDataSharingAttributes
getDefaultDSA(unsigned Level
) const {
767 return getStackSize() <= Level
? DSA_unspecified
768 : getStackElemAtLevel(Level
).DefaultAttr
;
770 DefaultDataSharingAttributes
getDefaultDSA() const {
771 return isStackEmpty() ? DSA_unspecified
: getTopOfStack().DefaultAttr
;
773 SourceLocation
getDefaultDSALocation() const {
774 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc
;
776 OpenMPDefaultmapClauseModifier
777 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind
) const {
778 return isStackEmpty()
779 ? OMPC_DEFAULTMAP_MODIFIER_unknown
780 : getTopOfStack().DefaultmapMap
[Kind
].ImplicitBehavior
;
782 OpenMPDefaultmapClauseModifier
783 getDefaultmapModifierAtLevel(unsigned Level
,
784 OpenMPDefaultmapClauseKind Kind
) const {
785 return getStackElemAtLevel(Level
).DefaultmapMap
[Kind
].ImplicitBehavior
;
787 bool isDefaultmapCapturedByRef(unsigned Level
,
788 OpenMPDefaultmapClauseKind Kind
) const {
789 OpenMPDefaultmapClauseModifier M
=
790 getDefaultmapModifierAtLevel(Level
, Kind
);
791 if (Kind
== OMPC_DEFAULTMAP_scalar
|| Kind
== OMPC_DEFAULTMAP_pointer
) {
792 return (M
== OMPC_DEFAULTMAP_MODIFIER_alloc
) ||
793 (M
== OMPC_DEFAULTMAP_MODIFIER_to
) ||
794 (M
== OMPC_DEFAULTMAP_MODIFIER_from
) ||
795 (M
== OMPC_DEFAULTMAP_MODIFIER_tofrom
);
799 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M
,
800 OpenMPDefaultmapClauseKind Kind
) {
802 case OMPC_DEFAULTMAP_scalar
:
803 case OMPC_DEFAULTMAP_pointer
:
804 return (M
== OMPC_DEFAULTMAP_MODIFIER_unknown
) ||
805 (M
== OMPC_DEFAULTMAP_MODIFIER_firstprivate
) ||
806 (M
== OMPC_DEFAULTMAP_MODIFIER_default
);
807 case OMPC_DEFAULTMAP_aggregate
:
808 return M
== OMPC_DEFAULTMAP_MODIFIER_firstprivate
;
812 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
814 bool mustBeFirstprivateAtLevel(unsigned Level
,
815 OpenMPDefaultmapClauseKind Kind
) const {
816 OpenMPDefaultmapClauseModifier M
=
817 getDefaultmapModifierAtLevel(Level
, Kind
);
818 return mustBeFirstprivateBase(M
, Kind
);
820 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind
) const {
821 OpenMPDefaultmapClauseModifier M
= getDefaultmapModifier(Kind
);
822 return mustBeFirstprivateBase(M
, Kind
);
825 /// Checks if the specified variable is a threadprivate.
826 bool isThreadPrivate(VarDecl
*D
) {
827 const DSAVarData DVar
= getTopDSA(D
, false);
828 return isOpenMPThreadPrivate(DVar
.CKind
);
831 /// Marks current region as ordered (it has an 'ordered' clause).
832 void setOrderedRegion(bool IsOrdered
, const Expr
*Param
,
833 OMPOrderedClause
*Clause
) {
835 getTopOfStack().OrderedRegion
.emplace(Param
, Clause
);
837 getTopOfStack().OrderedRegion
.reset();
839 /// Returns true, if region is ordered (has associated 'ordered' clause),
840 /// false - otherwise.
841 bool isOrderedRegion() const {
842 if (const SharingMapTy
*Top
= getTopOfStackOrNull())
843 return Top
->OrderedRegion
.has_value();
846 /// Returns optional parameter for the ordered region.
847 std::pair
<const Expr
*, OMPOrderedClause
*> getOrderedRegionParam() const {
848 if (const SharingMapTy
*Top
= getTopOfStackOrNull())
849 if (Top
->OrderedRegion
)
850 return Top
->OrderedRegion
.value();
851 return std::make_pair(nullptr, nullptr);
853 /// Returns true, if parent region is ordered (has associated
854 /// 'ordered' clause), false - otherwise.
855 bool isParentOrderedRegion() const {
856 if (const SharingMapTy
*Parent
= getSecondOnStackOrNull())
857 return Parent
->OrderedRegion
.has_value();
860 /// Returns optional parameter for the ordered region.
861 std::pair
<const Expr
*, OMPOrderedClause
*>
862 getParentOrderedRegionParam() const {
863 if (const SharingMapTy
*Parent
= getSecondOnStackOrNull())
864 if (Parent
->OrderedRegion
)
865 return Parent
->OrderedRegion
.value();
866 return std::make_pair(nullptr, nullptr);
868 /// Marks current region as nowait (it has a 'nowait' clause).
869 void setNowaitRegion(bool IsNowait
= true) {
870 getTopOfStack().NowaitRegion
= IsNowait
;
872 /// Returns true, if parent region is nowait (has associated
873 /// 'nowait' clause), false - otherwise.
874 bool isParentNowaitRegion() const {
875 if (const SharingMapTy
*Parent
= getSecondOnStackOrNull())
876 return Parent
->NowaitRegion
;
879 /// Marks current region as untied (it has a 'untied' clause).
880 void setUntiedRegion(bool IsUntied
= true) {
881 getTopOfStack().UntiedRegion
= IsUntied
;
883 /// Return true if current region is untied.
884 bool isUntiedRegion() const {
885 const SharingMapTy
*Top
= getTopOfStackOrNull();
886 return Top
? Top
->UntiedRegion
: false;
888 /// Marks parent region as cancel region.
889 void setParentCancelRegion(bool Cancel
= true) {
890 if (SharingMapTy
*Parent
= getSecondOnStackOrNull())
891 Parent
->CancelRegion
|= Cancel
;
893 /// Return true if current region has inner cancel construct.
894 bool isCancelRegion() const {
895 const SharingMapTy
*Top
= getTopOfStackOrNull();
896 return Top
? Top
->CancelRegion
: false;
899 /// Mark that parent region already has scan directive.
900 void setParentHasScanDirective(SourceLocation Loc
) {
901 if (SharingMapTy
*Parent
= getSecondOnStackOrNull())
902 Parent
->PrevScanLocation
= Loc
;
904 /// Return true if current region has inner cancel construct.
905 bool doesParentHasScanDirective() const {
906 const SharingMapTy
*Top
= getSecondOnStackOrNull();
907 return Top
? Top
->PrevScanLocation
.isValid() : false;
909 /// Return true if current region has inner cancel construct.
910 SourceLocation
getParentScanDirectiveLoc() const {
911 const SharingMapTy
*Top
= getSecondOnStackOrNull();
912 return Top
? Top
->PrevScanLocation
: SourceLocation();
914 /// Mark that parent region already has ordered directive.
915 void setParentHasOrderedDirective(SourceLocation Loc
) {
916 if (SharingMapTy
*Parent
= getSecondOnStackOrNull())
917 Parent
->PrevOrderedLocation
= Loc
;
919 /// Return true if current region has inner ordered construct.
920 bool doesParentHasOrderedDirective() const {
921 const SharingMapTy
*Top
= getSecondOnStackOrNull();
922 return Top
? Top
->PrevOrderedLocation
.isValid() : false;
924 /// Returns the location of the previously specified ordered directive.
925 SourceLocation
getParentOrderedDirectiveLoc() const {
926 const SharingMapTy
*Top
= getSecondOnStackOrNull();
927 return Top
? Top
->PrevOrderedLocation
: SourceLocation();
930 /// Set collapse value for the region.
931 void setAssociatedLoops(unsigned Val
) {
932 getTopOfStack().AssociatedLoops
= Val
;
934 getTopOfStack().HasMutipleLoops
= true;
936 /// Return collapse value for region.
937 unsigned getAssociatedLoops() const {
938 const SharingMapTy
*Top
= getTopOfStackOrNull();
939 return Top
? Top
->AssociatedLoops
: 0;
941 /// Returns true if the construct is associated with multiple loops.
942 bool hasMutipleLoops() const {
943 const SharingMapTy
*Top
= getTopOfStackOrNull();
944 return Top
? Top
->HasMutipleLoops
: false;
947 /// Marks current target region as one with closely nested teams
949 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc
) {
950 if (SharingMapTy
*Parent
= getSecondOnStackOrNull())
951 Parent
->InnerTeamsRegionLoc
= TeamsRegionLoc
;
953 /// Returns true, if current region has closely nested teams region.
954 bool hasInnerTeamsRegion() const {
955 return getInnerTeamsRegionLoc().isValid();
957 /// Returns location of the nested teams region (if any).
958 SourceLocation
getInnerTeamsRegionLoc() const {
959 const SharingMapTy
*Top
= getTopOfStackOrNull();
960 return Top
? Top
->InnerTeamsRegionLoc
: SourceLocation();
963 Scope
*getCurScope() const {
964 const SharingMapTy
*Top
= getTopOfStackOrNull();
965 return Top
? Top
->CurScope
: nullptr;
967 void setContext(DeclContext
*DC
) { getTopOfStack().Context
= DC
; }
968 SourceLocation
getConstructLoc() const {
969 const SharingMapTy
*Top
= getTopOfStackOrNull();
970 return Top
? Top
->ConstructLoc
: SourceLocation();
973 /// Do the check specified in \a Check to all component lists and return true
974 /// if any issue is found.
975 bool checkMappableExprComponentListsForDecl(
976 const ValueDecl
*VD
, bool CurrentRegionOnly
,
977 const llvm::function_ref
<
978 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef
,
989 if (CurrentRegionOnly
)
994 for (; SI
!= SE
; ++SI
) {
995 auto MI
= SI
->MappedExprComponents
.find(VD
);
996 if (MI
!= SI
->MappedExprComponents
.end())
997 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L
:
998 MI
->second
.Components
)
999 if (Check(L
, MI
->second
.Kind
))
1005 /// Do the check specified in \a Check to all component lists at a given level
1006 /// and return true if any issue is found.
1007 bool checkMappableExprComponentListsForDeclAtLevel(
1008 const ValueDecl
*VD
, unsigned Level
,
1009 const llvm::function_ref
<
1010 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef
,
1013 if (getStackSize() <= Level
)
1016 const SharingMapTy
&StackElem
= getStackElemAtLevel(Level
);
1017 auto MI
= StackElem
.MappedExprComponents
.find(VD
);
1018 if (MI
!= StackElem
.MappedExprComponents
.end())
1019 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L
:
1020 MI
->second
.Components
)
1021 if (Check(L
, MI
->second
.Kind
))
1026 /// Create a new mappable expression component list associated with a given
1027 /// declaration and initialize it with the provided list of components.
1028 void addMappableExpressionComponents(
1029 const ValueDecl
*VD
,
1030 OMPClauseMappableExprCommon::MappableExprComponentListRef Components
,
1031 OpenMPClauseKind WhereFoundClauseKind
) {
1032 MappedExprComponentTy
&MEC
= getTopOfStack().MappedExprComponents
[VD
];
1033 // Create new entry and append the new components there.
1034 MEC
.Components
.resize(MEC
.Components
.size() + 1);
1035 MEC
.Components
.back().append(Components
.begin(), Components
.end());
1036 MEC
.Kind
= WhereFoundClauseKind
;
1039 unsigned getNestingLevel() const {
1040 assert(!isStackEmpty());
1041 return getStackSize() - 1;
1043 void addDoacrossDependClause(OMPDependClause
*C
,
1044 const OperatorOffsetTy
&OpsOffs
) {
1045 SharingMapTy
*Parent
= getSecondOnStackOrNull();
1046 assert(Parent
&& isOpenMPWorksharingDirective(Parent
->Directive
));
1047 Parent
->DoacrossDepends
.try_emplace(C
, OpsOffs
);
1049 llvm::iterator_range
<DoacrossDependMapTy::const_iterator
>
1050 getDoacrossDependClauses() const {
1051 const SharingMapTy
&StackElem
= getTopOfStack();
1052 if (isOpenMPWorksharingDirective(StackElem
.Directive
)) {
1053 const DoacrossDependMapTy
&Ref
= StackElem
.DoacrossDepends
;
1054 return llvm::make_range(Ref
.begin(), Ref
.end());
1056 return llvm::make_range(StackElem
.DoacrossDepends
.end(),
1057 StackElem
.DoacrossDepends
.end());
1060 // Store types of classes which have been explicitly mapped
1061 void addMappedClassesQualTypes(QualType QT
) {
1062 SharingMapTy
&StackElem
= getTopOfStack();
1063 StackElem
.MappedClassesQualTypes
.insert(QT
);
1066 // Return set of mapped classes types
1067 bool isClassPreviouslyMapped(QualType QT
) const {
1068 const SharingMapTy
&StackElem
= getTopOfStack();
1069 return StackElem
.MappedClassesQualTypes
.contains(QT
);
1072 /// Adds global declare target to the parent target region.
1073 void addToParentTargetRegionLinkGlobals(DeclRefExpr
*E
) {
1074 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1075 E
->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link
&&
1076 "Expected declare target link global.");
1077 for (auto &Elem
: *this) {
1078 if (isOpenMPTargetExecutionDirective(Elem
.Directive
)) {
1079 Elem
.DeclareTargetLinkVarDecls
.push_back(E
);
1085 /// Returns the list of globals with declare target link if current directive
1087 ArrayRef
<DeclRefExpr
*> getLinkGlobals() const {
1088 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1089 "Expected target executable directive.");
1090 return getTopOfStack().DeclareTargetLinkVarDecls
;
1093 /// Adds list of allocators expressions.
1094 void addInnerAllocatorExpr(Expr
*E
) {
1095 getTopOfStack().InnerUsedAllocators
.push_back(E
);
1097 /// Return list of used allocators.
1098 ArrayRef
<Expr
*> getInnerAllocators() const {
1099 return getTopOfStack().InnerUsedAllocators
;
1101 /// Marks the declaration as implicitly firstprivate nin the task-based
1103 void addImplicitTaskFirstprivate(unsigned Level
, Decl
*D
) {
1104 getStackElemAtLevel(Level
).ImplicitTaskFirstprivates
.insert(D
);
1106 /// Checks if the decl is implicitly firstprivate in the task-based region.
1107 bool isImplicitTaskFirstprivate(Decl
*D
) const {
1108 return getTopOfStack().ImplicitTaskFirstprivates
.contains(D
);
1111 /// Marks decl as used in uses_allocators clause as the allocator.
1112 void addUsesAllocatorsDecl(const Decl
*D
, UsesAllocatorsDeclKind Kind
) {
1113 getTopOfStack().UsesAllocatorsDecls
.try_emplace(D
, Kind
);
1115 /// Checks if specified decl is used in uses allocator clause as the
1117 Optional
<UsesAllocatorsDeclKind
> isUsesAllocatorsDecl(unsigned Level
,
1118 const Decl
*D
) const {
1119 const SharingMapTy
&StackElem
= getTopOfStack();
1120 auto I
= StackElem
.UsesAllocatorsDecls
.find(D
);
1121 if (I
== StackElem
.UsesAllocatorsDecls
.end())
1123 return I
->getSecond();
1125 Optional
<UsesAllocatorsDeclKind
> isUsesAllocatorsDecl(const Decl
*D
) const {
1126 const SharingMapTy
&StackElem
= getTopOfStack();
1127 auto I
= StackElem
.UsesAllocatorsDecls
.find(D
);
1128 if (I
== StackElem
.UsesAllocatorsDecls
.end())
1130 return I
->getSecond();
1133 void addDeclareMapperVarRef(Expr
*Ref
) {
1134 SharingMapTy
&StackElem
= getTopOfStack();
1135 StackElem
.DeclareMapperVar
= Ref
;
1137 const Expr
*getDeclareMapperVarRef() const {
1138 const SharingMapTy
*Top
= getTopOfStackOrNull();
1139 return Top
? Top
->DeclareMapperVar
: nullptr;
1141 /// get captured field from ImplicitDefaultFirstprivateFDs
1142 VarDecl
*getImplicitFDCapExprDecl(const FieldDecl
*FD
) const {
1143 const_iterator I
= begin();
1144 const_iterator EndI
= end();
1145 size_t StackLevel
= getStackSize();
1146 for (; I
!= EndI
; ++I
) {
1147 if (I
->DefaultAttr
== DSA_firstprivate
|| I
->DefaultAttr
== DSA_private
)
1151 assert((StackLevel
> 0 && I
!= EndI
) || (StackLevel
== 0 && I
== EndI
));
1154 for (const auto &IFD
: I
->ImplicitDefaultFirstprivateFDs
)
1155 if (IFD
.FD
== FD
&& IFD
.StackLevel
== StackLevel
)
1159 /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1160 bool isImplicitDefaultFirstprivateFD(VarDecl
*VD
) const {
1161 const_iterator I
= begin();
1162 const_iterator EndI
= end();
1163 for (; I
!= EndI
; ++I
)
1164 if (I
->DefaultAttr
== DSA_firstprivate
|| I
->DefaultAttr
== DSA_private
)
1168 for (const auto &IFD
: I
->ImplicitDefaultFirstprivateFDs
)
1173 /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1174 void addImplicitDefaultFirstprivateFD(const FieldDecl
*FD
, VarDecl
*VD
) {
1175 iterator I
= begin();
1176 const_iterator EndI
= end();
1177 size_t StackLevel
= getStackSize();
1178 for (; I
!= EndI
; ++I
) {
1179 if (I
->DefaultAttr
== DSA_private
|| I
->DefaultAttr
== DSA_firstprivate
) {
1180 I
->ImplicitDefaultFirstprivateFDs
.emplace_back(FD
, StackLevel
, VD
);
1185 assert((StackLevel
> 0 && I
!= EndI
) || (StackLevel
== 0 && I
== EndI
));
1189 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind
) {
1190 return isOpenMPParallelDirective(DKind
) || isOpenMPTeamsDirective(DKind
);
1193 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind
) {
1194 return isImplicitTaskingRegion(DKind
) || isOpenMPTaskingDirective(DKind
) ||
1195 DKind
== OMPD_unknown
;
1200 static const Expr
*getExprAsWritten(const Expr
*E
) {
1201 if (const auto *FE
= dyn_cast
<FullExpr
>(E
))
1202 E
= FE
->getSubExpr();
1204 if (const auto *MTE
= dyn_cast
<MaterializeTemporaryExpr
>(E
))
1205 E
= MTE
->getSubExpr();
1207 while (const auto *Binder
= dyn_cast
<CXXBindTemporaryExpr
>(E
))
1208 E
= Binder
->getSubExpr();
1210 if (const auto *ICE
= dyn_cast
<ImplicitCastExpr
>(E
))
1211 E
= ICE
->getSubExprAsWritten();
1212 return E
->IgnoreParens();
1215 static Expr
*getExprAsWritten(Expr
*E
) {
1216 return const_cast<Expr
*>(getExprAsWritten(const_cast<const Expr
*>(E
)));
1219 static const ValueDecl
*getCanonicalDecl(const ValueDecl
*D
) {
1220 if (const auto *CED
= dyn_cast
<OMPCapturedExprDecl
>(D
))
1221 if (const auto *ME
= dyn_cast
<MemberExpr
>(getExprAsWritten(CED
->getInit())))
1222 D
= ME
->getMemberDecl();
1223 const auto *VD
= dyn_cast
<VarDecl
>(D
);
1224 const auto *FD
= dyn_cast
<FieldDecl
>(D
);
1225 if (VD
!= nullptr) {
1226 VD
= VD
->getCanonicalDecl();
1230 FD
= FD
->getCanonicalDecl();
1236 static ValueDecl
*getCanonicalDecl(ValueDecl
*D
) {
1237 return const_cast<ValueDecl
*>(
1238 getCanonicalDecl(const_cast<const ValueDecl
*>(D
)));
1241 DSAStackTy::DSAVarData
DSAStackTy::getDSA(const_iterator
&Iter
,
1242 ValueDecl
*D
) const {
1243 D
= getCanonicalDecl(D
);
1244 auto *VD
= dyn_cast
<VarDecl
>(D
);
1245 const auto *FD
= dyn_cast
<FieldDecl
>(D
);
1247 if (Iter
== end()) {
1248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1249 // in a region but not in construct]
1250 // File-scope or namespace-scope variables referenced in called routines
1251 // in the region are shared unless they appear in a threadprivate
1253 if (VD
&& !VD
->isFunctionOrMethodVarDecl() && !isa
<ParmVarDecl
>(VD
))
1254 DVar
.CKind
= OMPC_shared
;
1256 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1257 // in a region but not in construct]
1258 // Variables with static storage duration that are declared in called
1259 // routines in the region are shared.
1260 if (VD
&& VD
->hasGlobalStorage())
1261 DVar
.CKind
= OMPC_shared
;
1263 // Non-static data members are shared by default.
1265 DVar
.CKind
= OMPC_shared
;
1270 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1271 // in a Construct, C/C++, predetermined, p.1]
1272 // Variables with automatic storage duration that are declared in a scope
1273 // inside the construct are private.
1274 if (VD
&& isOpenMPLocal(VD
, Iter
) && VD
->isLocalVarDecl() &&
1275 (VD
->getStorageClass() == SC_Auto
|| VD
->getStorageClass() == SC_None
)) {
1276 DVar
.CKind
= OMPC_private
;
1280 DVar
.DKind
= Iter
->Directive
;
1281 // Explicitly specified attributes and local variables with predetermined
1283 if (Iter
->SharingMap
.count(D
)) {
1284 const DSAInfo
&Data
= Iter
->SharingMap
.lookup(D
);
1285 DVar
.RefExpr
= Data
.RefExpr
.getPointer();
1286 DVar
.PrivateCopy
= Data
.PrivateCopy
;
1287 DVar
.CKind
= Data
.Attributes
;
1288 DVar
.ImplicitDSALoc
= Iter
->DefaultAttrLoc
;
1289 DVar
.Modifier
= Data
.Modifier
;
1290 DVar
.AppliedToPointee
= Data
.AppliedToPointee
;
1294 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1295 // in a Construct, C/C++, implicitly determined, p.1]
1296 // In a parallel or task construct, the data-sharing attributes of these
1297 // variables are determined by the default clause, if present.
1298 switch (Iter
->DefaultAttr
) {
1300 DVar
.CKind
= OMPC_shared
;
1301 DVar
.ImplicitDSALoc
= Iter
->DefaultAttrLoc
;
1305 case DSA_firstprivate
:
1306 if (VD
&& VD
->getStorageDuration() == SD_Static
&&
1307 VD
->getDeclContext()->isFileContext()) {
1308 DVar
.CKind
= OMPC_unknown
;
1310 DVar
.CKind
= OMPC_firstprivate
;
1312 DVar
.ImplicitDSALoc
= Iter
->DefaultAttrLoc
;
1315 // each variable with static storage duration that is declared
1316 // in a namespace or global scope and referenced in the construct,
1317 // and that does not have a predetermined data-sharing attribute
1318 if (VD
&& VD
->getStorageDuration() == SD_Static
&&
1319 VD
->getDeclContext()->isFileContext()) {
1320 DVar
.CKind
= OMPC_unknown
;
1322 DVar
.CKind
= OMPC_private
;
1324 DVar
.ImplicitDSALoc
= Iter
->DefaultAttrLoc
;
1326 case DSA_unspecified
:
1327 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1328 // in a Construct, implicitly determined, p.2]
1329 // In a parallel construct, if no default clause is present, these
1330 // variables are shared.
1331 DVar
.ImplicitDSALoc
= Iter
->DefaultAttrLoc
;
1332 if ((isOpenMPParallelDirective(DVar
.DKind
) &&
1333 !isOpenMPTaskLoopDirective(DVar
.DKind
)) ||
1334 isOpenMPTeamsDirective(DVar
.DKind
)) {
1335 DVar
.CKind
= OMPC_shared
;
1339 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1340 // in a Construct, implicitly determined, p.4]
1341 // In a task construct, if no default clause is present, a variable that in
1342 // the enclosing context is determined to be shared by all implicit tasks
1343 // bound to the current team is shared.
1344 if (isOpenMPTaskingDirective(DVar
.DKind
)) {
1345 DSAVarData DVarTemp
;
1346 const_iterator I
= Iter
, E
= end();
1349 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1350 // Referenced in a Construct, implicitly determined, p.6]
1351 // In a task construct, if no default clause is present, a variable
1352 // whose data-sharing attribute is not determined by the rules above is
1354 DVarTemp
= getDSA(I
, D
);
1355 if (DVarTemp
.CKind
!= OMPC_shared
) {
1356 DVar
.RefExpr
= nullptr;
1357 DVar
.CKind
= OMPC_firstprivate
;
1360 } while (I
!= E
&& !isImplicitTaskingRegion(I
->Directive
));
1362 (DVarTemp
.CKind
== OMPC_unknown
) ? OMPC_firstprivate
: OMPC_shared
;
1366 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1367 // in a Construct, implicitly determined, p.3]
1368 // For constructs other than task, if no default clause is present, these
1369 // variables inherit their data-sharing attributes from the enclosing
1371 return getDSA(++Iter
, D
);
1374 const Expr
*DSAStackTy::addUniqueAligned(const ValueDecl
*D
,
1375 const Expr
*NewDE
) {
1376 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1377 D
= getCanonicalDecl(D
);
1378 SharingMapTy
&StackElem
= getTopOfStack();
1379 auto It
= StackElem
.AlignedMap
.find(D
);
1380 if (It
== StackElem
.AlignedMap
.end()) {
1381 assert(NewDE
&& "Unexpected nullptr expr to be added into aligned map");
1382 StackElem
.AlignedMap
[D
] = NewDE
;
1385 assert(It
->second
&& "Unexpected nullptr expr in the aligned map");
1389 const Expr
*DSAStackTy::addUniqueNontemporal(const ValueDecl
*D
,
1390 const Expr
*NewDE
) {
1391 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1392 D
= getCanonicalDecl(D
);
1393 SharingMapTy
&StackElem
= getTopOfStack();
1394 auto It
= StackElem
.NontemporalMap
.find(D
);
1395 if (It
== StackElem
.NontemporalMap
.end()) {
1396 assert(NewDE
&& "Unexpected nullptr expr to be added into aligned map");
1397 StackElem
.NontemporalMap
[D
] = NewDE
;
1400 assert(It
->second
&& "Unexpected nullptr expr in the aligned map");
1404 void DSAStackTy::addLoopControlVariable(const ValueDecl
*D
, VarDecl
*Capture
) {
1405 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1406 D
= getCanonicalDecl(D
);
1407 SharingMapTy
&StackElem
= getTopOfStack();
1408 StackElem
.LCVMap
.try_emplace(
1409 D
, LCDeclInfo(StackElem
.LCVMap
.size() + 1, Capture
));
1412 const DSAStackTy::LCDeclInfo
1413 DSAStackTy::isLoopControlVariable(const ValueDecl
*D
) const {
1414 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1415 D
= getCanonicalDecl(D
);
1416 const SharingMapTy
&StackElem
= getTopOfStack();
1417 auto It
= StackElem
.LCVMap
.find(D
);
1418 if (It
!= StackElem
.LCVMap
.end())
1420 return {0, nullptr};
1423 const DSAStackTy::LCDeclInfo
1424 DSAStackTy::isLoopControlVariable(const ValueDecl
*D
, unsigned Level
) const {
1425 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1426 D
= getCanonicalDecl(D
);
1427 for (unsigned I
= Level
+ 1; I
> 0; --I
) {
1428 const SharingMapTy
&StackElem
= getStackElemAtLevel(I
- 1);
1429 auto It
= StackElem
.LCVMap
.find(D
);
1430 if (It
!= StackElem
.LCVMap
.end())
1433 return {0, nullptr};
1436 const DSAStackTy::LCDeclInfo
1437 DSAStackTy::isParentLoopControlVariable(const ValueDecl
*D
) const {
1438 const SharingMapTy
*Parent
= getSecondOnStackOrNull();
1439 assert(Parent
&& "Data-sharing attributes stack is empty");
1440 D
= getCanonicalDecl(D
);
1441 auto It
= Parent
->LCVMap
.find(D
);
1442 if (It
!= Parent
->LCVMap
.end())
1444 return {0, nullptr};
1447 const ValueDecl
*DSAStackTy::getParentLoopControlVariable(unsigned I
) const {
1448 const SharingMapTy
*Parent
= getSecondOnStackOrNull();
1449 assert(Parent
&& "Data-sharing attributes stack is empty");
1450 if (Parent
->LCVMap
.size() < I
)
1452 for (const auto &Pair
: Parent
->LCVMap
)
1453 if (Pair
.second
.first
== I
)
1458 void DSAStackTy::addDSA(const ValueDecl
*D
, const Expr
*E
, OpenMPClauseKind A
,
1459 DeclRefExpr
*PrivateCopy
, unsigned Modifier
,
1460 bool AppliedToPointee
) {
1461 D
= getCanonicalDecl(D
);
1462 if (A
== OMPC_threadprivate
) {
1463 DSAInfo
&Data
= Threadprivates
[D
];
1464 Data
.Attributes
= A
;
1465 Data
.RefExpr
.setPointer(E
);
1466 Data
.PrivateCopy
= nullptr;
1467 Data
.Modifier
= Modifier
;
1469 DSAInfo
&Data
= getTopOfStack().SharingMap
[D
];
1470 assert(Data
.Attributes
== OMPC_unknown
|| (A
== Data
.Attributes
) ||
1471 (A
== OMPC_firstprivate
&& Data
.Attributes
== OMPC_lastprivate
) ||
1472 (A
== OMPC_lastprivate
&& Data
.Attributes
== OMPC_firstprivate
) ||
1473 (isLoopControlVariable(D
).first
&& A
== OMPC_private
));
1474 Data
.Modifier
= Modifier
;
1475 if (A
== OMPC_lastprivate
&& Data
.Attributes
== OMPC_firstprivate
) {
1476 Data
.RefExpr
.setInt(/*IntVal=*/true);
1479 const bool IsLastprivate
=
1480 A
== OMPC_lastprivate
|| Data
.Attributes
== OMPC_lastprivate
;
1481 Data
.Attributes
= A
;
1482 Data
.RefExpr
.setPointerAndInt(E
, IsLastprivate
);
1483 Data
.PrivateCopy
= PrivateCopy
;
1484 Data
.AppliedToPointee
= AppliedToPointee
;
1486 DSAInfo
&Data
= getTopOfStack().SharingMap
[PrivateCopy
->getDecl()];
1487 Data
.Modifier
= Modifier
;
1488 Data
.Attributes
= A
;
1489 Data
.RefExpr
.setPointerAndInt(PrivateCopy
, IsLastprivate
);
1490 Data
.PrivateCopy
= nullptr;
1491 Data
.AppliedToPointee
= AppliedToPointee
;
1496 /// Build a variable declaration for OpenMP loop iteration variable.
1497 static VarDecl
*buildVarDecl(Sema
&SemaRef
, SourceLocation Loc
, QualType Type
,
1498 StringRef Name
, const AttrVec
*Attrs
= nullptr,
1499 DeclRefExpr
*OrigRef
= nullptr) {
1500 DeclContext
*DC
= SemaRef
.CurContext
;
1501 IdentifierInfo
*II
= &SemaRef
.PP
.getIdentifierTable().get(Name
);
1502 TypeSourceInfo
*TInfo
= SemaRef
.Context
.getTrivialTypeSourceInfo(Type
, Loc
);
1504 VarDecl::Create(SemaRef
.Context
, DC
, Loc
, Loc
, II
, Type
, TInfo
, SC_None
);
1506 for (specific_attr_iterator
<AlignedAttr
> I(Attrs
->begin()), E(Attrs
->end());
1510 Decl
->setImplicit();
1513 OMPReferencedVarAttr::CreateImplicit(SemaRef
.Context
, OrigRef
));
1518 static DeclRefExpr
*buildDeclRefExpr(Sema
&S
, VarDecl
*D
, QualType Ty
,
1520 bool RefersToCapture
= false) {
1522 D
->markUsed(S
.Context
);
1523 return DeclRefExpr::Create(S
.getASTContext(), NestedNameSpecifierLoc(),
1524 SourceLocation(), D
, RefersToCapture
, Loc
, Ty
,
1528 void DSAStackTy::addTaskgroupReductionData(const ValueDecl
*D
, SourceRange SR
,
1529 BinaryOperatorKind BOK
) {
1530 D
= getCanonicalDecl(D
);
1531 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1533 getTopOfStack().SharingMap
[D
].Attributes
== OMPC_reduction
&&
1534 "Additional reduction info may be specified only for reduction items.");
1535 ReductionData
&ReductionData
= getTopOfStack().ReductionMap
[D
];
1536 assert(ReductionData
.ReductionRange
.isInvalid() &&
1537 (getTopOfStack().Directive
== OMPD_taskgroup
||
1538 ((isOpenMPParallelDirective(getTopOfStack().Directive
) ||
1539 isOpenMPWorksharingDirective(getTopOfStack().Directive
)) &&
1540 !isOpenMPSimdDirective(getTopOfStack().Directive
))) &&
1541 "Additional reduction info may be specified only once for reduction "
1543 ReductionData
.set(BOK
, SR
);
1544 Expr
*&TaskgroupReductionRef
= getTopOfStack().TaskgroupReductionRef
;
1545 if (!TaskgroupReductionRef
) {
1546 VarDecl
*VD
= buildVarDecl(SemaRef
, SR
.getBegin(),
1547 SemaRef
.Context
.VoidPtrTy
, ".task_red.");
1548 TaskgroupReductionRef
=
1549 buildDeclRefExpr(SemaRef
, VD
, SemaRef
.Context
.VoidPtrTy
, SR
.getBegin());
1553 void DSAStackTy::addTaskgroupReductionData(const ValueDecl
*D
, SourceRange SR
,
1554 const Expr
*ReductionRef
) {
1555 D
= getCanonicalDecl(D
);
1556 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1558 getTopOfStack().SharingMap
[D
].Attributes
== OMPC_reduction
&&
1559 "Additional reduction info may be specified only for reduction items.");
1560 ReductionData
&ReductionData
= getTopOfStack().ReductionMap
[D
];
1561 assert(ReductionData
.ReductionRange
.isInvalid() &&
1562 (getTopOfStack().Directive
== OMPD_taskgroup
||
1563 ((isOpenMPParallelDirective(getTopOfStack().Directive
) ||
1564 isOpenMPWorksharingDirective(getTopOfStack().Directive
)) &&
1565 !isOpenMPSimdDirective(getTopOfStack().Directive
))) &&
1566 "Additional reduction info may be specified only once for reduction "
1568 ReductionData
.set(ReductionRef
, SR
);
1569 Expr
*&TaskgroupReductionRef
= getTopOfStack().TaskgroupReductionRef
;
1570 if (!TaskgroupReductionRef
) {
1571 VarDecl
*VD
= buildVarDecl(SemaRef
, SR
.getBegin(),
1572 SemaRef
.Context
.VoidPtrTy
, ".task_red.");
1573 TaskgroupReductionRef
=
1574 buildDeclRefExpr(SemaRef
, VD
, SemaRef
.Context
.VoidPtrTy
, SR
.getBegin());
1578 const DSAStackTy::DSAVarData
DSAStackTy::getTopMostTaskgroupReductionData(
1579 const ValueDecl
*D
, SourceRange
&SR
, BinaryOperatorKind
&BOK
,
1580 Expr
*&TaskgroupDescriptor
) const {
1581 D
= getCanonicalDecl(D
);
1582 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1583 for (const_iterator I
= begin() + 1, E
= end(); I
!= E
; ++I
) {
1584 const DSAInfo
&Data
= I
->SharingMap
.lookup(D
);
1585 if (Data
.Attributes
!= OMPC_reduction
||
1586 Data
.Modifier
!= OMPC_REDUCTION_task
)
1588 const ReductionData
&ReductionData
= I
->ReductionMap
.lookup(D
);
1589 if (!ReductionData
.ReductionOp
||
1590 ReductionData
.ReductionOp
.is
<const Expr
*>())
1591 return DSAVarData();
1592 SR
= ReductionData
.ReductionRange
;
1593 BOK
= ReductionData
.ReductionOp
.get
<ReductionData::BOKPtrType
>();
1594 assert(I
->TaskgroupReductionRef
&& "taskgroup reduction reference "
1595 "expression for the descriptor is not "
1597 TaskgroupDescriptor
= I
->TaskgroupReductionRef
;
1598 return DSAVarData(I
->Directive
, OMPC_reduction
, Data
.RefExpr
.getPointer(),
1599 Data
.PrivateCopy
, I
->DefaultAttrLoc
, OMPC_REDUCTION_task
,
1600 /*AppliedToPointee=*/false);
1602 return DSAVarData();
1605 const DSAStackTy::DSAVarData
DSAStackTy::getTopMostTaskgroupReductionData(
1606 const ValueDecl
*D
, SourceRange
&SR
, const Expr
*&ReductionRef
,
1607 Expr
*&TaskgroupDescriptor
) const {
1608 D
= getCanonicalDecl(D
);
1609 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1610 for (const_iterator I
= begin() + 1, E
= end(); I
!= E
; ++I
) {
1611 const DSAInfo
&Data
= I
->SharingMap
.lookup(D
);
1612 if (Data
.Attributes
!= OMPC_reduction
||
1613 Data
.Modifier
!= OMPC_REDUCTION_task
)
1615 const ReductionData
&ReductionData
= I
->ReductionMap
.lookup(D
);
1616 if (!ReductionData
.ReductionOp
||
1617 !ReductionData
.ReductionOp
.is
<const Expr
*>())
1618 return DSAVarData();
1619 SR
= ReductionData
.ReductionRange
;
1620 ReductionRef
= ReductionData
.ReductionOp
.get
<const Expr
*>();
1621 assert(I
->TaskgroupReductionRef
&& "taskgroup reduction reference "
1622 "expression for the descriptor is not "
1624 TaskgroupDescriptor
= I
->TaskgroupReductionRef
;
1625 return DSAVarData(I
->Directive
, OMPC_reduction
, Data
.RefExpr
.getPointer(),
1626 Data
.PrivateCopy
, I
->DefaultAttrLoc
, OMPC_REDUCTION_task
,
1627 /*AppliedToPointee=*/false);
1629 return DSAVarData();
1632 bool DSAStackTy::isOpenMPLocal(VarDecl
*D
, const_iterator I
) const {
1633 D
= D
->getCanonicalDecl();
1634 for (const_iterator E
= end(); I
!= E
; ++I
) {
1635 if (isImplicitOrExplicitTaskingRegion(I
->Directive
) ||
1636 isOpenMPTargetExecutionDirective(I
->Directive
)) {
1638 Scope
*TopScope
= I
->CurScope
->getParent();
1639 Scope
*CurScope
= getCurScope();
1640 while (CurScope
&& CurScope
!= TopScope
&& !CurScope
->isDeclScope(D
))
1641 CurScope
= CurScope
->getParent();
1642 return CurScope
!= TopScope
;
1644 for (DeclContext
*DC
= D
->getDeclContext(); DC
; DC
= DC
->getParent())
1645 if (I
->Context
== DC
)
1653 static bool isConstNotMutableType(Sema
&SemaRef
, QualType Type
,
1654 bool AcceptIfMutable
= true,
1655 bool *IsClassType
= nullptr) {
1656 ASTContext
&Context
= SemaRef
.getASTContext();
1657 Type
= Type
.getNonReferenceType().getCanonicalType();
1658 bool IsConstant
= Type
.isConstant(Context
);
1659 Type
= Context
.getBaseElementType(Type
);
1660 const CXXRecordDecl
*RD
= AcceptIfMutable
&& SemaRef
.getLangOpts().CPlusPlus
1661 ? Type
->getAsCXXRecordDecl()
1663 if (const auto *CTSD
= dyn_cast_or_null
<ClassTemplateSpecializationDecl
>(RD
))
1664 if (const ClassTemplateDecl
*CTD
= CTSD
->getSpecializedTemplate())
1665 RD
= CTD
->getTemplatedDecl();
1668 return IsConstant
&& !(SemaRef
.getLangOpts().CPlusPlus
&& RD
&&
1669 RD
->hasDefinition() && RD
->hasMutableFields());
1672 static bool rejectConstNotMutableType(Sema
&SemaRef
, const ValueDecl
*D
,
1673 QualType Type
, OpenMPClauseKind CKind
,
1674 SourceLocation ELoc
,
1675 bool AcceptIfMutable
= true,
1676 bool ListItemNotVar
= false) {
1677 ASTContext
&Context
= SemaRef
.getASTContext();
1679 if (isConstNotMutableType(SemaRef
, Type
, AcceptIfMutable
, &IsClassType
)) {
1680 unsigned Diag
= ListItemNotVar
? diag::err_omp_const_list_item
1681 : IsClassType
? diag::err_omp_const_not_mutable_variable
1682 : diag::err_omp_const_variable
;
1683 SemaRef
.Diag(ELoc
, Diag
) << getOpenMPClauseName(CKind
);
1684 if (!ListItemNotVar
&& D
) {
1685 const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
);
1686 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
1687 VarDecl::DeclarationOnly
;
1688 SemaRef
.Diag(D
->getLocation(),
1689 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
1697 const DSAStackTy::DSAVarData
DSAStackTy::getTopDSA(ValueDecl
*D
,
1699 D
= getCanonicalDecl(D
);
1702 auto *VD
= dyn_cast
<VarDecl
>(D
);
1703 auto TI
= Threadprivates
.find(D
);
1704 if (TI
!= Threadprivates
.end()) {
1705 DVar
.RefExpr
= TI
->getSecond().RefExpr
.getPointer();
1706 DVar
.CKind
= OMPC_threadprivate
;
1707 DVar
.Modifier
= TI
->getSecond().Modifier
;
1710 if (VD
&& VD
->hasAttr
<OMPThreadPrivateDeclAttr
>()) {
1711 DVar
.RefExpr
= buildDeclRefExpr(
1712 SemaRef
, VD
, D
->getType().getNonReferenceType(),
1713 VD
->getAttr
<OMPThreadPrivateDeclAttr
>()->getLocation());
1714 DVar
.CKind
= OMPC_threadprivate
;
1715 addDSA(D
, DVar
.RefExpr
, OMPC_threadprivate
);
1718 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1719 // in a Construct, C/C++, predetermined, p.1]
1720 // Variables appearing in threadprivate directives are threadprivate.
1721 if ((VD
&& VD
->getTLSKind() != VarDecl::TLS_None
&&
1722 !(VD
->hasAttr
<OMPThreadPrivateDeclAttr
>() &&
1723 SemaRef
.getLangOpts().OpenMPUseTLS
&&
1724 SemaRef
.getASTContext().getTargetInfo().isTLSSupported())) ||
1725 (VD
&& VD
->getStorageClass() == SC_Register
&&
1726 VD
->hasAttr
<AsmLabelAttr
>() && !VD
->isLocalVarDecl())) {
1727 DVar
.RefExpr
= buildDeclRefExpr(
1728 SemaRef
, VD
, D
->getType().getNonReferenceType(), D
->getLocation());
1729 DVar
.CKind
= OMPC_threadprivate
;
1730 addDSA(D
, DVar
.RefExpr
, OMPC_threadprivate
);
1733 if (SemaRef
.getLangOpts().OpenMPCUDAMode
&& VD
&&
1734 VD
->isLocalVarDeclOrParm() && !isStackEmpty() &&
1735 !isLoopControlVariable(D
).first
) {
1736 const_iterator IterTarget
=
1737 std::find_if(begin(), end(), [](const SharingMapTy
&Data
) {
1738 return isOpenMPTargetExecutionDirective(Data
.Directive
);
1740 if (IterTarget
!= end()) {
1741 const_iterator ParentIterTarget
= IterTarget
+ 1;
1742 for (const_iterator Iter
= begin(); Iter
!= ParentIterTarget
; ++Iter
) {
1743 if (isOpenMPLocal(VD
, Iter
)) {
1745 buildDeclRefExpr(SemaRef
, VD
, D
->getType().getNonReferenceType(),
1747 DVar
.CKind
= OMPC_threadprivate
;
1751 if (!isClauseParsingMode() || IterTarget
!= begin()) {
1752 auto DSAIter
= IterTarget
->SharingMap
.find(D
);
1753 if (DSAIter
!= IterTarget
->SharingMap
.end() &&
1754 isOpenMPPrivate(DSAIter
->getSecond().Attributes
)) {
1755 DVar
.RefExpr
= DSAIter
->getSecond().RefExpr
.getPointer();
1756 DVar
.CKind
= OMPC_threadprivate
;
1759 const_iterator End
= end();
1760 if (!SemaRef
.isOpenMPCapturedByRef(D
,
1761 std::distance(ParentIterTarget
, End
),
1762 /*OpenMPCaptureLevel=*/0)) {
1764 buildDeclRefExpr(SemaRef
, VD
, D
->getType().getNonReferenceType(),
1765 IterTarget
->ConstructLoc
);
1766 DVar
.CKind
= OMPC_threadprivate
;
1774 // Not in OpenMP execution region and top scope was already checked.
1777 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1778 // in a Construct, C/C++, predetermined, p.4]
1779 // Static data members are shared.
1780 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1781 // in a Construct, C/C++, predetermined, p.7]
1782 // Variables with static storage duration that are declared in a scope
1783 // inside the construct are shared.
1784 if (VD
&& VD
->isStaticDataMember()) {
1785 // Check for explicitly specified attributes.
1786 const_iterator I
= begin();
1787 const_iterator EndI
= end();
1788 if (FromParent
&& I
!= EndI
)
1791 auto It
= I
->SharingMap
.find(D
);
1792 if (It
!= I
->SharingMap
.end()) {
1793 const DSAInfo
&Data
= It
->getSecond();
1794 DVar
.RefExpr
= Data
.RefExpr
.getPointer();
1795 DVar
.PrivateCopy
= Data
.PrivateCopy
;
1796 DVar
.CKind
= Data
.Attributes
;
1797 DVar
.ImplicitDSALoc
= I
->DefaultAttrLoc
;
1798 DVar
.DKind
= I
->Directive
;
1799 DVar
.Modifier
= Data
.Modifier
;
1800 DVar
.AppliedToPointee
= Data
.AppliedToPointee
;
1805 DVar
.CKind
= OMPC_shared
;
1809 auto &&MatchesAlways
= [](OpenMPDirectiveKind
) { return true; };
1810 // The predetermined shared attribute for const-qualified types having no
1811 // mutable members was removed after OpenMP 3.1.
1812 if (SemaRef
.LangOpts
.OpenMP
<= 31) {
1813 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1814 // in a Construct, C/C++, predetermined, p.6]
1815 // Variables with const qualified type having no mutable member are
1817 if (isConstNotMutableType(SemaRef
, D
->getType())) {
1818 // Variables with const-qualified type having no mutable member may be
1819 // listed in a firstprivate clause, even if they are static data members.
1820 DSAVarData DVarTemp
= hasInnermostDSA(
1822 [](OpenMPClauseKind C
, bool) {
1823 return C
== OMPC_firstprivate
|| C
== OMPC_shared
;
1825 MatchesAlways
, FromParent
);
1826 if (DVarTemp
.CKind
!= OMPC_unknown
&& DVarTemp
.RefExpr
)
1829 DVar
.CKind
= OMPC_shared
;
1834 // Explicitly specified attributes and local variables with predetermined
1836 const_iterator I
= begin();
1837 const_iterator EndI
= end();
1838 if (FromParent
&& I
!= EndI
)
1842 auto It
= I
->SharingMap
.find(D
);
1843 if (It
!= I
->SharingMap
.end()) {
1844 const DSAInfo
&Data
= It
->getSecond();
1845 DVar
.RefExpr
= Data
.RefExpr
.getPointer();
1846 DVar
.PrivateCopy
= Data
.PrivateCopy
;
1847 DVar
.CKind
= Data
.Attributes
;
1848 DVar
.ImplicitDSALoc
= I
->DefaultAttrLoc
;
1849 DVar
.DKind
= I
->Directive
;
1850 DVar
.Modifier
= Data
.Modifier
;
1851 DVar
.AppliedToPointee
= Data
.AppliedToPointee
;
1857 const DSAStackTy::DSAVarData
DSAStackTy::getImplicitDSA(ValueDecl
*D
,
1858 bool FromParent
) const {
1859 if (isStackEmpty()) {
1861 return getDSA(I
, D
);
1863 D
= getCanonicalDecl(D
);
1864 const_iterator StartI
= begin();
1865 const_iterator EndI
= end();
1866 if (FromParent
&& StartI
!= EndI
)
1868 return getDSA(StartI
, D
);
1871 const DSAStackTy::DSAVarData
DSAStackTy::getImplicitDSA(ValueDecl
*D
,
1872 unsigned Level
) const {
1873 if (getStackSize() <= Level
)
1874 return DSAVarData();
1875 D
= getCanonicalDecl(D
);
1876 const_iterator StartI
= std::next(begin(), getStackSize() - 1 - Level
);
1877 return getDSA(StartI
, D
);
1880 const DSAStackTy::DSAVarData
1881 DSAStackTy::hasDSA(ValueDecl
*D
,
1882 const llvm::function_ref
<bool(OpenMPClauseKind
, bool,
1883 DefaultDataSharingAttributes
)>
1885 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
1886 bool FromParent
) const {
1889 D
= getCanonicalDecl(D
);
1890 const_iterator I
= begin();
1891 const_iterator EndI
= end();
1892 if (FromParent
&& I
!= EndI
)
1894 for (; I
!= EndI
; ++I
) {
1895 if (!DPred(I
->Directive
) &&
1896 !isImplicitOrExplicitTaskingRegion(I
->Directive
))
1898 const_iterator NewI
= I
;
1899 DSAVarData DVar
= getDSA(NewI
, D
);
1900 if (I
== NewI
&& CPred(DVar
.CKind
, DVar
.AppliedToPointee
, I
->DefaultAttr
))
1906 const DSAStackTy::DSAVarData
DSAStackTy::hasInnermostDSA(
1907 ValueDecl
*D
, const llvm::function_ref
<bool(OpenMPClauseKind
, bool)> CPred
,
1908 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
1909 bool FromParent
) const {
1912 D
= getCanonicalDecl(D
);
1913 const_iterator StartI
= begin();
1914 const_iterator EndI
= end();
1915 if (FromParent
&& StartI
!= EndI
)
1917 if (StartI
== EndI
|| !DPred(StartI
->Directive
))
1919 const_iterator NewI
= StartI
;
1920 DSAVarData DVar
= getDSA(NewI
, D
);
1921 return (NewI
== StartI
&& CPred(DVar
.CKind
, DVar
.AppliedToPointee
))
1926 bool DSAStackTy::hasExplicitDSA(
1928 const llvm::function_ref
<bool(OpenMPClauseKind
, bool)> CPred
,
1929 unsigned Level
, bool NotLastprivate
) const {
1930 if (getStackSize() <= Level
)
1932 D
= getCanonicalDecl(D
);
1933 const SharingMapTy
&StackElem
= getStackElemAtLevel(Level
);
1934 auto I
= StackElem
.SharingMap
.find(D
);
1935 if (I
!= StackElem
.SharingMap
.end() && I
->getSecond().RefExpr
.getPointer() &&
1936 CPred(I
->getSecond().Attributes
, I
->getSecond().AppliedToPointee
) &&
1937 (!NotLastprivate
|| !I
->getSecond().RefExpr
.getInt()))
1939 // Check predetermined rules for the loop control variables.
1940 auto LI
= StackElem
.LCVMap
.find(D
);
1941 if (LI
!= StackElem
.LCVMap
.end())
1942 return CPred(OMPC_private
, /*AppliedToPointee=*/false);
1946 bool DSAStackTy::hasExplicitDirective(
1947 const llvm::function_ref
<bool(OpenMPDirectiveKind
)> DPred
,
1948 unsigned Level
) const {
1949 if (getStackSize() <= Level
)
1951 const SharingMapTy
&StackElem
= getStackElemAtLevel(Level
);
1952 return DPred(StackElem
.Directive
);
1955 bool DSAStackTy::hasDirective(
1956 const llvm::function_ref
<bool(OpenMPDirectiveKind
,
1957 const DeclarationNameInfo
&, SourceLocation
)>
1959 bool FromParent
) const {
1960 // We look only in the enclosing region.
1961 size_t Skip
= FromParent
? 2 : 1;
1962 for (const_iterator I
= begin() + std::min(Skip
, getStackSize()), E
= end();
1964 if (DPred(I
->Directive
, I
->DirectiveName
, I
->ConstructLoc
))
1970 void Sema::InitDataSharingAttributesStack() {
1971 VarDataSharingAttributesStack
= new DSAStackTy(*this);
1974 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1976 void Sema::pushOpenMPFunctionRegion() { DSAStack
->pushFunction(); }
1978 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo
*OldFSI
) {
1979 DSAStack
->popFunction(OldFSI
);
1982 static bool isOpenMPDeviceDelayedContext(Sema
&S
) {
1983 assert(S
.LangOpts
.OpenMP
&& S
.LangOpts
.OpenMPIsDevice
&&
1984 "Expected OpenMP device compilation.");
1985 return !S
.isInOpenMPTargetExecutionDirective();
1989 /// Status of the function emission on the host/device.
1990 enum class FunctionEmissionStatus
{
1995 } // anonymous namespace
1997 Sema::SemaDiagnosticBuilder
Sema::diagIfOpenMPDeviceCode(SourceLocation Loc
,
2000 assert(LangOpts
.OpenMP
&& LangOpts
.OpenMPIsDevice
&&
2001 "Expected OpenMP device compilation.");
2003 SemaDiagnosticBuilder::Kind Kind
= SemaDiagnosticBuilder::K_Nop
;
2005 FunctionEmissionStatus FES
= getEmissionStatus(FD
);
2007 case FunctionEmissionStatus::Emitted
:
2008 Kind
= SemaDiagnosticBuilder::K_Immediate
;
2010 case FunctionEmissionStatus::Unknown
:
2011 // TODO: We should always delay diagnostics here in case a target
2012 // region is in a function we do not emit. However, as the
2013 // current diagnostics are associated with the function containing
2014 // the target region and we do not emit that one, we would miss out
2015 // on diagnostics for the target region itself. We need to anchor
2016 // the diagnostics with the new generated function *or* ensure we
2017 // emit diagnostics associated with the surrounding function.
2018 Kind
= isOpenMPDeviceDelayedContext(*this)
2019 ? SemaDiagnosticBuilder::K_Deferred
2020 : SemaDiagnosticBuilder::K_Immediate
;
2022 case FunctionEmissionStatus::TemplateDiscarded
:
2023 case FunctionEmissionStatus::OMPDiscarded
:
2024 Kind
= SemaDiagnosticBuilder::K_Nop
;
2026 case FunctionEmissionStatus::CUDADiscarded
:
2027 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2032 return SemaDiagnosticBuilder(Kind
, Loc
, DiagID
, FD
, *this);
2035 Sema::SemaDiagnosticBuilder
Sema::diagIfOpenMPHostCode(SourceLocation Loc
,
2038 assert(LangOpts
.OpenMP
&& !LangOpts
.OpenMPIsDevice
&&
2039 "Expected OpenMP host compilation.");
2041 SemaDiagnosticBuilder::Kind Kind
= SemaDiagnosticBuilder::K_Nop
;
2043 FunctionEmissionStatus FES
= getEmissionStatus(FD
);
2045 case FunctionEmissionStatus::Emitted
:
2046 Kind
= SemaDiagnosticBuilder::K_Immediate
;
2048 case FunctionEmissionStatus::Unknown
:
2049 Kind
= SemaDiagnosticBuilder::K_Deferred
;
2051 case FunctionEmissionStatus::TemplateDiscarded
:
2052 case FunctionEmissionStatus::OMPDiscarded
:
2053 case FunctionEmissionStatus::CUDADiscarded
:
2054 Kind
= SemaDiagnosticBuilder::K_Nop
;
2059 return SemaDiagnosticBuilder(Kind
, Loc
, DiagID
, FD
, *this);
2062 static OpenMPDefaultmapClauseKind
2063 getVariableCategoryFromDecl(const LangOptions
&LO
, const ValueDecl
*VD
) {
2064 if (LO
.OpenMP
<= 45) {
2065 if (VD
->getType().getNonReferenceType()->isScalarType())
2066 return OMPC_DEFAULTMAP_scalar
;
2067 return OMPC_DEFAULTMAP_aggregate
;
2069 if (VD
->getType().getNonReferenceType()->isAnyPointerType())
2070 return OMPC_DEFAULTMAP_pointer
;
2071 if (VD
->getType().getNonReferenceType()->isScalarType())
2072 return OMPC_DEFAULTMAP_scalar
;
2073 return OMPC_DEFAULTMAP_aggregate
;
2076 bool Sema::isOpenMPCapturedByRef(const ValueDecl
*D
, unsigned Level
,
2077 unsigned OpenMPCaptureLevel
) const {
2078 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2080 ASTContext
&Ctx
= getASTContext();
2081 bool IsByRef
= true;
2083 // Find the directive that is associated with the provided scope.
2084 D
= cast
<ValueDecl
>(D
->getCanonicalDecl());
2085 QualType Ty
= D
->getType();
2087 bool IsVariableUsedInMapClause
= false;
2088 if (DSAStack
->hasExplicitDirective(isOpenMPTargetExecutionDirective
, Level
)) {
2089 // This table summarizes how a given variable should be passed to the device
2090 // given its type and the clauses where it appears. This table is based on
2091 // the description in OpenMP 4.5 [2.10.4, target Construct] and
2092 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2094 // =========================================================================
2095 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
2096 // | |(tofrom:scalar)| | pvt | | | |
2097 // =========================================================================
2098 // | scl | | | | - | | bycopy|
2099 // | scl | | - | x | - | - | bycopy|
2100 // | scl | | x | - | - | - | null |
2101 // | scl | x | | | - | | byref |
2102 // | scl | x | - | x | - | - | bycopy|
2103 // | scl | x | x | - | - | - | null |
2104 // | scl | | - | - | - | x | byref |
2105 // | scl | x | - | - | - | x | byref |
2107 // | agg | n.a. | | | - | | byref |
2108 // | agg | n.a. | - | x | - | - | byref |
2109 // | agg | n.a. | x | - | - | - | null |
2110 // | agg | n.a. | - | - | - | x | byref |
2111 // | agg | n.a. | - | - | - | x[] | byref |
2113 // | ptr | n.a. | | | - | | bycopy|
2114 // | ptr | n.a. | - | x | - | - | bycopy|
2115 // | ptr | n.a. | x | - | - | - | null |
2116 // | ptr | n.a. | - | - | - | x | byref |
2117 // | ptr | n.a. | - | - | - | x[] | bycopy|
2118 // | ptr | n.a. | - | - | x | | bycopy|
2119 // | ptr | n.a. | - | - | x | x | bycopy|
2120 // | ptr | n.a. | - | - | x | x[] | bycopy|
2121 // =========================================================================
2127 // - - invalid in this combination
2128 // [] - mapped with an array section
2129 // byref - should be mapped by reference
2130 // byval - should be mapped by value
2131 // null - initialize a local variable to null on the device
2134 // - All scalar declarations that show up in a map clause have to be passed
2135 // by reference, because they may have been mapped in the enclosing data
2137 // - If the scalar value does not fit the size of uintptr, it has to be
2138 // passed by reference, regardless the result in the table above.
2139 // - For pointers mapped by value that have either an implicit map or an
2140 // array section, the runtime library may pass the NULL value to the
2141 // device instead of the value passed to it by the compiler.
2143 if (Ty
->isReferenceType())
2144 Ty
= Ty
->castAs
<ReferenceType
>()->getPointeeType();
2146 // Locate map clauses and see if the variable being captured is referred to
2147 // in any of those clauses. Here we only care about variables, not fields,
2148 // because fields are part of aggregates.
2149 bool IsVariableAssociatedWithSection
= false;
2151 DSAStack
->checkMappableExprComponentListsForDeclAtLevel(
2153 [&IsVariableUsedInMapClause
, &IsVariableAssociatedWithSection
,
2154 D
](OMPClauseMappableExprCommon::MappableExprComponentListRef
2156 OpenMPClauseKind WhereFoundClauseKind
) {
2157 // Only the map clause information influences how a variable is
2158 // captured. E.g. is_device_ptr does not require changing the default
2160 if (WhereFoundClauseKind
!= OMPC_map
)
2163 auto EI
= MapExprComponents
.rbegin();
2164 auto EE
= MapExprComponents
.rend();
2166 assert(EI
!= EE
&& "Invalid map expression!");
2168 if (isa
<DeclRefExpr
>(EI
->getAssociatedExpression()))
2169 IsVariableUsedInMapClause
|= EI
->getAssociatedDeclaration() == D
;
2175 if (isa
<ArraySubscriptExpr
>(EI
->getAssociatedExpression()) ||
2176 isa
<OMPArraySectionExpr
>(EI
->getAssociatedExpression()) ||
2177 isa
<MemberExpr
>(EI
->getAssociatedExpression()) ||
2178 isa
<OMPArrayShapingExpr
>(EI
->getAssociatedExpression())) {
2179 IsVariableAssociatedWithSection
= true;
2180 // There is nothing more we need to know about this variable.
2184 // Keep looking for more map info.
2188 if (IsVariableUsedInMapClause
) {
2189 // If variable is identified in a map clause it is always captured by
2190 // reference except if it is a pointer that is dereferenced somehow.
2191 IsByRef
= !(Ty
->isPointerType() && IsVariableAssociatedWithSection
);
2193 // By default, all the data that has a scalar type is mapped by copy
2194 // (except for reduction variables).
2195 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2196 IsByRef
= (DSAStack
->isForceCaptureByReferenceInTargetExecutable() &&
2197 !Ty
->isAnyPointerType()) ||
2198 !Ty
->isScalarType() ||
2199 DSAStack
->isDefaultmapCapturedByRef(
2200 Level
, getVariableCategoryFromDecl(LangOpts
, D
)) ||
2201 DSAStack
->hasExplicitDSA(
2203 [](OpenMPClauseKind K
, bool AppliedToPointee
) {
2204 return K
== OMPC_reduction
&& !AppliedToPointee
;
2210 if (IsByRef
&& Ty
.getNonReferenceType()->isScalarType()) {
2212 ((IsVariableUsedInMapClause
&&
2213 DSAStack
->getCaptureRegion(Level
, OpenMPCaptureLevel
) ==
2215 !(DSAStack
->hasExplicitDSA(
2217 [](OpenMPClauseKind K
, bool AppliedToPointee
) -> bool {
2218 return K
== OMPC_firstprivate
||
2219 (K
== OMPC_reduction
&& AppliedToPointee
);
2221 Level
, /*NotLastprivate=*/true) ||
2222 DSAStack
->isUsesAllocatorsDecl(Level
, D
))) &&
2223 // If the variable is artificial and must be captured by value - try to
2224 // capture by value.
2225 !(isa
<OMPCapturedExprDecl
>(D
) && !D
->hasAttr
<OMPCaptureNoInitAttr
>() &&
2226 !cast
<OMPCapturedExprDecl
>(D
)->getInit()->isGLValue()) &&
2227 // If the variable is implicitly firstprivate and scalar - capture by
2229 !((DSAStack
->getDefaultDSA() == DSA_firstprivate
||
2230 DSAStack
->getDefaultDSA() == DSA_private
) &&
2231 !DSAStack
->hasExplicitDSA(
2232 D
, [](OpenMPClauseKind K
, bool) { return K
!= OMPC_unknown
; },
2234 !DSAStack
->isLoopControlVariable(D
, Level
).first
);
2237 // When passing data by copy, we need to make sure it fits the uintptr size
2238 // and alignment, because the runtime library only deals with uintptr types.
2239 // If it does not fit the uintptr size, we need to pass the data by reference
2242 (Ctx
.getTypeSizeInChars(Ty
) >
2243 Ctx
.getTypeSizeInChars(Ctx
.getUIntPtrType()) ||
2244 Ctx
.getDeclAlign(D
) > Ctx
.getTypeAlignInChars(Ctx
.getUIntPtrType()))) {
2251 unsigned Sema::getOpenMPNestingLevel() const {
2252 assert(getLangOpts().OpenMP
);
2253 return DSAStack
->getNestingLevel();
2256 bool Sema::isInOpenMPTaskUntiedContext() const {
2257 return isOpenMPTaskingDirective(DSAStack
->getCurrentDirective()) &&
2258 DSAStack
->isUntiedRegion();
2261 bool Sema::isInOpenMPTargetExecutionDirective() const {
2262 return (isOpenMPTargetExecutionDirective(DSAStack
->getCurrentDirective()) &&
2263 !DSAStack
->isClauseParsingMode()) ||
2264 DSAStack
->hasDirective(
2265 [](OpenMPDirectiveKind K
, const DeclarationNameInfo
&,
2266 SourceLocation
) -> bool {
2267 return isOpenMPTargetExecutionDirective(K
);
2272 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl
*D
) {
2273 // Only rebuild for Field.
2274 if (!dyn_cast
<FieldDecl
>(D
))
2276 DSAStackTy::DSAVarData DVarPrivate
= DSAStack
->hasDSA(
2278 [](OpenMPClauseKind C
, bool AppliedToPointee
,
2279 DefaultDataSharingAttributes DefaultAttr
) {
2280 return isOpenMPPrivate(C
) && !AppliedToPointee
&&
2281 (DefaultAttr
== DSA_firstprivate
|| DefaultAttr
== DSA_private
);
2283 [](OpenMPDirectiveKind
) { return true; },
2284 DSAStack
->isClauseParsingMode());
2285 if (DVarPrivate
.CKind
!= OMPC_unknown
)
2290 static OMPCapturedExprDecl
*buildCaptureDecl(Sema
&S
, IdentifierInfo
*Id
,
2291 Expr
*CaptureExpr
, bool WithInit
,
2292 DeclContext
*CurContext
,
2295 VarDecl
*Sema::isOpenMPCapturedDecl(ValueDecl
*D
, bool CheckScopeInfo
,
2297 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2298 D
= getCanonicalDecl(D
);
2300 auto *VD
= dyn_cast
<VarDecl
>(D
);
2301 // Do not capture constexpr variables.
2302 if (VD
&& VD
->isConstexpr())
2305 // If we want to determine whether the variable should be captured from the
2306 // perspective of the current capturing scope, and we've already left all the
2307 // capturing scopes of the top directive on the stack, check from the
2308 // perspective of its parent directive (if any) instead.
2309 DSAStackTy::ParentDirectiveScope
InParentDirectiveRAII(
2310 *DSAStack
, CheckScopeInfo
&& DSAStack
->isBodyComplete());
2312 // If we are attempting to capture a global variable in a directive with
2313 // 'target' we return true so that this global is also mapped to the device.
2315 if (VD
&& !VD
->hasLocalStorage() &&
2316 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2317 if (isInOpenMPTargetExecutionDirective()) {
2318 DSAStackTy::DSAVarData DVarTop
=
2319 DSAStack
->getTopDSA(D
, DSAStack
->isClauseParsingMode());
2320 if (DVarTop
.CKind
!= OMPC_unknown
&& DVarTop
.RefExpr
)
2322 // If the declaration is enclosed in a 'declare target' directive,
2323 // then it should not be captured.
2325 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD
))
2327 CapturedRegionScopeInfo
*CSI
= nullptr;
2328 for (FunctionScopeInfo
*FSI
: llvm::drop_begin(
2329 llvm::reverse(FunctionScopes
),
2330 CheckScopeInfo
? (FunctionScopes
.size() - (StopAt
+ 1)) : 0)) {
2331 if (!isa
<CapturingScopeInfo
>(FSI
))
2333 if (auto *RSI
= dyn_cast
<CapturedRegionScopeInfo
>(FSI
))
2334 if (RSI
->CapRegionKind
== CR_OpenMP
) {
2339 assert(CSI
&& "Failed to find CapturedRegionScopeInfo");
2340 SmallVector
<OpenMPDirectiveKind
, 4> Regions
;
2341 getOpenMPCaptureRegions(Regions
,
2342 DSAStack
->getDirective(CSI
->OpenMPLevel
));
2343 if (Regions
[CSI
->OpenMPCaptureLevel
] != OMPD_task
)
2346 if (isInOpenMPDeclareTargetContext()) {
2347 // Try to mark variable as declare target if it is used in capturing
2349 if (LangOpts
.OpenMP
<= 45 &&
2350 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD
))
2351 checkDeclIsAllowedInOpenMPTarget(nullptr, VD
);
2356 if (CheckScopeInfo
) {
2357 bool OpenMPFound
= false;
2358 for (unsigned I
= StopAt
+ 1; I
> 0; --I
) {
2359 FunctionScopeInfo
*FSI
= FunctionScopes
[I
- 1];
2360 if (!isa
<CapturingScopeInfo
>(FSI
))
2362 if (auto *RSI
= dyn_cast
<CapturedRegionScopeInfo
>(FSI
))
2363 if (RSI
->CapRegionKind
== CR_OpenMP
) {
2372 if (DSAStack
->getCurrentDirective() != OMPD_unknown
&&
2373 (!DSAStack
->isClauseParsingMode() ||
2374 DSAStack
->getParentDirective() != OMPD_unknown
)) {
2375 auto &&Info
= DSAStack
->isLoopControlVariable(D
);
2377 (VD
&& VD
->hasLocalStorage() &&
2378 isImplicitOrExplicitTaskingRegion(DSAStack
->getCurrentDirective())) ||
2379 (VD
&& DSAStack
->isForceVarCapturing()))
2380 return VD
? VD
: Info
.second
;
2381 DSAStackTy::DSAVarData DVarTop
=
2382 DSAStack
->getTopDSA(D
, DSAStack
->isClauseParsingMode());
2383 if (DVarTop
.CKind
!= OMPC_unknown
&& isOpenMPPrivate(DVarTop
.CKind
) &&
2384 (!VD
|| VD
->hasLocalStorage() || !DVarTop
.AppliedToPointee
))
2385 return VD
? VD
: cast
<VarDecl
>(DVarTop
.PrivateCopy
->getDecl());
2386 // Threadprivate variables must not be captured.
2387 if (isOpenMPThreadPrivate(DVarTop
.CKind
))
2389 // The variable is not private or it is the variable in the directive with
2390 // default(none) clause and not used in any clause.
2391 DSAStackTy::DSAVarData DVarPrivate
= DSAStack
->hasDSA(
2393 [](OpenMPClauseKind C
, bool AppliedToPointee
, bool) {
2394 return isOpenMPPrivate(C
) && !AppliedToPointee
;
2396 [](OpenMPDirectiveKind
) { return true; },
2397 DSAStack
->isClauseParsingMode());
2398 // Global shared must not be captured.
2399 if (VD
&& !VD
->hasLocalStorage() && DVarPrivate
.CKind
== OMPC_unknown
&&
2400 ((DSAStack
->getDefaultDSA() != DSA_none
&&
2401 DSAStack
->getDefaultDSA() != DSA_private
&&
2402 DSAStack
->getDefaultDSA() != DSA_firstprivate
) ||
2403 DVarTop
.CKind
== OMPC_shared
))
2405 auto *FD
= dyn_cast
<FieldDecl
>(D
);
2406 if (DVarPrivate
.CKind
!= OMPC_unknown
&& !VD
&& FD
&&
2407 !DVarPrivate
.PrivateCopy
) {
2408 DSAStackTy::DSAVarData DVarPrivate
= DSAStack
->hasDSA(
2410 [](OpenMPClauseKind C
, bool AppliedToPointee
,
2411 DefaultDataSharingAttributes DefaultAttr
) {
2412 return isOpenMPPrivate(C
) && !AppliedToPointee
&&
2413 (DefaultAttr
== DSA_firstprivate
||
2414 DefaultAttr
== DSA_private
);
2416 [](OpenMPDirectiveKind
) { return true; },
2417 DSAStack
->isClauseParsingMode());
2418 if (DVarPrivate
.CKind
== OMPC_unknown
)
2421 VarDecl
*VD
= DSAStack
->getImplicitFDCapExprDecl(FD
);
2424 if (getCurrentThisType().isNull())
2426 Expr
*ThisExpr
= BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2427 /*IsImplicit=*/true);
2428 const CXXScopeSpec CS
= CXXScopeSpec();
2429 Expr
*ME
= BuildMemberExpr(ThisExpr
, /*IsArrow=*/true, SourceLocation(),
2430 NestedNameSpecifierLoc(), SourceLocation(), FD
,
2431 DeclAccessPair::make(FD
, FD
->getAccess()),
2432 /*HadMultipleCandidates=*/false,
2433 DeclarationNameInfo(), FD
->getType(),
2434 VK_LValue
, OK_Ordinary
);
2435 OMPCapturedExprDecl
*CD
= buildCaptureDecl(
2436 *this, FD
->getIdentifier(), ME
, DVarPrivate
.CKind
!= OMPC_private
,
2437 CurContext
->getParent(), /*AsExpression=*/false);
2438 DeclRefExpr
*VDPrivateRefExpr
= buildDeclRefExpr(
2439 *this, CD
, CD
->getType().getNonReferenceType(), SourceLocation());
2440 VD
= cast
<VarDecl
>(VDPrivateRefExpr
->getDecl());
2441 DSAStack
->addImplicitDefaultFirstprivateFD(FD
, VD
);
2444 if (DVarPrivate
.CKind
!= OMPC_unknown
||
2445 (VD
&& (DSAStack
->getDefaultDSA() == DSA_none
||
2446 DSAStack
->getDefaultDSA() == DSA_private
||
2447 DSAStack
->getDefaultDSA() == DSA_firstprivate
)))
2448 return VD
? VD
: cast
<VarDecl
>(DVarPrivate
.PrivateCopy
->getDecl());
2453 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex
,
2454 unsigned Level
) const {
2455 FunctionScopesIndex
-= getOpenMPCaptureLevels(DSAStack
->getDirective(Level
));
2458 void Sema::startOpenMPLoop() {
2459 assert(LangOpts
.OpenMP
&& "OpenMP must be enabled.");
2460 if (isOpenMPLoopDirective(DSAStack
->getCurrentDirective()))
2461 DSAStack
->loopInit();
2464 void Sema::startOpenMPCXXRangeFor() {
2465 assert(LangOpts
.OpenMP
&& "OpenMP must be enabled.");
2466 if (isOpenMPLoopDirective(DSAStack
->getCurrentDirective())) {
2467 DSAStack
->resetPossibleLoopCounter();
2468 DSAStack
->loopStart();
2472 OpenMPClauseKind
Sema::isOpenMPPrivateDecl(ValueDecl
*D
, unsigned Level
,
2473 unsigned CapLevel
) const {
2474 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2475 if (DSAStack
->getCurrentDirective() != OMPD_unknown
&&
2476 (!DSAStack
->isClauseParsingMode() ||
2477 DSAStack
->getParentDirective() != OMPD_unknown
)) {
2478 DSAStackTy::DSAVarData DVarPrivate
= DSAStack
->hasDSA(
2480 [](OpenMPClauseKind C
, bool AppliedToPointee
,
2481 DefaultDataSharingAttributes DefaultAttr
) {
2482 return isOpenMPPrivate(C
) && !AppliedToPointee
&&
2483 DefaultAttr
== DSA_private
;
2485 [](OpenMPDirectiveKind
) { return true; },
2486 DSAStack
->isClauseParsingMode());
2487 if (DVarPrivate
.CKind
== OMPC_private
&& isa
<OMPCapturedExprDecl
>(D
) &&
2488 DSAStack
->isImplicitDefaultFirstprivateFD(cast
<VarDecl
>(D
)) &&
2489 !DSAStack
->isLoopControlVariable(D
).first
)
2490 return OMPC_private
;
2492 if (DSAStack
->hasExplicitDirective(isOpenMPTaskingDirective
, Level
)) {
2493 bool IsTriviallyCopyable
=
2494 D
->getType().getNonReferenceType().isTriviallyCopyableType(Context
) &&
2496 .getNonReferenceType()
2498 ->getAsCXXRecordDecl();
2499 OpenMPDirectiveKind DKind
= DSAStack
->getDirective(Level
);
2500 SmallVector
<OpenMPDirectiveKind
, 4> CaptureRegions
;
2501 getOpenMPCaptureRegions(CaptureRegions
, DKind
);
2502 if (isOpenMPTaskingDirective(CaptureRegions
[CapLevel
]) &&
2503 (IsTriviallyCopyable
||
2504 !isOpenMPTaskLoopDirective(CaptureRegions
[CapLevel
]))) {
2505 if (DSAStack
->hasExplicitDSA(
2507 [](OpenMPClauseKind K
, bool) { return K
== OMPC_firstprivate
; },
2508 Level
, /*NotLastprivate=*/true))
2509 return OMPC_firstprivate
;
2510 DSAStackTy::DSAVarData DVar
= DSAStack
->getImplicitDSA(D
, Level
);
2511 if (DVar
.CKind
!= OMPC_shared
&&
2512 !DSAStack
->isLoopControlVariable(D
, Level
).first
&& !DVar
.RefExpr
) {
2513 DSAStack
->addImplicitTaskFirstprivate(Level
, D
);
2514 return OMPC_firstprivate
;
2518 if (isOpenMPLoopDirective(DSAStack
->getCurrentDirective())) {
2519 if (DSAStack
->getAssociatedLoops() > 0 && !DSAStack
->isLoopStarted()) {
2520 DSAStack
->resetPossibleLoopCounter(D
);
2521 DSAStack
->loopStart();
2522 return OMPC_private
;
2524 if ((DSAStack
->getPossiblyLoopCunter() == D
->getCanonicalDecl() ||
2525 DSAStack
->isLoopControlVariable(D
).first
) &&
2526 !DSAStack
->hasExplicitDSA(
2527 D
, [](OpenMPClauseKind K
, bool) { return K
!= OMPC_private
; },
2529 !isOpenMPSimdDirective(DSAStack
->getCurrentDirective()))
2530 return OMPC_private
;
2532 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
2533 if (DSAStack
->isThreadPrivate(const_cast<VarDecl
*>(VD
)) &&
2534 DSAStack
->isForceVarCapturing() &&
2535 !DSAStack
->hasExplicitDSA(
2536 D
, [](OpenMPClauseKind K
, bool) { return K
== OMPC_copyin
; },
2538 return OMPC_private
;
2540 // User-defined allocators are private since they must be defined in the
2541 // context of target region.
2542 if (DSAStack
->hasExplicitDirective(isOpenMPTargetExecutionDirective
, Level
) &&
2543 DSAStack
->isUsesAllocatorsDecl(Level
, D
).value_or(
2544 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait
) ==
2545 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator
)
2546 return OMPC_private
;
2547 return (DSAStack
->hasExplicitDSA(
2548 D
, [](OpenMPClauseKind K
, bool) { return K
== OMPC_private
; },
2550 (DSAStack
->isClauseParsingMode() &&
2551 DSAStack
->getClauseParsingMode() == OMPC_private
) ||
2552 // Consider taskgroup reduction descriptor variable a private
2553 // to avoid possible capture in the region.
2554 (DSAStack
->hasExplicitDirective(
2555 [](OpenMPDirectiveKind K
) {
2556 return K
== OMPD_taskgroup
||
2557 ((isOpenMPParallelDirective(K
) ||
2558 isOpenMPWorksharingDirective(K
)) &&
2559 !isOpenMPSimdDirective(K
));
2562 DSAStack
->isTaskgroupReductionRef(D
, Level
)))
2567 void Sema::setOpenMPCaptureKind(FieldDecl
*FD
, const ValueDecl
*D
,
2569 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2570 D
= getCanonicalDecl(D
);
2571 OpenMPClauseKind OMPC
= OMPC_unknown
;
2572 for (unsigned I
= DSAStack
->getNestingLevel() + 1; I
> Level
; --I
) {
2573 const unsigned NewLevel
= I
- 1;
2574 if (DSAStack
->hasExplicitDSA(
2576 [&OMPC
](const OpenMPClauseKind K
, bool AppliedToPointee
) {
2577 if (isOpenMPPrivate(K
) && !AppliedToPointee
) {
2585 if (DSAStack
->checkMappableExprComponentListsForDeclAtLevel(
2587 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
,
2588 OpenMPClauseKind
) { return true; })) {
2592 if (DSAStack
->hasExplicitDirective(isOpenMPTargetExecutionDirective
,
2595 if (DSAStack
->mustBeFirstprivateAtLevel(
2596 NewLevel
, getVariableCategoryFromDecl(LangOpts
, D
)))
2597 OMPC
= OMPC_firstprivate
;
2601 if (OMPC
!= OMPC_unknown
)
2602 FD
->addAttr(OMPCaptureKindAttr::CreateImplicit(Context
, unsigned(OMPC
)));
2605 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl
*D
, unsigned Level
,
2606 unsigned CaptureLevel
) const {
2607 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2608 // Return true if the current level is no longer enclosed in a target region.
2610 SmallVector
<OpenMPDirectiveKind
, 4> Regions
;
2611 getOpenMPCaptureRegions(Regions
, DSAStack
->getDirective(Level
));
2612 const auto *VD
= dyn_cast
<VarDecl
>(D
);
2613 return VD
&& !VD
->hasLocalStorage() &&
2614 DSAStack
->hasExplicitDirective(isOpenMPTargetExecutionDirective
,
2616 Regions
[CaptureLevel
] != OMPD_task
;
2619 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl
*D
, unsigned Level
,
2620 unsigned CaptureLevel
) const {
2621 assert(LangOpts
.OpenMP
&& "OpenMP is not allowed");
2622 // Return true if the current level is no longer enclosed in a target region.
2624 if (const auto *VD
= dyn_cast
<VarDecl
>(D
)) {
2625 if (!VD
->hasLocalStorage()) {
2626 if (isInOpenMPTargetExecutionDirective())
2628 DSAStackTy::DSAVarData TopDVar
=
2629 DSAStack
->getTopDSA(D
, /*FromParent=*/false);
2630 unsigned NumLevels
=
2631 getOpenMPCaptureLevels(DSAStack
->getDirective(Level
));
2633 // non-file scope static variale with default(firstprivate)
2634 // should be gloabal captured.
2635 return (NumLevels
== CaptureLevel
+ 1 &&
2636 (TopDVar
.CKind
!= OMPC_shared
||
2637 DSAStack
->getDefaultDSA() == DSA_firstprivate
));
2640 DSAStackTy::DSAVarData DVar
= DSAStack
->getImplicitDSA(D
, Level
);
2641 if (DVar
.CKind
!= OMPC_shared
)
2643 } while (Level
> 0);
2649 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack
; }
2651 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc
,
2653 OMPDeclareVariantScopes
.push_back(OMPDeclareVariantScope(TI
));
2656 void Sema::ActOnOpenMPEndDeclareVariant() {
2657 assert(isInOpenMPDeclareVariantScope() &&
2658 "Not in OpenMP declare variant scope!");
2660 OMPDeclareVariantScopes
.pop_back();
2663 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl
*Caller
,
2664 const FunctionDecl
*Callee
,
2665 SourceLocation Loc
) {
2666 assert(LangOpts
.OpenMP
&& "Expected OpenMP compilation mode.");
2667 Optional
<OMPDeclareTargetDeclAttr::DevTypeTy
> DevTy
=
2668 OMPDeclareTargetDeclAttr::getDeviceType(Caller
->getMostRecentDecl());
2669 // Ignore host functions during device analyzis.
2670 if (LangOpts
.OpenMPIsDevice
&&
2671 (!DevTy
|| *DevTy
== OMPDeclareTargetDeclAttr::DT_Host
))
2673 // Ignore nohost functions during host analyzis.
2674 if (!LangOpts
.OpenMPIsDevice
&& DevTy
&&
2675 *DevTy
== OMPDeclareTargetDeclAttr::DT_NoHost
)
2677 const FunctionDecl
*FD
= Callee
->getMostRecentDecl();
2678 DevTy
= OMPDeclareTargetDeclAttr::getDeviceType(FD
);
2679 if (LangOpts
.OpenMPIsDevice
&& DevTy
&&
2680 *DevTy
== OMPDeclareTargetDeclAttr::DT_Host
) {
2681 // Diagnose host function called during device codegen.
2682 StringRef HostDevTy
=
2683 getOpenMPSimpleClauseTypeName(OMPC_device_type
, OMPC_DEVICE_TYPE_host
);
2684 Diag(Loc
, diag::err_omp_wrong_device_function_call
) << HostDevTy
<< 0;
2685 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD
),
2686 diag::note_omp_marked_device_type_here
)
2690 if (!LangOpts
.OpenMPIsDevice
&& !LangOpts
.OpenMPOffloadMandatory
&& DevTy
&&
2691 *DevTy
== OMPDeclareTargetDeclAttr::DT_NoHost
) {
2692 // Diagnose nohost function called during host codegen.
2693 StringRef NoHostDevTy
= getOpenMPSimpleClauseTypeName(
2694 OMPC_device_type
, OMPC_DEVICE_TYPE_nohost
);
2695 Diag(Loc
, diag::err_omp_wrong_device_function_call
) << NoHostDevTy
<< 1;
2696 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD
),
2697 diag::note_omp_marked_device_type_here
)
2702 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind
,
2703 const DeclarationNameInfo
&DirName
,
2704 Scope
*CurScope
, SourceLocation Loc
) {
2705 DSAStack
->push(DKind
, DirName
, CurScope
, Loc
);
2706 PushExpressionEvaluationContext(
2707 ExpressionEvaluationContext::PotentiallyEvaluated
);
2710 void Sema::StartOpenMPClause(OpenMPClauseKind K
) {
2711 DSAStack
->setClauseParsingMode(K
);
2714 void Sema::EndOpenMPClause() {
2715 DSAStack
->setClauseParsingMode(/*K=*/OMPC_unknown
);
2716 CleanupVarDeclMarking();
2719 static std::pair
<ValueDecl
*, bool>
2720 getPrivateItem(Sema
&S
, Expr
*&RefExpr
, SourceLocation
&ELoc
,
2721 SourceRange
&ERange
, bool AllowArraySection
= false,
2722 StringRef DiagType
= "");
2724 /// Check consistency of the reduction clauses.
2725 static void checkReductionClauses(Sema
&S
, DSAStackTy
*Stack
,
2726 ArrayRef
<OMPClause
*> Clauses
) {
2727 bool InscanFound
= false;
2728 SourceLocation InscanLoc
;
2729 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2730 // A reduction clause without the inscan reduction-modifier may not appear on
2731 // a construct on which a reduction clause with the inscan reduction-modifier
2733 for (OMPClause
*C
: Clauses
) {
2734 if (C
->getClauseKind() != OMPC_reduction
)
2736 auto *RC
= cast
<OMPReductionClause
>(C
);
2737 if (RC
->getModifier() == OMPC_REDUCTION_inscan
) {
2739 InscanLoc
= RC
->getModifierLoc();
2742 if (RC
->getModifier() == OMPC_REDUCTION_task
) {
2743 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2744 // A reduction clause with the task reduction-modifier may only appear on
2745 // a parallel construct, a worksharing construct or a combined or
2746 // composite construct for which any of the aforementioned constructs is a
2747 // constituent construct and simd or loop are not constituent constructs.
2748 OpenMPDirectiveKind CurDir
= Stack
->getCurrentDirective();
2749 if (!(isOpenMPParallelDirective(CurDir
) ||
2750 isOpenMPWorksharingDirective(CurDir
)) ||
2751 isOpenMPSimdDirective(CurDir
))
2752 S
.Diag(RC
->getModifierLoc(),
2753 diag::err_omp_reduction_task_not_parallel_or_worksharing
);
2758 for (OMPClause
*C
: Clauses
) {
2759 if (C
->getClauseKind() != OMPC_reduction
)
2761 auto *RC
= cast
<OMPReductionClause
>(C
);
2762 if (RC
->getModifier() != OMPC_REDUCTION_inscan
) {
2763 S
.Diag(RC
->getModifier() == OMPC_REDUCTION_unknown
2765 : RC
->getModifierLoc(),
2766 diag::err_omp_inscan_reduction_expected
);
2767 S
.Diag(InscanLoc
, diag::note_omp_previous_inscan_reduction
);
2770 for (Expr
*Ref
: RC
->varlists()) {
2771 assert(Ref
&& "NULL expr in OpenMP nontemporal clause.");
2772 SourceLocation ELoc
;
2774 Expr
*SimpleRefExpr
= Ref
;
2775 auto Res
= getPrivateItem(S
, SimpleRefExpr
, ELoc
, ERange
,
2776 /*AllowArraySection=*/true);
2777 ValueDecl
*D
= Res
.first
;
2780 if (!Stack
->isUsedInScanDirective(getCanonicalDecl(D
))) {
2781 S
.Diag(Ref
->getExprLoc(),
2782 diag::err_omp_reduction_not_inclusive_exclusive
)
2783 << Ref
->getSourceRange();
2790 static void checkAllocateClauses(Sema
&S
, DSAStackTy
*Stack
,
2791 ArrayRef
<OMPClause
*> Clauses
);
2792 static DeclRefExpr
*buildCapture(Sema
&S
, ValueDecl
*D
, Expr
*CaptureExpr
,
2795 static void reportOriginalDsa(Sema
&SemaRef
, const DSAStackTy
*Stack
,
2797 const DSAStackTy::DSAVarData
&DVar
,
2798 bool IsLoopIterVar
= false);
2800 void Sema::EndOpenMPDSABlock(Stmt
*CurDirective
) {
2801 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2802 // A variable of class type (or array thereof) that appears in a lastprivate
2803 // clause requires an accessible, unambiguous default constructor for the
2804 // class type, unless the list item is also specified in a firstprivate
2806 if (const auto *D
= dyn_cast_or_null
<OMPExecutableDirective
>(CurDirective
)) {
2807 for (OMPClause
*C
: D
->clauses()) {
2808 if (auto *Clause
= dyn_cast
<OMPLastprivateClause
>(C
)) {
2809 SmallVector
<Expr
*, 8> PrivateCopies
;
2810 for (Expr
*DE
: Clause
->varlists()) {
2811 if (DE
->isValueDependent() || DE
->isTypeDependent()) {
2812 PrivateCopies
.push_back(nullptr);
2815 auto *DRE
= cast
<DeclRefExpr
>(DE
->IgnoreParens());
2816 auto *VD
= cast
<VarDecl
>(DRE
->getDecl());
2817 QualType Type
= VD
->getType().getNonReferenceType();
2818 const DSAStackTy::DSAVarData DVar
=
2819 DSAStack
->getTopDSA(VD
, /*FromParent=*/false);
2820 if (DVar
.CKind
== OMPC_lastprivate
) {
2821 // Generate helper private variable and initialize it with the
2822 // default value. The address of the original variable is replaced
2823 // by the address of the new private variable in CodeGen. This new
2824 // variable is not added to IdResolver, so the code in the OpenMP
2825 // region uses original variable for proper diagnostics.
2826 VarDecl
*VDPrivate
= buildVarDecl(
2827 *this, DE
->getExprLoc(), Type
.getUnqualifiedType(),
2828 VD
->getName(), VD
->hasAttrs() ? &VD
->getAttrs() : nullptr, DRE
);
2829 ActOnUninitializedDecl(VDPrivate
);
2830 if (VDPrivate
->isInvalidDecl()) {
2831 PrivateCopies
.push_back(nullptr);
2834 PrivateCopies
.push_back(buildDeclRefExpr(
2835 *this, VDPrivate
, DE
->getType(), DE
->getExprLoc()));
2837 // The variable is also a firstprivate, so initialization sequence
2838 // for private copy is generated already.
2839 PrivateCopies
.push_back(nullptr);
2842 Clause
->setPrivateCopies(PrivateCopies
);
2845 // Finalize nontemporal clause by handling private copies, if any.
2846 if (auto *Clause
= dyn_cast
<OMPNontemporalClause
>(C
)) {
2847 SmallVector
<Expr
*, 8> PrivateRefs
;
2848 for (Expr
*RefExpr
: Clause
->varlists()) {
2849 assert(RefExpr
&& "NULL expr in OpenMP nontemporal clause.");
2850 SourceLocation ELoc
;
2852 Expr
*SimpleRefExpr
= RefExpr
;
2853 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
2855 // It will be analyzed later.
2856 PrivateRefs
.push_back(RefExpr
);
2857 ValueDecl
*D
= Res
.first
;
2861 const DSAStackTy::DSAVarData DVar
=
2862 DSAStack
->getTopDSA(D
, /*FromParent=*/false);
2863 PrivateRefs
.push_back(DVar
.PrivateCopy
? DVar
.PrivateCopy
2866 Clause
->setPrivateRefs(PrivateRefs
);
2869 if (auto *Clause
= dyn_cast
<OMPUsesAllocatorsClause
>(C
)) {
2870 for (unsigned I
= 0, E
= Clause
->getNumberOfAllocators(); I
< E
; ++I
) {
2871 OMPUsesAllocatorsClause::Data D
= Clause
->getAllocatorData(I
);
2872 auto *DRE
= dyn_cast
<DeclRefExpr
>(D
.Allocator
->IgnoreParenImpCasts());
2875 ValueDecl
*VD
= DRE
->getDecl();
2876 if (!VD
|| !isa
<VarDecl
>(VD
))
2878 DSAStackTy::DSAVarData DVar
=
2879 DSAStack
->getTopDSA(VD
, /*FromParent=*/false);
2880 // OpenMP [2.12.5, target Construct]
2881 // Memory allocators that appear in a uses_allocators clause cannot
2882 // appear in other data-sharing attribute clauses or data-mapping
2883 // attribute clauses in the same construct.
2884 Expr
*MapExpr
= nullptr;
2886 DSAStack
->checkMappableExprComponentListsForDecl(
2887 VD
, /*CurrentRegionOnly=*/true,
2889 OMPClauseMappableExprCommon::MappableExprComponentListRef
2891 OpenMPClauseKind C
) {
2892 auto MI
= MapExprComponents
.rbegin();
2893 auto ME
= MapExprComponents
.rend();
2895 MI
->getAssociatedDeclaration()->getCanonicalDecl() ==
2896 VD
->getCanonicalDecl()) {
2897 MapExpr
= MI
->getAssociatedExpression();
2902 Diag(D
.Allocator
->getExprLoc(),
2903 diag::err_omp_allocator_used_in_clauses
)
2904 << D
.Allocator
->getSourceRange();
2906 reportOriginalDsa(*this, DSAStack
, VD
, DVar
);
2908 Diag(MapExpr
->getExprLoc(), diag::note_used_here
)
2909 << MapExpr
->getSourceRange();
2915 // Check allocate clauses.
2916 if (!CurContext
->isDependentContext())
2917 checkAllocateClauses(*this, DSAStack
, D
->clauses());
2918 checkReductionClauses(*this, DSAStack
, D
->clauses());
2922 DiscardCleanupsInEvaluationContext();
2923 PopExpressionEvaluationContext();
2926 static bool FinishOpenMPLinearClause(OMPLinearClause
&Clause
, DeclRefExpr
*IV
,
2927 Expr
*NumIterations
, Sema
&SemaRef
,
2928 Scope
*S
, DSAStackTy
*Stack
);
2932 class VarDeclFilterCCC final
: public CorrectionCandidateCallback
{
2937 explicit VarDeclFilterCCC(Sema
&S
) : SemaRef(S
) {}
2938 bool ValidateCandidate(const TypoCorrection
&Candidate
) override
{
2939 NamedDecl
*ND
= Candidate
.getCorrectionDecl();
2940 if (const auto *VD
= dyn_cast_or_null
<VarDecl
>(ND
)) {
2941 return VD
->hasGlobalStorage() &&
2942 SemaRef
.isDeclInScope(ND
, SemaRef
.getCurLexicalContext(),
2943 SemaRef
.getCurScope());
2948 std::unique_ptr
<CorrectionCandidateCallback
> clone() override
{
2949 return std::make_unique
<VarDeclFilterCCC
>(*this);
2953 class VarOrFuncDeclFilterCCC final
: public CorrectionCandidateCallback
{
2958 explicit VarOrFuncDeclFilterCCC(Sema
&S
) : SemaRef(S
) {}
2959 bool ValidateCandidate(const TypoCorrection
&Candidate
) override
{
2960 NamedDecl
*ND
= Candidate
.getCorrectionDecl();
2961 if (ND
&& ((isa
<VarDecl
>(ND
) && ND
->getKind() == Decl::Var
) ||
2962 isa
<FunctionDecl
>(ND
))) {
2963 return SemaRef
.isDeclInScope(ND
, SemaRef
.getCurLexicalContext(),
2964 SemaRef
.getCurScope());
2969 std::unique_ptr
<CorrectionCandidateCallback
> clone() override
{
2970 return std::make_unique
<VarOrFuncDeclFilterCCC
>(*this);
2976 ExprResult
Sema::ActOnOpenMPIdExpression(Scope
*CurScope
,
2977 CXXScopeSpec
&ScopeSpec
,
2978 const DeclarationNameInfo
&Id
,
2979 OpenMPDirectiveKind Kind
) {
2980 LookupResult
Lookup(*this, Id
, LookupOrdinaryName
);
2981 LookupParsedName(Lookup
, CurScope
, &ScopeSpec
, true);
2983 if (Lookup
.isAmbiguous())
2987 if (!Lookup
.isSingleResult()) {
2988 VarDeclFilterCCC
CCC(*this);
2989 if (TypoCorrection Corrected
=
2990 CorrectTypo(Id
, LookupOrdinaryName
, CurScope
, nullptr, CCC
,
2991 CTK_ErrorRecovery
)) {
2992 diagnoseTypo(Corrected
,
2993 PDiag(Lookup
.empty()
2994 ? diag::err_undeclared_var_use_suggest
2995 : diag::err_omp_expected_var_arg_suggest
)
2997 VD
= Corrected
.getCorrectionDeclAs
<VarDecl
>();
2999 Diag(Id
.getLoc(), Lookup
.empty() ? diag::err_undeclared_var_use
3000 : diag::err_omp_expected_var_arg
)
3004 } else if (!(VD
= Lookup
.getAsSingle
<VarDecl
>())) {
3005 Diag(Id
.getLoc(), diag::err_omp_expected_var_arg
) << Id
.getName();
3006 Diag(Lookup
.getFoundDecl()->getLocation(), diag::note_declared_at
);
3009 Lookup
.suppressDiagnostics();
3011 // OpenMP [2.9.2, Syntax, C/C++]
3012 // Variables must be file-scope, namespace-scope, or static block-scope.
3013 if (Kind
== OMPD_threadprivate
&& !VD
->hasGlobalStorage()) {
3014 Diag(Id
.getLoc(), diag::err_omp_global_var_arg
)
3015 << getOpenMPDirectiveName(Kind
) << !VD
->isStaticLocal();
3017 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3018 Diag(VD
->getLocation(),
3019 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3024 VarDecl
*CanonicalVD
= VD
->getCanonicalDecl();
3025 NamedDecl
*ND
= CanonicalVD
;
3026 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3027 // A threadprivate directive for file-scope variables must appear outside
3028 // any definition or declaration.
3029 if (CanonicalVD
->getDeclContext()->isTranslationUnit() &&
3030 !getCurLexicalContext()->isTranslationUnit()) {
3031 Diag(Id
.getLoc(), diag::err_omp_var_scope
)
3032 << getOpenMPDirectiveName(Kind
) << VD
;
3034 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3035 Diag(VD
->getLocation(),
3036 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3040 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3041 // A threadprivate directive for static class member variables must appear
3042 // in the class definition, in the same scope in which the member
3043 // variables are declared.
3044 if (CanonicalVD
->isStaticDataMember() &&
3045 !CanonicalVD
->getDeclContext()->Equals(getCurLexicalContext())) {
3046 Diag(Id
.getLoc(), diag::err_omp_var_scope
)
3047 << getOpenMPDirectiveName(Kind
) << VD
;
3049 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3050 Diag(VD
->getLocation(),
3051 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3055 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3056 // A threadprivate directive for namespace-scope variables must appear
3057 // outside any definition or declaration other than the namespace
3058 // definition itself.
3059 if (CanonicalVD
->getDeclContext()->isNamespace() &&
3060 (!getCurLexicalContext()->isFileContext() ||
3061 !getCurLexicalContext()->Encloses(CanonicalVD
->getDeclContext()))) {
3062 Diag(Id
.getLoc(), diag::err_omp_var_scope
)
3063 << getOpenMPDirectiveName(Kind
) << VD
;
3065 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3066 Diag(VD
->getLocation(),
3067 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3071 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3072 // A threadprivate directive for static block-scope variables must appear
3073 // in the scope of the variable and not in a nested scope.
3074 if (CanonicalVD
->isLocalVarDecl() && CurScope
&&
3075 !isDeclInScope(ND
, getCurLexicalContext(), CurScope
)) {
3076 Diag(Id
.getLoc(), diag::err_omp_var_scope
)
3077 << getOpenMPDirectiveName(Kind
) << VD
;
3079 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3080 Diag(VD
->getLocation(),
3081 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3086 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3087 // A threadprivate directive must lexically precede all references to any
3088 // of the variables in its list.
3089 if (Kind
== OMPD_threadprivate
&& VD
->isUsed() &&
3090 !DSAStack
->isThreadPrivate(VD
)) {
3091 Diag(Id
.getLoc(), diag::err_omp_var_used
)
3092 << getOpenMPDirectiveName(Kind
) << VD
;
3096 QualType ExprType
= VD
->getType().getNonReferenceType();
3097 return DeclRefExpr::Create(Context
, NestedNameSpecifierLoc(),
3098 SourceLocation(), VD
,
3099 /*RefersToEnclosingVariableOrCapture=*/false,
3100 Id
.getLoc(), ExprType
, VK_LValue
);
3103 Sema::DeclGroupPtrTy
3104 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc
,
3105 ArrayRef
<Expr
*> VarList
) {
3106 if (OMPThreadPrivateDecl
*D
= CheckOMPThreadPrivateDecl(Loc
, VarList
)) {
3107 CurContext
->addDecl(D
);
3108 return DeclGroupPtrTy::make(DeclGroupRef(D
));
3114 class LocalVarRefChecker final
3115 : public ConstStmtVisitor
<LocalVarRefChecker
, bool> {
3119 bool VisitDeclRefExpr(const DeclRefExpr
*E
) {
3120 if (const auto *VD
= dyn_cast
<VarDecl
>(E
->getDecl())) {
3121 if (VD
->hasLocalStorage()) {
3122 SemaRef
.Diag(E
->getBeginLoc(),
3123 diag::err_omp_local_var_in_threadprivate_init
)
3124 << E
->getSourceRange();
3125 SemaRef
.Diag(VD
->getLocation(), diag::note_defined_here
)
3126 << VD
<< VD
->getSourceRange();
3132 bool VisitStmt(const Stmt
*S
) {
3133 for (const Stmt
*Child
: S
->children()) {
3134 if (Child
&& Visit(Child
))
3139 explicit LocalVarRefChecker(Sema
&SemaRef
) : SemaRef(SemaRef
) {}
3143 OMPThreadPrivateDecl
*
3144 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc
, ArrayRef
<Expr
*> VarList
) {
3145 SmallVector
<Expr
*, 8> Vars
;
3146 for (Expr
*RefExpr
: VarList
) {
3147 auto *DE
= cast
<DeclRefExpr
>(RefExpr
);
3148 auto *VD
= cast
<VarDecl
>(DE
->getDecl());
3149 SourceLocation ILoc
= DE
->getExprLoc();
3151 // Mark variable as used.
3152 VD
->setReferenced();
3153 VD
->markUsed(Context
);
3155 QualType QType
= VD
->getType();
3156 if (QType
->isDependentType() || QType
->isInstantiationDependentType()) {
3157 // It will be analyzed later.
3162 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3163 // A threadprivate variable must not have an incomplete type.
3164 if (RequireCompleteType(ILoc
, VD
->getType(),
3165 diag::err_omp_threadprivate_incomplete_type
)) {
3169 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3170 // A threadprivate variable must not have a reference type.
3171 if (VD
->getType()->isReferenceType()) {
3172 Diag(ILoc
, diag::err_omp_ref_type_arg
)
3173 << getOpenMPDirectiveName(OMPD_threadprivate
) << VD
->getType();
3175 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3176 Diag(VD
->getLocation(),
3177 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3182 // Check if this is a TLS variable. If TLS is not being supported, produce
3183 // the corresponding diagnostic.
3184 if ((VD
->getTLSKind() != VarDecl::TLS_None
&&
3185 !(VD
->hasAttr
<OMPThreadPrivateDeclAttr
>() &&
3186 getLangOpts().OpenMPUseTLS
&&
3187 getASTContext().getTargetInfo().isTLSSupported())) ||
3188 (VD
->getStorageClass() == SC_Register
&& VD
->hasAttr
<AsmLabelAttr
>() &&
3189 !VD
->isLocalVarDecl())) {
3190 Diag(ILoc
, diag::err_omp_var_thread_local
)
3191 << VD
<< ((VD
->getTLSKind() != VarDecl::TLS_None
) ? 0 : 1);
3193 VD
->isThisDeclarationADefinition(Context
) == VarDecl::DeclarationOnly
;
3194 Diag(VD
->getLocation(),
3195 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3200 // Check if initial value of threadprivate variable reference variable with
3201 // local storage (it is not supported by runtime).
3202 if (const Expr
*Init
= VD
->getAnyInitializer()) {
3203 LocalVarRefChecker
Checker(*this);
3204 if (Checker
.Visit(Init
))
3208 Vars
.push_back(RefExpr
);
3209 DSAStack
->addDSA(VD
, DE
, OMPC_threadprivate
);
3210 VD
->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3211 Context
, SourceRange(Loc
, Loc
)));
3212 if (ASTMutationListener
*ML
= Context
.getASTMutationListener())
3213 ML
->DeclarationMarkedOpenMPThreadPrivate(VD
);
3215 OMPThreadPrivateDecl
*D
= nullptr;
3216 if (!Vars
.empty()) {
3217 D
= OMPThreadPrivateDecl::Create(Context
, getCurLexicalContext(), Loc
,
3219 D
->setAccess(AS_public
);
3224 static OMPAllocateDeclAttr::AllocatorTypeTy
3225 getAllocatorKind(Sema
&S
, DSAStackTy
*Stack
, Expr
*Allocator
) {
3227 return OMPAllocateDeclAttr::OMPNullMemAlloc
;
3228 if (Allocator
->isTypeDependent() || Allocator
->isValueDependent() ||
3229 Allocator
->isInstantiationDependent() ||
3230 Allocator
->containsUnexpandedParameterPack())
3231 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
;
3232 auto AllocatorKindRes
= OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
;
3233 const Expr
*AE
= Allocator
->IgnoreParenImpCasts();
3234 for (int I
= 0; I
< OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
; ++I
) {
3235 auto AllocatorKind
= static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I
);
3236 const Expr
*DefAllocator
= Stack
->getAllocator(AllocatorKind
);
3237 llvm::FoldingSetNodeID AEId
, DAEId
;
3238 AE
->Profile(AEId
, S
.getASTContext(), /*Canonical=*/true);
3239 DefAllocator
->Profile(DAEId
, S
.getASTContext(), /*Canonical=*/true);
3240 if (AEId
== DAEId
) {
3241 AllocatorKindRes
= AllocatorKind
;
3245 return AllocatorKindRes
;
3248 static bool checkPreviousOMPAllocateAttribute(
3249 Sema
&S
, DSAStackTy
*Stack
, Expr
*RefExpr
, VarDecl
*VD
,
3250 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
, Expr
*Allocator
) {
3251 if (!VD
->hasAttr
<OMPAllocateDeclAttr
>())
3253 const auto *A
= VD
->getAttr
<OMPAllocateDeclAttr
>();
3254 Expr
*PrevAllocator
= A
->getAllocator();
3255 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind
=
3256 getAllocatorKind(S
, Stack
, PrevAllocator
);
3257 bool AllocatorsMatch
= AllocatorKind
== PrevAllocatorKind
;
3258 if (AllocatorsMatch
&&
3259 AllocatorKind
== OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
&&
3260 Allocator
&& PrevAllocator
) {
3261 const Expr
*AE
= Allocator
->IgnoreParenImpCasts();
3262 const Expr
*PAE
= PrevAllocator
->IgnoreParenImpCasts();
3263 llvm::FoldingSetNodeID AEId
, PAEId
;
3264 AE
->Profile(AEId
, S
.Context
, /*Canonical=*/true);
3265 PAE
->Profile(PAEId
, S
.Context
, /*Canonical=*/true);
3266 AllocatorsMatch
= AEId
== PAEId
;
3268 if (!AllocatorsMatch
) {
3269 SmallString
<256> AllocatorBuffer
;
3270 llvm::raw_svector_ostream
AllocatorStream(AllocatorBuffer
);
3272 Allocator
->printPretty(AllocatorStream
, nullptr, S
.getPrintingPolicy());
3273 SmallString
<256> PrevAllocatorBuffer
;
3274 llvm::raw_svector_ostream
PrevAllocatorStream(PrevAllocatorBuffer
);
3276 PrevAllocator
->printPretty(PrevAllocatorStream
, nullptr,
3277 S
.getPrintingPolicy());
3279 SourceLocation AllocatorLoc
=
3280 Allocator
? Allocator
->getExprLoc() : RefExpr
->getExprLoc();
3281 SourceRange AllocatorRange
=
3282 Allocator
? Allocator
->getSourceRange() : RefExpr
->getSourceRange();
3283 SourceLocation PrevAllocatorLoc
=
3284 PrevAllocator
? PrevAllocator
->getExprLoc() : A
->getLocation();
3285 SourceRange PrevAllocatorRange
=
3286 PrevAllocator
? PrevAllocator
->getSourceRange() : A
->getRange();
3287 S
.Diag(AllocatorLoc
, diag::warn_omp_used_different_allocator
)
3288 << (Allocator
? 1 : 0) << AllocatorStream
.str()
3289 << (PrevAllocator
? 1 : 0) << PrevAllocatorStream
.str()
3291 S
.Diag(PrevAllocatorLoc
, diag::note_omp_previous_allocator
)
3292 << PrevAllocatorRange
;
3299 applyOMPAllocateAttribute(Sema
&S
, VarDecl
*VD
,
3300 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
,
3301 Expr
*Allocator
, Expr
*Alignment
, SourceRange SR
) {
3302 if (VD
->hasAttr
<OMPAllocateDeclAttr
>())
3305 (Alignment
->isTypeDependent() || Alignment
->isValueDependent() ||
3306 Alignment
->isInstantiationDependent() ||
3307 Alignment
->containsUnexpandedParameterPack()))
3308 // Apply later when we have a usable value.
3311 (Allocator
->isTypeDependent() || Allocator
->isValueDependent() ||
3312 Allocator
->isInstantiationDependent() ||
3313 Allocator
->containsUnexpandedParameterPack()))
3315 auto *A
= OMPAllocateDeclAttr::CreateImplicit(S
.Context
, AllocatorKind
,
3316 Allocator
, Alignment
, SR
);
3318 if (ASTMutationListener
*ML
= S
.Context
.getASTMutationListener())
3319 ML
->DeclarationMarkedOpenMPAllocate(VD
, A
);
3322 Sema::DeclGroupPtrTy
3323 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc
, ArrayRef
<Expr
*> VarList
,
3324 ArrayRef
<OMPClause
*> Clauses
,
3325 DeclContext
*Owner
) {
3326 assert(Clauses
.size() <= 2 && "Expected at most two clauses.");
3327 Expr
*Alignment
= nullptr;
3328 Expr
*Allocator
= nullptr;
3329 if (Clauses
.empty()) {
3330 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3331 // allocate directives that appear in a target region must specify an
3332 // allocator clause unless a requires directive with the dynamic_allocators
3333 // clause is present in the same compilation unit.
3334 if (LangOpts
.OpenMPIsDevice
&&
3335 !DSAStack
->hasRequiresDeclWithClause
<OMPDynamicAllocatorsClause
>())
3336 targetDiag(Loc
, diag::err_expected_allocator_clause
);
3338 for (const OMPClause
*C
: Clauses
)
3339 if (const auto *AC
= dyn_cast
<OMPAllocatorClause
>(C
))
3340 Allocator
= AC
->getAllocator();
3341 else if (const auto *AC
= dyn_cast
<OMPAlignClause
>(C
))
3342 Alignment
= AC
->getAlignment();
3344 llvm_unreachable("Unexpected clause on allocate directive");
3346 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
=
3347 getAllocatorKind(*this, DSAStack
, Allocator
);
3348 SmallVector
<Expr
*, 8> Vars
;
3349 for (Expr
*RefExpr
: VarList
) {
3350 auto *DE
= cast
<DeclRefExpr
>(RefExpr
);
3351 auto *VD
= cast
<VarDecl
>(DE
->getDecl());
3353 // Check if this is a TLS variable or global register.
3354 if (VD
->getTLSKind() != VarDecl::TLS_None
||
3355 VD
->hasAttr
<OMPThreadPrivateDeclAttr
>() ||
3356 (VD
->getStorageClass() == SC_Register
&& VD
->hasAttr
<AsmLabelAttr
>() &&
3357 !VD
->isLocalVarDecl()))
3360 // If the used several times in the allocate directive, the same allocator
3362 if (checkPreviousOMPAllocateAttribute(*this, DSAStack
, RefExpr
, VD
,
3363 AllocatorKind
, Allocator
))
3366 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3367 // If a list item has a static storage type, the allocator expression in the
3368 // allocator clause must be a constant expression that evaluates to one of
3369 // the predefined memory allocator values.
3370 if (Allocator
&& VD
->hasGlobalStorage()) {
3371 if (AllocatorKind
== OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
) {
3372 Diag(Allocator
->getExprLoc(),
3373 diag::err_omp_expected_predefined_allocator
)
3374 << Allocator
->getSourceRange();
3375 bool IsDecl
= VD
->isThisDeclarationADefinition(Context
) ==
3376 VarDecl::DeclarationOnly
;
3377 Diag(VD
->getLocation(),
3378 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
3384 Vars
.push_back(RefExpr
);
3385 applyOMPAllocateAttribute(*this, VD
, AllocatorKind
, Allocator
, Alignment
,
3386 DE
->getSourceRange());
3391 Owner
= getCurLexicalContext();
3392 auto *D
= OMPAllocateDecl::Create(Context
, Owner
, Loc
, Vars
, Clauses
);
3393 D
->setAccess(AS_public
);
3395 return DeclGroupPtrTy::make(DeclGroupRef(D
));
3398 Sema::DeclGroupPtrTy
3399 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc
,
3400 ArrayRef
<OMPClause
*> ClauseList
) {
3401 OMPRequiresDecl
*D
= nullptr;
3402 if (!CurContext
->isFileContext()) {
3403 Diag(Loc
, diag::err_omp_invalid_scope
) << "requires";
3405 D
= CheckOMPRequiresDecl(Loc
, ClauseList
);
3407 CurContext
->addDecl(D
);
3408 DSAStack
->addRequiresDecl(D
);
3411 return DeclGroupPtrTy::make(DeclGroupRef(D
));
3414 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc
,
3415 OpenMPDirectiveKind DKind
,
3416 ArrayRef
<std::string
> Assumptions
,
3417 bool SkippedClauses
) {
3418 if (!SkippedClauses
&& Assumptions
.empty())
3419 Diag(Loc
, diag::err_omp_no_clause_for_directive
)
3420 << llvm::omp::getAllAssumeClauseOptions()
3421 << llvm::omp::getOpenMPDirectiveName(DKind
);
3423 auto *AA
= AssumptionAttr::Create(Context
, llvm::join(Assumptions
, ","), Loc
);
3424 if (DKind
== llvm::omp::Directive::OMPD_begin_assumes
) {
3425 OMPAssumeScoped
.push_back(AA
);
3429 // Global assumes without assumption clauses are ignored.
3430 if (Assumptions
.empty())
3433 assert(DKind
== llvm::omp::Directive::OMPD_assumes
&&
3434 "Unexpected omp assumption directive!");
3435 OMPAssumeGlobal
.push_back(AA
);
3437 // The OMPAssumeGlobal scope above will take care of new declarations but
3438 // we also want to apply the assumption to existing ones, e.g., to
3439 // declarations in included headers. To this end, we traverse all existing
3440 // declaration contexts and annotate function declarations here.
3441 SmallVector
<DeclContext
*, 8> DeclContexts
;
3442 auto *Ctx
= CurContext
;
3443 while (Ctx
->getLexicalParent())
3444 Ctx
= Ctx
->getLexicalParent();
3445 DeclContexts
.push_back(Ctx
);
3446 while (!DeclContexts
.empty()) {
3447 DeclContext
*DC
= DeclContexts
.pop_back_val();
3448 for (auto *SubDC
: DC
->decls()) {
3449 if (SubDC
->isInvalidDecl())
3451 if (auto *CTD
= dyn_cast
<ClassTemplateDecl
>(SubDC
)) {
3452 DeclContexts
.push_back(CTD
->getTemplatedDecl());
3453 llvm::append_range(DeclContexts
, CTD
->specializations());
3456 if (auto *DC
= dyn_cast
<DeclContext
>(SubDC
))
3457 DeclContexts
.push_back(DC
);
3458 if (auto *F
= dyn_cast
<FunctionDecl
>(SubDC
)) {
3466 void Sema::ActOnOpenMPEndAssumesDirective() {
3467 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3468 OMPAssumeScoped
.pop_back();
3471 OMPRequiresDecl
*Sema::CheckOMPRequiresDecl(SourceLocation Loc
,
3472 ArrayRef
<OMPClause
*> ClauseList
) {
3473 /// For target specific clauses, the requires directive cannot be
3474 /// specified after the handling of any of the target regions in the
3475 /// current compilation unit.
3476 ArrayRef
<SourceLocation
> TargetLocations
=
3477 DSAStack
->getEncounteredTargetLocs();
3478 SourceLocation AtomicLoc
= DSAStack
->getAtomicDirectiveLoc();
3479 if (!TargetLocations
.empty() || !AtomicLoc
.isInvalid()) {
3480 for (const OMPClause
*CNew
: ClauseList
) {
3481 // Check if any of the requires clauses affect target regions.
3482 if (isa
<OMPUnifiedSharedMemoryClause
>(CNew
) ||
3483 isa
<OMPUnifiedAddressClause
>(CNew
) ||
3484 isa
<OMPReverseOffloadClause
>(CNew
) ||
3485 isa
<OMPDynamicAllocatorsClause
>(CNew
)) {
3486 Diag(Loc
, diag::err_omp_directive_before_requires
)
3487 << "target" << getOpenMPClauseName(CNew
->getClauseKind());
3488 for (SourceLocation TargetLoc
: TargetLocations
) {
3489 Diag(TargetLoc
, diag::note_omp_requires_encountered_directive
)
3492 } else if (!AtomicLoc
.isInvalid() &&
3493 isa
<OMPAtomicDefaultMemOrderClause
>(CNew
)) {
3494 Diag(Loc
, diag::err_omp_directive_before_requires
)
3495 << "atomic" << getOpenMPClauseName(CNew
->getClauseKind());
3496 Diag(AtomicLoc
, diag::note_omp_requires_encountered_directive
)
3502 if (!DSAStack
->hasDuplicateRequiresClause(ClauseList
))
3503 return OMPRequiresDecl::Create(Context
, getCurLexicalContext(), Loc
,
3508 static void reportOriginalDsa(Sema
&SemaRef
, const DSAStackTy
*Stack
,
3510 const DSAStackTy::DSAVarData
&DVar
,
3511 bool IsLoopIterVar
) {
3513 SemaRef
.Diag(DVar
.RefExpr
->getExprLoc(), diag::note_omp_explicit_dsa
)
3514 << getOpenMPClauseName(DVar
.CKind
);
3518 PDSA_StaticMemberShared
,
3519 PDSA_StaticLocalVarShared
,
3520 PDSA_LoopIterVarPrivate
,
3521 PDSA_LoopIterVarLinear
,
3522 PDSA_LoopIterVarLastprivate
,
3523 PDSA_ConstVarShared
,
3524 PDSA_GlobalVarShared
,
3525 PDSA_TaskVarFirstprivate
,
3526 PDSA_LocalVarPrivate
,
3528 } Reason
= PDSA_Implicit
;
3529 bool ReportHint
= false;
3530 auto ReportLoc
= D
->getLocation();
3531 auto *VD
= dyn_cast
<VarDecl
>(D
);
3532 if (IsLoopIterVar
) {
3533 if (DVar
.CKind
== OMPC_private
)
3534 Reason
= PDSA_LoopIterVarPrivate
;
3535 else if (DVar
.CKind
== OMPC_lastprivate
)
3536 Reason
= PDSA_LoopIterVarLastprivate
;
3538 Reason
= PDSA_LoopIterVarLinear
;
3539 } else if (isOpenMPTaskingDirective(DVar
.DKind
) &&
3540 DVar
.CKind
== OMPC_firstprivate
) {
3541 Reason
= PDSA_TaskVarFirstprivate
;
3542 ReportLoc
= DVar
.ImplicitDSALoc
;
3543 } else if (VD
&& VD
->isStaticLocal())
3544 Reason
= PDSA_StaticLocalVarShared
;
3545 else if (VD
&& VD
->isStaticDataMember())
3546 Reason
= PDSA_StaticMemberShared
;
3547 else if (VD
&& VD
->isFileVarDecl())
3548 Reason
= PDSA_GlobalVarShared
;
3549 else if (D
->getType().isConstant(SemaRef
.getASTContext()))
3550 Reason
= PDSA_ConstVarShared
;
3551 else if (VD
&& VD
->isLocalVarDecl() && DVar
.CKind
== OMPC_private
) {
3553 Reason
= PDSA_LocalVarPrivate
;
3555 if (Reason
!= PDSA_Implicit
) {
3556 SemaRef
.Diag(ReportLoc
, diag::note_omp_predetermined_dsa
)
3557 << Reason
<< ReportHint
3558 << getOpenMPDirectiveName(Stack
->getCurrentDirective());
3559 } else if (DVar
.ImplicitDSALoc
.isValid()) {
3560 SemaRef
.Diag(DVar
.ImplicitDSALoc
, diag::note_omp_implicit_dsa
)
3561 << getOpenMPClauseName(DVar
.CKind
);
3565 static OpenMPMapClauseKind
3566 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M
,
3567 bool IsAggregateOrDeclareTarget
) {
3568 OpenMPMapClauseKind Kind
= OMPC_MAP_unknown
;
3570 case OMPC_DEFAULTMAP_MODIFIER_alloc
:
3571 Kind
= OMPC_MAP_alloc
;
3573 case OMPC_DEFAULTMAP_MODIFIER_to
:
3576 case OMPC_DEFAULTMAP_MODIFIER_from
:
3577 Kind
= OMPC_MAP_from
;
3579 case OMPC_DEFAULTMAP_MODIFIER_tofrom
:
3580 Kind
= OMPC_MAP_tofrom
;
3582 case OMPC_DEFAULTMAP_MODIFIER_present
:
3583 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3584 // If implicit-behavior is present, each variable referenced in the
3585 // construct in the category specified by variable-category is treated as if
3586 // it had been listed in a map clause with the map-type of alloc and
3587 // map-type-modifier of present.
3588 Kind
= OMPC_MAP_alloc
;
3590 case OMPC_DEFAULTMAP_MODIFIER_firstprivate
:
3591 case OMPC_DEFAULTMAP_MODIFIER_last
:
3592 llvm_unreachable("Unexpected defaultmap implicit behavior");
3593 case OMPC_DEFAULTMAP_MODIFIER_none
:
3594 case OMPC_DEFAULTMAP_MODIFIER_default
:
3595 case OMPC_DEFAULTMAP_MODIFIER_unknown
:
3596 // IsAggregateOrDeclareTarget could be true if:
3597 // 1. the implicit behavior for aggregate is tofrom
3598 // 2. it's a declare target link
3599 if (IsAggregateOrDeclareTarget
) {
3600 Kind
= OMPC_MAP_tofrom
;
3603 llvm_unreachable("Unexpected defaultmap implicit behavior");
3605 assert(Kind
!= OMPC_MAP_unknown
&& "Expect map kind to be known");
3610 class DSAAttrChecker final
: public StmtVisitor
<DSAAttrChecker
, void> {
3613 bool ErrorFound
= false;
3614 bool TryCaptureCXXThisMembers
= false;
3615 CapturedStmt
*CS
= nullptr;
3616 const static unsigned DefaultmapKindNum
= OMPC_DEFAULTMAP_pointer
+ 1;
3617 llvm::SmallVector
<Expr
*, 4> ImplicitFirstprivate
;
3618 llvm::SmallVector
<Expr
*, 4> ImplicitPrivate
;
3619 llvm::SmallVector
<Expr
*, 4> ImplicitMap
[DefaultmapKindNum
][OMPC_MAP_delete
];
3620 llvm::SmallVector
<OpenMPMapModifierKind
, NumberOfOMPMapClauseModifiers
>
3621 ImplicitMapModifier
[DefaultmapKindNum
];
3622 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA
;
3623 llvm::SmallDenseSet
<const ValueDecl
*, 4> ImplicitDeclarations
;
3625 void VisitSubCaptures(OMPExecutableDirective
*S
) {
3626 // Check implicitly captured variables.
3627 if (!S
->hasAssociatedStmt() || !S
->getAssociatedStmt())
3629 if (S
->getDirectiveKind() == OMPD_atomic
||
3630 S
->getDirectiveKind() == OMPD_critical
||
3631 S
->getDirectiveKind() == OMPD_section
||
3632 S
->getDirectiveKind() == OMPD_master
||
3633 S
->getDirectiveKind() == OMPD_masked
||
3634 isOpenMPLoopTransformationDirective(S
->getDirectiveKind())) {
3635 Visit(S
->getAssociatedStmt());
3638 visitSubCaptures(S
->getInnermostCapturedStmt());
3639 // Try to capture inner this->member references to generate correct mappings
3641 if (TryCaptureCXXThisMembers
||
3642 (isOpenMPTargetExecutionDirective(Stack
->getCurrentDirective()) &&
3643 llvm::any_of(S
->getInnermostCapturedStmt()->captures(),
3644 [](const CapturedStmt::Capture
&C
) {
3645 return C
.capturesThis();
3647 bool SavedTryCaptureCXXThisMembers
= TryCaptureCXXThisMembers
;
3648 TryCaptureCXXThisMembers
= true;
3649 Visit(S
->getInnermostCapturedStmt()->getCapturedStmt());
3650 TryCaptureCXXThisMembers
= SavedTryCaptureCXXThisMembers
;
3652 // In tasks firstprivates are not captured anymore, need to analyze them
3654 if (isOpenMPTaskingDirective(S
->getDirectiveKind()) &&
3655 !isOpenMPTaskLoopDirective(S
->getDirectiveKind())) {
3656 for (OMPClause
*C
: S
->clauses())
3657 if (auto *FC
= dyn_cast
<OMPFirstprivateClause
>(C
)) {
3658 for (Expr
*Ref
: FC
->varlists())
3665 void VisitDeclRefExpr(DeclRefExpr
*E
) {
3666 if (TryCaptureCXXThisMembers
|| E
->isTypeDependent() ||
3667 E
->isValueDependent() || E
->containsUnexpandedParameterPack() ||
3668 E
->isInstantiationDependent())
3670 if (auto *VD
= dyn_cast
<VarDecl
>(E
->getDecl())) {
3671 // Check the datasharing rules for the expressions in the clauses.
3672 if (!CS
|| (isa
<OMPCapturedExprDecl
>(VD
) && !CS
->capturesVariable(VD
) &&
3673 !Stack
->getTopDSA(VD
, /*FromParent=*/false).RefExpr
&&
3674 !Stack
->isImplicitDefaultFirstprivateFD(VD
))) {
3675 if (auto *CED
= dyn_cast
<OMPCapturedExprDecl
>(VD
))
3676 if (!CED
->hasAttr
<OMPCaptureNoInitAttr
>()) {
3677 Visit(CED
->getInit());
3680 } else if (VD
->isImplicit() || isa
<OMPCapturedExprDecl
>(VD
))
3681 // Do not analyze internal variables and do not enclose them into
3682 // implicit clauses.
3683 if (!Stack
->isImplicitDefaultFirstprivateFD(VD
))
3685 VD
= VD
->getCanonicalDecl();
3686 // Skip internally declared variables.
3687 if (VD
->hasLocalStorage() && CS
&& !CS
->capturesVariable(VD
) &&
3688 !Stack
->isImplicitDefaultFirstprivateFD(VD
) &&
3689 !Stack
->isImplicitTaskFirstprivate(VD
))
3691 // Skip allocators in uses_allocators clauses.
3692 if (Stack
->isUsesAllocatorsDecl(VD
))
3695 DSAStackTy::DSAVarData DVar
= Stack
->getTopDSA(VD
, /*FromParent=*/false);
3696 // Check if the variable has explicit DSA set and stop analysis if it so.
3697 if (DVar
.RefExpr
|| !ImplicitDeclarations
.insert(VD
).second
)
3700 // Skip internally declared static variables.
3701 llvm::Optional
<OMPDeclareTargetDeclAttr::MapTypeTy
> Res
=
3702 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD
);
3703 if (VD
->hasGlobalStorage() && CS
&& !CS
->capturesVariable(VD
) &&
3704 (Stack
->hasRequiresDeclWithClause
<OMPUnifiedSharedMemoryClause
>() ||
3705 !Res
|| *Res
!= OMPDeclareTargetDeclAttr::MT_Link
) &&
3706 !Stack
->isImplicitDefaultFirstprivateFD(VD
) &&
3707 !Stack
->isImplicitTaskFirstprivate(VD
))
3710 SourceLocation ELoc
= E
->getExprLoc();
3711 OpenMPDirectiveKind DKind
= Stack
->getCurrentDirective();
3712 // The default(none) clause requires that each variable that is referenced
3713 // in the construct, and does not have a predetermined data-sharing
3714 // attribute, must have its data-sharing attribute explicitly determined
3715 // by being listed in a data-sharing attribute clause.
3716 if (DVar
.CKind
== OMPC_unknown
&&
3717 (Stack
->getDefaultDSA() == DSA_none
||
3718 Stack
->getDefaultDSA() == DSA_private
||
3719 Stack
->getDefaultDSA() == DSA_firstprivate
) &&
3720 isImplicitOrExplicitTaskingRegion(DKind
) &&
3721 VarsWithInheritedDSA
.count(VD
) == 0) {
3722 bool InheritedDSA
= Stack
->getDefaultDSA() == DSA_none
;
3723 if (!InheritedDSA
&& (Stack
->getDefaultDSA() == DSA_firstprivate
||
3724 Stack
->getDefaultDSA() == DSA_private
)) {
3725 DSAStackTy::DSAVarData DVar
=
3726 Stack
->getImplicitDSA(VD
, /*FromParent=*/false);
3727 InheritedDSA
= DVar
.CKind
== OMPC_unknown
;
3730 VarsWithInheritedDSA
[VD
] = E
;
3731 if (Stack
->getDefaultDSA() == DSA_none
)
3735 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3736 // If implicit-behavior is none, each variable referenced in the
3737 // construct that does not have a predetermined data-sharing attribute
3738 // and does not appear in a to or link clause on a declare target
3739 // directive must be listed in a data-mapping attribute clause, a
3740 // data-sharing attribute clause (including a data-sharing attribute
3741 // clause on a combined construct where target. is one of the
3742 // constituent constructs), or an is_device_ptr clause.
3743 OpenMPDefaultmapClauseKind ClauseKind
=
3744 getVariableCategoryFromDecl(SemaRef
.getLangOpts(), VD
);
3745 if (SemaRef
.getLangOpts().OpenMP
>= 50) {
3746 bool IsModifierNone
= Stack
->getDefaultmapModifier(ClauseKind
) ==
3747 OMPC_DEFAULTMAP_MODIFIER_none
;
3748 if (DVar
.CKind
== OMPC_unknown
&& IsModifierNone
&&
3749 VarsWithInheritedDSA
.count(VD
) == 0 && !Res
) {
3750 // Only check for data-mapping attribute and is_device_ptr here
3751 // since we have already make sure that the declaration does not
3752 // have a data-sharing attribute above
3753 if (!Stack
->checkMappableExprComponentListsForDecl(
3754 VD
, /*CurrentRegionOnly=*/true,
3755 [VD
](OMPClauseMappableExprCommon::MappableExprComponentListRef
3758 auto MI
= MapExprComponents
.rbegin();
3759 auto ME
= MapExprComponents
.rend();
3760 return MI
!= ME
&& MI
->getAssociatedDeclaration() == VD
;
3762 VarsWithInheritedDSA
[VD
] = E
;
3767 if (SemaRef
.getLangOpts().OpenMP
> 50) {
3768 bool IsModifierPresent
= Stack
->getDefaultmapModifier(ClauseKind
) ==
3769 OMPC_DEFAULTMAP_MODIFIER_present
;
3770 if (IsModifierPresent
) {
3771 if (!llvm::is_contained(ImplicitMapModifier
[ClauseKind
],
3772 OMPC_MAP_MODIFIER_present
)) {
3773 ImplicitMapModifier
[ClauseKind
].push_back(
3774 OMPC_MAP_MODIFIER_present
);
3779 if (isOpenMPTargetExecutionDirective(DKind
) &&
3780 !Stack
->isLoopControlVariable(VD
).first
) {
3781 if (!Stack
->checkMappableExprComponentListsForDecl(
3782 VD
, /*CurrentRegionOnly=*/true,
3783 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3786 if (SemaRef
.LangOpts
.OpenMP
>= 50)
3787 return !StackComponents
.empty();
3788 // Variable is used if it has been marked as an array, array
3789 // section, array shaping or the variable iself.
3790 return StackComponents
.size() == 1 ||
3792 llvm::drop_begin(llvm::reverse(StackComponents
)),
3793 [](const OMPClauseMappableExprCommon::
3794 MappableComponent
&MC
) {
3795 return MC
.getAssociatedDeclaration() ==
3797 (isa
<OMPArraySectionExpr
>(
3798 MC
.getAssociatedExpression()) ||
3799 isa
<OMPArrayShapingExpr
>(
3800 MC
.getAssociatedExpression()) ||
3801 isa
<ArraySubscriptExpr
>(
3802 MC
.getAssociatedExpression()));
3805 bool IsFirstprivate
= false;
3806 // By default lambdas are captured as firstprivates.
3807 if (const auto *RD
=
3808 VD
->getType().getNonReferenceType()->getAsCXXRecordDecl())
3809 IsFirstprivate
= RD
->isLambda();
3811 IsFirstprivate
|| (Stack
->mustBeFirstprivate(ClauseKind
) && !Res
);
3812 if (IsFirstprivate
) {
3813 ImplicitFirstprivate
.emplace_back(E
);
3815 OpenMPDefaultmapClauseModifier M
=
3816 Stack
->getDefaultmapModifier(ClauseKind
);
3817 OpenMPMapClauseKind Kind
= getMapClauseKindFromModifier(
3818 M
, ClauseKind
== OMPC_DEFAULTMAP_aggregate
|| Res
);
3819 ImplicitMap
[ClauseKind
][Kind
].emplace_back(E
);
3825 // OpenMP [2.9.3.6, Restrictions, p.2]
3826 // A list item that appears in a reduction clause of the innermost
3827 // enclosing worksharing or parallel construct may not be accessed in an
3829 DVar
= Stack
->hasInnermostDSA(
3831 [](OpenMPClauseKind C
, bool AppliedToPointee
) {
3832 return C
== OMPC_reduction
&& !AppliedToPointee
;
3834 [](OpenMPDirectiveKind K
) {
3835 return isOpenMPParallelDirective(K
) ||
3836 isOpenMPWorksharingDirective(K
) || isOpenMPTeamsDirective(K
);
3838 /*FromParent=*/true);
3839 if (isOpenMPTaskingDirective(DKind
) && DVar
.CKind
== OMPC_reduction
) {
3841 SemaRef
.Diag(ELoc
, diag::err_omp_reduction_in_task
);
3842 reportOriginalDsa(SemaRef
, Stack
, VD
, DVar
);
3846 // Define implicit data-sharing attributes for task.
3847 DVar
= Stack
->getImplicitDSA(VD
, /*FromParent=*/false);
3848 if (((isOpenMPTaskingDirective(DKind
) && DVar
.CKind
!= OMPC_shared
) ||
3849 (((Stack
->getDefaultDSA() == DSA_firstprivate
&&
3850 DVar
.CKind
== OMPC_firstprivate
) ||
3851 (Stack
->getDefaultDSA() == DSA_private
&&
3852 DVar
.CKind
== OMPC_private
)) &&
3854 !Stack
->isLoopControlVariable(VD
).first
) {
3855 if (Stack
->getDefaultDSA() == DSA_private
)
3856 ImplicitPrivate
.push_back(E
);
3858 ImplicitFirstprivate
.push_back(E
);
3862 // Store implicitly used globals with declare target link for parent
3864 if (!isOpenMPTargetExecutionDirective(DKind
) && Res
&&
3865 *Res
== OMPDeclareTargetDeclAttr::MT_Link
) {
3866 Stack
->addToParentTargetRegionLinkGlobals(E
);
3871 void VisitMemberExpr(MemberExpr
*E
) {
3872 if (E
->isTypeDependent() || E
->isValueDependent() ||
3873 E
->containsUnexpandedParameterPack() || E
->isInstantiationDependent())
3875 auto *FD
= dyn_cast
<FieldDecl
>(E
->getMemberDecl());
3876 OpenMPDirectiveKind DKind
= Stack
->getCurrentDirective();
3877 if (auto *TE
= dyn_cast
<CXXThisExpr
>(E
->getBase()->IgnoreParenCasts())) {
3880 DSAStackTy::DSAVarData DVar
= Stack
->getTopDSA(FD
, /*FromParent=*/false);
3881 // Check if the variable has explicit DSA set and stop analysis if it
3883 if (DVar
.RefExpr
|| !ImplicitDeclarations
.insert(FD
).second
)
3886 if (isOpenMPTargetExecutionDirective(DKind
) &&
3887 !Stack
->isLoopControlVariable(FD
).first
&&
3888 !Stack
->checkMappableExprComponentListsForDecl(
3889 FD
, /*CurrentRegionOnly=*/true,
3890 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3893 return isa
<CXXThisExpr
>(
3895 StackComponents
.back().getAssociatedExpression())
3899 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3900 // A bit-field cannot appear in a map clause.
3902 if (FD
->isBitField())
3905 // Check to see if the member expression is referencing a class that
3906 // has already been explicitly mapped
3907 if (Stack
->isClassPreviouslyMapped(TE
->getType()))
3910 OpenMPDefaultmapClauseModifier Modifier
=
3911 Stack
->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate
);
3912 OpenMPDefaultmapClauseKind ClauseKind
=
3913 getVariableCategoryFromDecl(SemaRef
.getLangOpts(), FD
);
3914 OpenMPMapClauseKind Kind
= getMapClauseKindFromModifier(
3915 Modifier
, /*IsAggregateOrDeclareTarget*/ true);
3916 ImplicitMap
[ClauseKind
][Kind
].emplace_back(E
);
3920 SourceLocation ELoc
= E
->getExprLoc();
3921 // OpenMP [2.9.3.6, Restrictions, p.2]
3922 // A list item that appears in a reduction clause of the innermost
3923 // enclosing worksharing or parallel construct may not be accessed in
3924 // an explicit task.
3925 DVar
= Stack
->hasInnermostDSA(
3927 [](OpenMPClauseKind C
, bool AppliedToPointee
) {
3928 return C
== OMPC_reduction
&& !AppliedToPointee
;
3930 [](OpenMPDirectiveKind K
) {
3931 return isOpenMPParallelDirective(K
) ||
3932 isOpenMPWorksharingDirective(K
) || isOpenMPTeamsDirective(K
);
3934 /*FromParent=*/true);
3935 if (isOpenMPTaskingDirective(DKind
) && DVar
.CKind
== OMPC_reduction
) {
3937 SemaRef
.Diag(ELoc
, diag::err_omp_reduction_in_task
);
3938 reportOriginalDsa(SemaRef
, Stack
, FD
, DVar
);
3942 // Define implicit data-sharing attributes for task.
3943 DVar
= Stack
->getImplicitDSA(FD
, /*FromParent=*/false);
3944 if (isOpenMPTaskingDirective(DKind
) && DVar
.CKind
!= OMPC_shared
&&
3945 !Stack
->isLoopControlVariable(FD
).first
) {
3946 // Check if there is a captured expression for the current field in the
3947 // region. Do not mark it as firstprivate unless there is no captured
3949 // TODO: try to make it firstprivate.
3950 if (DVar
.CKind
!= OMPC_unknown
)
3951 ImplicitFirstprivate
.push_back(E
);
3955 if (isOpenMPTargetExecutionDirective(DKind
)) {
3956 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents
;
3957 if (!checkMapClauseExpressionBase(SemaRef
, E
, CurComponents
, OMPC_map
,
3958 Stack
->getCurrentDirective(),
3959 /*NoDiagnose=*/true))
3961 const auto *VD
= cast
<ValueDecl
>(
3962 CurComponents
.back().getAssociatedDeclaration()->getCanonicalDecl());
3963 if (!Stack
->checkMappableExprComponentListsForDecl(
3964 VD
, /*CurrentRegionOnly=*/true,
3966 OMPClauseMappableExprCommon::MappableExprComponentListRef
3969 auto CCI
= CurComponents
.rbegin();
3970 auto CCE
= CurComponents
.rend();
3971 for (const auto &SC
: llvm::reverse(StackComponents
)) {
3972 // Do both expressions have the same kind?
3973 if (CCI
->getAssociatedExpression()->getStmtClass() !=
3974 SC
.getAssociatedExpression()->getStmtClass())
3975 if (!((isa
<OMPArraySectionExpr
>(
3976 SC
.getAssociatedExpression()) ||
3977 isa
<OMPArrayShapingExpr
>(
3978 SC
.getAssociatedExpression())) &&
3979 isa
<ArraySubscriptExpr
>(
3980 CCI
->getAssociatedExpression())))
3983 const Decl
*CCD
= CCI
->getAssociatedDeclaration();
3984 const Decl
*SCD
= SC
.getAssociatedDeclaration();
3985 CCD
= CCD
? CCD
->getCanonicalDecl() : nullptr;
3986 SCD
= SCD
? SCD
->getCanonicalDecl() : nullptr;
3989 std::advance(CCI
, 1);
3995 Visit(E
->getBase());
3997 } else if (!TryCaptureCXXThisMembers
) {
3998 Visit(E
->getBase());
4001 void VisitOMPExecutableDirective(OMPExecutableDirective
*S
) {
4002 for (OMPClause
*C
: S
->clauses()) {
4003 // Skip analysis of arguments of private clauses for task|target
4005 if (isa_and_nonnull
<OMPPrivateClause
>(C
))
4007 // Skip analysis of arguments of implicitly defined firstprivate clause
4008 // for task|target directives.
4009 // Skip analysis of arguments of implicitly defined map clause for target
4011 if (C
&& !((isa
<OMPFirstprivateClause
>(C
) || isa
<OMPMapClause
>(C
)) &&
4013 !isOpenMPTaskingDirective(Stack
->getCurrentDirective()))) {
4014 for (Stmt
*CC
: C
->children()) {
4020 // Check implicitly captured variables.
4021 VisitSubCaptures(S
);
4024 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective
*S
) {
4025 // Loop transformation directives do not introduce data sharing
4029 void VisitCallExpr(CallExpr
*S
) {
4030 for (Stmt
*C
: S
->arguments()) {
4032 // Check implicitly captured variables in the task-based directives to
4033 // check if they must be firstprivatized.
4037 if (Expr
*Callee
= S
->getCallee())
4038 if (auto *CE
= dyn_cast
<MemberExpr
>(Callee
->IgnoreParenImpCasts()))
4039 Visit(CE
->getBase());
4041 void VisitStmt(Stmt
*S
) {
4042 for (Stmt
*C
: S
->children()) {
4044 // Check implicitly captured variables in the task-based directives to
4045 // check if they must be firstprivatized.
4051 void visitSubCaptures(CapturedStmt
*S
) {
4052 for (const CapturedStmt::Capture
&Cap
: S
->captures()) {
4053 if (!Cap
.capturesVariable() && !Cap
.capturesVariableByCopy())
4055 VarDecl
*VD
= Cap
.getCapturedVar();
4056 // Do not try to map the variable if it or its sub-component was mapped
4058 if (isOpenMPTargetExecutionDirective(Stack
->getCurrentDirective()) &&
4059 Stack
->checkMappableExprComponentListsForDecl(
4060 VD
, /*CurrentRegionOnly=*/true,
4061 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
,
4062 OpenMPClauseKind
) { return true; }))
4064 DeclRefExpr
*DRE
= buildDeclRefExpr(
4065 SemaRef
, VD
, VD
->getType().getNonLValueExprType(SemaRef
.Context
),
4066 Cap
.getLocation(), /*RefersToCapture=*/true);
4070 bool isErrorFound() const { return ErrorFound
; }
4071 ArrayRef
<Expr
*> getImplicitFirstprivate() const {
4072 return ImplicitFirstprivate
;
4074 ArrayRef
<Expr
*> getImplicitPrivate() const { return ImplicitPrivate
; }
4075 ArrayRef
<Expr
*> getImplicitMap(OpenMPDefaultmapClauseKind DK
,
4076 OpenMPMapClauseKind MK
) const {
4077 return ImplicitMap
[DK
][MK
];
4079 ArrayRef
<OpenMPMapModifierKind
>
4080 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind
) const {
4081 return ImplicitMapModifier
[Kind
];
4083 const Sema::VarsWithInheritedDSAType
&getVarsWithInheritedDSA() const {
4084 return VarsWithInheritedDSA
;
4087 DSAAttrChecker(DSAStackTy
*S
, Sema
&SemaRef
, CapturedStmt
*CS
)
4088 : Stack(S
), SemaRef(SemaRef
), ErrorFound(false), CS(CS
) {
4089 // Process declare target link variables for the target directives.
4090 if (isOpenMPTargetExecutionDirective(S
->getCurrentDirective())) {
4091 for (DeclRefExpr
*E
: Stack
->getLinkGlobals())
4098 static void handleDeclareVariantConstructTrait(DSAStackTy
*Stack
,
4099 OpenMPDirectiveKind DKind
,
4101 SmallVector
<llvm::omp::TraitProperty
, 8> Traits
;
4102 if (isOpenMPTargetExecutionDirective(DKind
))
4103 Traits
.emplace_back(llvm::omp::TraitProperty::construct_target_target
);
4104 if (isOpenMPTeamsDirective(DKind
))
4105 Traits
.emplace_back(llvm::omp::TraitProperty::construct_teams_teams
);
4106 if (isOpenMPParallelDirective(DKind
))
4107 Traits
.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel
);
4108 if (isOpenMPWorksharingDirective(DKind
))
4109 Traits
.emplace_back(llvm::omp::TraitProperty::construct_for_for
);
4110 if (isOpenMPSimdDirective(DKind
))
4111 Traits
.emplace_back(llvm::omp::TraitProperty::construct_simd_simd
);
4112 Stack
->handleConstructTrait(Traits
, ScopeEntry
);
4115 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind
, Scope
*CurScope
) {
4118 case OMPD_parallel_for
:
4119 case OMPD_parallel_for_simd
:
4120 case OMPD_parallel_sections
:
4121 case OMPD_parallel_master
:
4122 case OMPD_parallel_masked
:
4123 case OMPD_parallel_loop
:
4125 case OMPD_teams_distribute
:
4126 case OMPD_teams_distribute_simd
: {
4127 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4128 QualType KmpInt32PtrTy
=
4129 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4130 Sema::CapturedParamNameType Params
[] = {
4131 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4132 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4133 std::make_pair(StringRef(), QualType()) // __context with shared vars
4135 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4139 case OMPD_target_teams
:
4140 case OMPD_target_parallel
:
4141 case OMPD_target_parallel_for
:
4142 case OMPD_target_parallel_for_simd
:
4143 case OMPD_target_teams_loop
:
4144 case OMPD_target_parallel_loop
:
4145 case OMPD_target_teams_distribute
:
4146 case OMPD_target_teams_distribute_simd
: {
4147 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4148 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4149 QualType KmpInt32PtrTy
=
4150 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4151 QualType Args
[] = {VoidPtrTy
};
4152 FunctionProtoType::ExtProtoInfo EPI
;
4153 EPI
.Variadic
= true;
4154 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4155 Sema::CapturedParamNameType Params
[] = {
4156 std::make_pair(".global_tid.", KmpInt32Ty
),
4157 std::make_pair(".part_id.", KmpInt32PtrTy
),
4158 std::make_pair(".privates.", VoidPtrTy
),
4161 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4162 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4163 std::make_pair(StringRef(), QualType()) // __context with shared vars
4165 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4166 Params
, /*OpenMPCaptureLevel=*/0);
4167 // Mark this captured region as inlined, because we don't use outlined
4168 // function directly.
4169 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4170 AlwaysInlineAttr::CreateImplicit(
4171 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4172 AlwaysInlineAttr::Keyword_forceinline
));
4173 Sema::CapturedParamNameType ParamsTarget
[] = {
4174 std::make_pair(StringRef(), QualType()) // __context with shared vars
4176 // Start a captured region for 'target' with no implicit parameters.
4177 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4178 ParamsTarget
, /*OpenMPCaptureLevel=*/1);
4179 Sema::CapturedParamNameType ParamsTeamsOrParallel
[] = {
4180 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4181 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4182 std::make_pair(StringRef(), QualType()) // __context with shared vars
4184 // Start a captured region for 'teams' or 'parallel'. Both regions have
4185 // the same implicit parameters.
4186 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4187 ParamsTeamsOrParallel
, /*OpenMPCaptureLevel=*/2);
4191 case OMPD_target_simd
: {
4192 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4193 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4194 QualType KmpInt32PtrTy
=
4195 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4196 QualType Args
[] = {VoidPtrTy
};
4197 FunctionProtoType::ExtProtoInfo EPI
;
4198 EPI
.Variadic
= true;
4199 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4200 Sema::CapturedParamNameType Params
[] = {
4201 std::make_pair(".global_tid.", KmpInt32Ty
),
4202 std::make_pair(".part_id.", KmpInt32PtrTy
),
4203 std::make_pair(".privates.", VoidPtrTy
),
4206 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4207 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4208 std::make_pair(StringRef(), QualType()) // __context with shared vars
4210 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4211 Params
, /*OpenMPCaptureLevel=*/0);
4212 // Mark this captured region as inlined, because we don't use outlined
4213 // function directly.
4214 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4215 AlwaysInlineAttr::CreateImplicit(
4216 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4217 AlwaysInlineAttr::Keyword_forceinline
));
4218 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4219 std::make_pair(StringRef(), QualType()),
4220 /*OpenMPCaptureLevel=*/1);
4232 // TODO: 'loop' may require additional parameters depending on the binding.
4233 // Treat similar to OMPD_simd/OMPD_for for now.
4239 case OMPD_taskgroup
:
4240 case OMPD_distribute
:
4241 case OMPD_distribute_simd
:
4243 case OMPD_target_data
:
4244 case OMPD_dispatch
: {
4245 Sema::CapturedParamNameType Params
[] = {
4246 std::make_pair(StringRef(), QualType()) // __context with shared vars
4248 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4253 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4254 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4255 QualType KmpInt32PtrTy
=
4256 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4257 QualType Args
[] = {VoidPtrTy
};
4258 FunctionProtoType::ExtProtoInfo EPI
;
4259 EPI
.Variadic
= true;
4260 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4261 Sema::CapturedParamNameType Params
[] = {
4262 std::make_pair(".global_tid.", KmpInt32Ty
),
4263 std::make_pair(".part_id.", KmpInt32PtrTy
),
4264 std::make_pair(".privates.", VoidPtrTy
),
4267 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4268 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4269 std::make_pair(StringRef(), QualType()) // __context with shared vars
4271 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4273 // Mark this captured region as inlined, because we don't use outlined
4274 // function directly.
4275 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4276 AlwaysInlineAttr::CreateImplicit(
4277 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4278 AlwaysInlineAttr::Keyword_forceinline
));
4282 case OMPD_taskloop_simd
:
4283 case OMPD_master_taskloop
:
4284 case OMPD_masked_taskloop
:
4285 case OMPD_masked_taskloop_simd
:
4286 case OMPD_master_taskloop_simd
: {
4287 QualType KmpInt32Ty
=
4288 Context
.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4290 QualType KmpUInt64Ty
=
4291 Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4293 QualType KmpInt64Ty
=
4294 Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4296 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4297 QualType KmpInt32PtrTy
=
4298 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4299 QualType Args
[] = {VoidPtrTy
};
4300 FunctionProtoType::ExtProtoInfo EPI
;
4301 EPI
.Variadic
= true;
4302 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4303 Sema::CapturedParamNameType Params
[] = {
4304 std::make_pair(".global_tid.", KmpInt32Ty
),
4305 std::make_pair(".part_id.", KmpInt32PtrTy
),
4306 std::make_pair(".privates.", VoidPtrTy
),
4309 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4310 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4311 std::make_pair(".lb.", KmpUInt64Ty
),
4312 std::make_pair(".ub.", KmpUInt64Ty
),
4313 std::make_pair(".st.", KmpInt64Ty
),
4314 std::make_pair(".liter.", KmpInt32Ty
),
4315 std::make_pair(".reductions.", VoidPtrTy
),
4316 std::make_pair(StringRef(), QualType()) // __context with shared vars
4318 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4320 // Mark this captured region as inlined, because we don't use outlined
4321 // function directly.
4322 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4323 AlwaysInlineAttr::CreateImplicit(
4324 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4325 AlwaysInlineAttr::Keyword_forceinline
));
4328 case OMPD_parallel_masked_taskloop
:
4329 case OMPD_parallel_masked_taskloop_simd
:
4330 case OMPD_parallel_master_taskloop
:
4331 case OMPD_parallel_master_taskloop_simd
: {
4332 QualType KmpInt32Ty
=
4333 Context
.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4335 QualType KmpUInt64Ty
=
4336 Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4338 QualType KmpInt64Ty
=
4339 Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4341 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4342 QualType KmpInt32PtrTy
=
4343 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4344 Sema::CapturedParamNameType ParamsParallel
[] = {
4345 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4346 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4347 std::make_pair(StringRef(), QualType()) // __context with shared vars
4349 // Start a captured region for 'parallel'.
4350 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4351 ParamsParallel
, /*OpenMPCaptureLevel=*/0);
4352 QualType Args
[] = {VoidPtrTy
};
4353 FunctionProtoType::ExtProtoInfo EPI
;
4354 EPI
.Variadic
= true;
4355 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4356 Sema::CapturedParamNameType Params
[] = {
4357 std::make_pair(".global_tid.", KmpInt32Ty
),
4358 std::make_pair(".part_id.", KmpInt32PtrTy
),
4359 std::make_pair(".privates.", VoidPtrTy
),
4362 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4363 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4364 std::make_pair(".lb.", KmpUInt64Ty
),
4365 std::make_pair(".ub.", KmpUInt64Ty
),
4366 std::make_pair(".st.", KmpInt64Ty
),
4367 std::make_pair(".liter.", KmpInt32Ty
),
4368 std::make_pair(".reductions.", VoidPtrTy
),
4369 std::make_pair(StringRef(), QualType()) // __context with shared vars
4371 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4372 Params
, /*OpenMPCaptureLevel=*/1);
4373 // Mark this captured region as inlined, because we don't use outlined
4374 // function directly.
4375 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4376 AlwaysInlineAttr::CreateImplicit(
4377 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4378 AlwaysInlineAttr::Keyword_forceinline
));
4381 case OMPD_distribute_parallel_for_simd
:
4382 case OMPD_distribute_parallel_for
: {
4383 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4384 QualType KmpInt32PtrTy
=
4385 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4386 Sema::CapturedParamNameType Params
[] = {
4387 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4388 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4389 std::make_pair(".previous.lb.", Context
.getSizeType().withConst()),
4390 std::make_pair(".previous.ub.", Context
.getSizeType().withConst()),
4391 std::make_pair(StringRef(), QualType()) // __context with shared vars
4393 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4397 case OMPD_target_teams_distribute_parallel_for
:
4398 case OMPD_target_teams_distribute_parallel_for_simd
: {
4399 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4400 QualType KmpInt32PtrTy
=
4401 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4402 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4404 QualType Args
[] = {VoidPtrTy
};
4405 FunctionProtoType::ExtProtoInfo EPI
;
4406 EPI
.Variadic
= true;
4407 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4408 Sema::CapturedParamNameType Params
[] = {
4409 std::make_pair(".global_tid.", KmpInt32Ty
),
4410 std::make_pair(".part_id.", KmpInt32PtrTy
),
4411 std::make_pair(".privates.", VoidPtrTy
),
4414 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4415 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4416 std::make_pair(StringRef(), QualType()) // __context with shared vars
4418 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4419 Params
, /*OpenMPCaptureLevel=*/0);
4420 // Mark this captured region as inlined, because we don't use outlined
4421 // function directly.
4422 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4423 AlwaysInlineAttr::CreateImplicit(
4424 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4425 AlwaysInlineAttr::Keyword_forceinline
));
4426 Sema::CapturedParamNameType ParamsTarget
[] = {
4427 std::make_pair(StringRef(), QualType()) // __context with shared vars
4429 // Start a captured region for 'target' with no implicit parameters.
4430 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4431 ParamsTarget
, /*OpenMPCaptureLevel=*/1);
4433 Sema::CapturedParamNameType ParamsTeams
[] = {
4434 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4435 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4436 std::make_pair(StringRef(), QualType()) // __context with shared vars
4438 // Start a captured region for 'target' with no implicit parameters.
4439 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4440 ParamsTeams
, /*OpenMPCaptureLevel=*/2);
4442 Sema::CapturedParamNameType ParamsParallel
[] = {
4443 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4444 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4445 std::make_pair(".previous.lb.", Context
.getSizeType().withConst()),
4446 std::make_pair(".previous.ub.", Context
.getSizeType().withConst()),
4447 std::make_pair(StringRef(), QualType()) // __context with shared vars
4449 // Start a captured region for 'teams' or 'parallel'. Both regions have
4450 // the same implicit parameters.
4451 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4452 ParamsParallel
, /*OpenMPCaptureLevel=*/3);
4456 case OMPD_teams_loop
: {
4457 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4458 QualType KmpInt32PtrTy
=
4459 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4461 Sema::CapturedParamNameType ParamsTeams
[] = {
4462 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4463 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4464 std::make_pair(StringRef(), QualType()) // __context with shared vars
4466 // Start a captured region for 'teams'.
4467 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4468 ParamsTeams
, /*OpenMPCaptureLevel=*/0);
4472 case OMPD_teams_distribute_parallel_for
:
4473 case OMPD_teams_distribute_parallel_for_simd
: {
4474 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4475 QualType KmpInt32PtrTy
=
4476 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4478 Sema::CapturedParamNameType ParamsTeams
[] = {
4479 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4480 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4481 std::make_pair(StringRef(), QualType()) // __context with shared vars
4483 // Start a captured region for 'target' with no implicit parameters.
4484 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4485 ParamsTeams
, /*OpenMPCaptureLevel=*/0);
4487 Sema::CapturedParamNameType ParamsParallel
[] = {
4488 std::make_pair(".global_tid.", KmpInt32PtrTy
),
4489 std::make_pair(".bound_tid.", KmpInt32PtrTy
),
4490 std::make_pair(".previous.lb.", Context
.getSizeType().withConst()),
4491 std::make_pair(".previous.ub.", Context
.getSizeType().withConst()),
4492 std::make_pair(StringRef(), QualType()) // __context with shared vars
4494 // Start a captured region for 'teams' or 'parallel'. Both regions have
4495 // the same implicit parameters.
4496 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4497 ParamsParallel
, /*OpenMPCaptureLevel=*/1);
4500 case OMPD_target_update
:
4501 case OMPD_target_enter_data
:
4502 case OMPD_target_exit_data
: {
4503 QualType KmpInt32Ty
= Context
.getIntTypeForBitwidth(32, 1).withConst();
4504 QualType VoidPtrTy
= Context
.VoidPtrTy
.withConst().withRestrict();
4505 QualType KmpInt32PtrTy
=
4506 Context
.getPointerType(KmpInt32Ty
).withConst().withRestrict();
4507 QualType Args
[] = {VoidPtrTy
};
4508 FunctionProtoType::ExtProtoInfo EPI
;
4509 EPI
.Variadic
= true;
4510 QualType CopyFnType
= Context
.getFunctionType(Context
.VoidTy
, Args
, EPI
);
4511 Sema::CapturedParamNameType Params
[] = {
4512 std::make_pair(".global_tid.", KmpInt32Ty
),
4513 std::make_pair(".part_id.", KmpInt32PtrTy
),
4514 std::make_pair(".privates.", VoidPtrTy
),
4517 Context
.getPointerType(CopyFnType
).withConst().withRestrict()),
4518 std::make_pair(".task_t.", Context
.VoidPtrTy
.withConst()),
4519 std::make_pair(StringRef(), QualType()) // __context with shared vars
4521 ActOnCapturedRegionStart(DSAStack
->getConstructLoc(), CurScope
, CR_OpenMP
,
4523 // Mark this captured region as inlined, because we don't use outlined
4524 // function directly.
4525 getCurCapturedRegion()->TheCapturedDecl
->addAttr(
4526 AlwaysInlineAttr::CreateImplicit(
4527 Context
, {}, AttributeCommonInfo::AS_Keyword
,
4528 AlwaysInlineAttr::Keyword_forceinline
));
4531 case OMPD_threadprivate
:
4533 case OMPD_taskyield
:
4536 case OMPD_cancellation_point
:
4541 case OMPD_declare_reduction
:
4542 case OMPD_declare_mapper
:
4543 case OMPD_declare_simd
:
4544 case OMPD_declare_target
:
4545 case OMPD_end_declare_target
:
4547 case OMPD_declare_variant
:
4548 case OMPD_begin_declare_variant
:
4549 case OMPD_end_declare_variant
:
4550 case OMPD_metadirective
:
4551 llvm_unreachable("OpenMP Directive is not allowed");
4554 llvm_unreachable("Unknown OpenMP directive");
4556 DSAStack
->setContext(CurContext
);
4557 handleDeclareVariantConstructTrait(DSAStack
, DKind
, /* ScopeEntry */ true);
4560 int Sema::getNumberOfConstructScopes(unsigned Level
) const {
4561 return getOpenMPCaptureLevels(DSAStack
->getDirective(Level
));
4564 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind
) {
4565 SmallVector
<OpenMPDirectiveKind
, 4> CaptureRegions
;
4566 getOpenMPCaptureRegions(CaptureRegions
, DKind
);
4567 return CaptureRegions
.size();
4570 static OMPCapturedExprDecl
*buildCaptureDecl(Sema
&S
, IdentifierInfo
*Id
,
4571 Expr
*CaptureExpr
, bool WithInit
,
4572 DeclContext
*CurContext
,
4573 bool AsExpression
) {
4574 assert(CaptureExpr
);
4575 ASTContext
&C
= S
.getASTContext();
4576 Expr
*Init
= AsExpression
? CaptureExpr
: CaptureExpr
->IgnoreImpCasts();
4577 QualType Ty
= Init
->getType();
4578 if (CaptureExpr
->getObjectKind() == OK_Ordinary
&& CaptureExpr
->isGLValue()) {
4579 if (S
.getLangOpts().CPlusPlus
) {
4580 Ty
= C
.getLValueReferenceType(Ty
);
4582 Ty
= C
.getPointerType(Ty
);
4584 S
.CreateBuiltinUnaryOp(CaptureExpr
->getExprLoc(), UO_AddrOf
, Init
);
4585 if (!Res
.isUsable())
4591 auto *CED
= OMPCapturedExprDecl::Create(C
, CurContext
, Id
, Ty
,
4592 CaptureExpr
->getBeginLoc());
4594 CED
->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C
));
4595 CurContext
->addHiddenDecl(CED
);
4596 Sema::TentativeAnalysisScope
Trap(S
);
4597 S
.AddInitializerToDecl(CED
, Init
, /*DirectInit=*/false);
4601 static DeclRefExpr
*buildCapture(Sema
&S
, ValueDecl
*D
, Expr
*CaptureExpr
,
4603 OMPCapturedExprDecl
*CD
;
4604 if (VarDecl
*VD
= S
.isOpenMPCapturedDecl(D
))
4605 CD
= cast
<OMPCapturedExprDecl
>(VD
);
4607 CD
= buildCaptureDecl(S
, D
->getIdentifier(), CaptureExpr
, WithInit
,
4609 /*AsExpression=*/false);
4610 return buildDeclRefExpr(S
, CD
, CD
->getType().getNonReferenceType(),
4611 CaptureExpr
->getExprLoc());
4614 static ExprResult
buildCapture(Sema
&S
, Expr
*CaptureExpr
, DeclRefExpr
*&Ref
) {
4615 CaptureExpr
= S
.DefaultLvalueConversion(CaptureExpr
).get();
4617 OMPCapturedExprDecl
*CD
= buildCaptureDecl(
4618 S
, &S
.getASTContext().Idents
.get(".capture_expr."), CaptureExpr
,
4619 /*WithInit=*/true, S
.CurContext
, /*AsExpression=*/true);
4620 Ref
= buildDeclRefExpr(S
, CD
, CD
->getType().getNonReferenceType(),
4621 CaptureExpr
->getExprLoc());
4623 ExprResult Res
= Ref
;
4624 if (!S
.getLangOpts().CPlusPlus
&&
4625 CaptureExpr
->getObjectKind() == OK_Ordinary
&& CaptureExpr
->isGLValue() &&
4626 Ref
->getType()->isPointerType()) {
4627 Res
= S
.CreateBuiltinUnaryOp(CaptureExpr
->getExprLoc(), UO_Deref
, Ref
);
4628 if (!Res
.isUsable())
4631 return S
.DefaultLvalueConversion(Res
.get());
4635 // OpenMP directives parsed in this section are represented as a
4636 // CapturedStatement with an associated statement. If a syntax error
4637 // is detected during the parsing of the associated statement, the
4638 // compiler must abort processing and close the CapturedStatement.
4640 // Combined directives such as 'target parallel' have more than one
4641 // nested CapturedStatements. This RAII ensures that we unwind out
4642 // of all the nested CapturedStatements when an error is found.
4643 class CaptureRegionUnwinderRAII
{
4647 OpenMPDirectiveKind DKind
= OMPD_unknown
;
4650 CaptureRegionUnwinderRAII(Sema
&S
, bool &ErrorFound
,
4651 OpenMPDirectiveKind DKind
)
4652 : S(S
), ErrorFound(ErrorFound
), DKind(DKind
) {}
4653 ~CaptureRegionUnwinderRAII() {
4655 int ThisCaptureLevel
= S
.getOpenMPCaptureLevels(DKind
);
4656 while (--ThisCaptureLevel
>= 0)
4657 S
.ActOnCapturedRegionError();
4663 void Sema::tryCaptureOpenMPLambdas(ValueDecl
*V
) {
4664 // Capture variables captured by reference in lambdas for target-based
4666 if (!CurContext
->isDependentContext() &&
4667 (isOpenMPTargetExecutionDirective(DSAStack
->getCurrentDirective()) ||
4668 isOpenMPTargetDataManagementDirective(
4669 DSAStack
->getCurrentDirective()))) {
4670 QualType Type
= V
->getType();
4671 if (const auto *RD
= Type
.getCanonicalType()
4672 .getNonReferenceType()
4673 ->getAsCXXRecordDecl()) {
4674 bool SavedForceCaptureByReferenceInTargetExecutable
=
4675 DSAStack
->isForceCaptureByReferenceInTargetExecutable();
4676 DSAStack
->setForceCaptureByReferenceInTargetExecutable(
4678 if (RD
->isLambda()) {
4679 llvm::DenseMap
<const ValueDecl
*, FieldDecl
*> Captures
;
4680 FieldDecl
*ThisCapture
;
4681 RD
->getCaptureFields(Captures
, ThisCapture
);
4682 for (const LambdaCapture
&LC
: RD
->captures()) {
4683 if (LC
.getCaptureKind() == LCK_ByRef
) {
4684 VarDecl
*VD
= cast
<VarDecl
>(LC
.getCapturedVar());
4685 DeclContext
*VDC
= VD
->getDeclContext();
4686 if (!VDC
->Encloses(CurContext
))
4688 MarkVariableReferenced(LC
.getLocation(), VD
);
4689 } else if (LC
.getCaptureKind() == LCK_This
) {
4690 QualType ThisTy
= getCurrentThisType();
4691 if (!ThisTy
.isNull() &&
4692 Context
.typesAreCompatible(ThisTy
, ThisCapture
->getType()))
4693 CheckCXXThisCapture(LC
.getLocation());
4697 DSAStack
->setForceCaptureByReferenceInTargetExecutable(
4698 SavedForceCaptureByReferenceInTargetExecutable
);
4703 static bool checkOrderedOrderSpecified(Sema
&S
,
4704 const ArrayRef
<OMPClause
*> Clauses
) {
4705 const OMPOrderedClause
*Ordered
= nullptr;
4706 const OMPOrderClause
*Order
= nullptr;
4708 for (const OMPClause
*Clause
: Clauses
) {
4709 if (Clause
->getClauseKind() == OMPC_ordered
)
4710 Ordered
= cast
<OMPOrderedClause
>(Clause
);
4711 else if (Clause
->getClauseKind() == OMPC_order
) {
4712 Order
= cast
<OMPOrderClause
>(Clause
);
4713 if (Order
->getKind() != OMPC_ORDER_concurrent
)
4716 if (Ordered
&& Order
)
4720 if (Ordered
&& Order
) {
4721 S
.Diag(Order
->getKindKwLoc(),
4722 diag::err_omp_simple_clause_incompatible_with_ordered
)
4723 << getOpenMPClauseName(OMPC_order
)
4724 << getOpenMPSimpleClauseTypeName(OMPC_order
, OMPC_ORDER_concurrent
)
4725 << SourceRange(Order
->getBeginLoc(), Order
->getEndLoc());
4726 S
.Diag(Ordered
->getBeginLoc(), diag::note_omp_ordered_param
)
4727 << 0 << SourceRange(Ordered
->getBeginLoc(), Ordered
->getEndLoc());
4733 StmtResult
Sema::ActOnOpenMPRegionEnd(StmtResult S
,
4734 ArrayRef
<OMPClause
*> Clauses
) {
4735 handleDeclareVariantConstructTrait(DSAStack
, DSAStack
->getCurrentDirective(),
4736 /* ScopeEntry */ false);
4737 if (DSAStack
->getCurrentDirective() == OMPD_atomic
||
4738 DSAStack
->getCurrentDirective() == OMPD_critical
||
4739 DSAStack
->getCurrentDirective() == OMPD_section
||
4740 DSAStack
->getCurrentDirective() == OMPD_master
||
4741 DSAStack
->getCurrentDirective() == OMPD_masked
)
4744 bool ErrorFound
= false;
4745 CaptureRegionUnwinderRAII
CaptureRegionUnwinder(
4746 *this, ErrorFound
, DSAStack
->getCurrentDirective());
4747 if (!S
.isUsable()) {
4752 SmallVector
<OpenMPDirectiveKind
, 4> CaptureRegions
;
4753 getOpenMPCaptureRegions(CaptureRegions
, DSAStack
->getCurrentDirective());
4754 OMPOrderedClause
*OC
= nullptr;
4755 OMPScheduleClause
*SC
= nullptr;
4756 SmallVector
<const OMPLinearClause
*, 4> LCs
;
4757 SmallVector
<const OMPClauseWithPreInit
*, 4> PICs
;
4758 // This is required for proper codegen.
4759 for (OMPClause
*Clause
: Clauses
) {
4760 if (!LangOpts
.OpenMPSimd
&&
4761 (isOpenMPTaskingDirective(DSAStack
->getCurrentDirective()) ||
4762 DSAStack
->getCurrentDirective() == OMPD_target
) &&
4763 Clause
->getClauseKind() == OMPC_in_reduction
) {
4764 // Capture taskgroup task_reduction descriptors inside the tasking regions
4765 // with the corresponding in_reduction items.
4766 auto *IRC
= cast
<OMPInReductionClause
>(Clause
);
4767 for (Expr
*E
: IRC
->taskgroup_descriptors())
4769 MarkDeclarationsReferencedInExpr(E
);
4771 if (isOpenMPPrivate(Clause
->getClauseKind()) ||
4772 Clause
->getClauseKind() == OMPC_copyprivate
||
4773 (getLangOpts().OpenMPUseTLS
&&
4774 getASTContext().getTargetInfo().isTLSSupported() &&
4775 Clause
->getClauseKind() == OMPC_copyin
)) {
4776 DSAStack
->setForceVarCapturing(Clause
->getClauseKind() == OMPC_copyin
);
4777 // Mark all variables in private list clauses as used in inner region.
4778 for (Stmt
*VarRef
: Clause
->children()) {
4779 if (auto *E
= cast_or_null
<Expr
>(VarRef
)) {
4780 MarkDeclarationsReferencedInExpr(E
);
4783 DSAStack
->setForceVarCapturing(/*V=*/false);
4784 } else if (isOpenMPLoopTransformationDirective(
4785 DSAStack
->getCurrentDirective())) {
4786 assert(CaptureRegions
.empty() &&
4787 "No captured regions in loop transformation directives.");
4788 } else if (CaptureRegions
.size() > 1 ||
4789 CaptureRegions
.back() != OMPD_unknown
) {
4790 if (auto *C
= OMPClauseWithPreInit::get(Clause
))
4792 if (auto *C
= OMPClauseWithPostUpdate::get(Clause
)) {
4793 if (Expr
*E
= C
->getPostUpdateExpr())
4794 MarkDeclarationsReferencedInExpr(E
);
4797 if (Clause
->getClauseKind() == OMPC_schedule
)
4798 SC
= cast
<OMPScheduleClause
>(Clause
);
4799 else if (Clause
->getClauseKind() == OMPC_ordered
)
4800 OC
= cast
<OMPOrderedClause
>(Clause
);
4801 else if (Clause
->getClauseKind() == OMPC_linear
)
4802 LCs
.push_back(cast
<OMPLinearClause
>(Clause
));
4804 // Capture allocator expressions if used.
4805 for (Expr
*E
: DSAStack
->getInnerAllocators())
4806 MarkDeclarationsReferencedInExpr(E
);
4807 // OpenMP, 2.7.1 Loop Construct, Restrictions
4808 // The nonmonotonic modifier cannot be specified if an ordered clause is
4811 (SC
->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
||
4812 SC
->getSecondScheduleModifier() ==
4813 OMPC_SCHEDULE_MODIFIER_nonmonotonic
) &&
4815 Diag(SC
->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4816 ? SC
->getFirstScheduleModifierLoc()
4817 : SC
->getSecondScheduleModifierLoc(),
4818 diag::err_omp_simple_clause_incompatible_with_ordered
)
4819 << getOpenMPClauseName(OMPC_schedule
)
4820 << getOpenMPSimpleClauseTypeName(OMPC_schedule
,
4821 OMPC_SCHEDULE_MODIFIER_nonmonotonic
)
4822 << SourceRange(OC
->getBeginLoc(), OC
->getEndLoc());
4825 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4826 // If an order(concurrent) clause is present, an ordered clause may not appear
4827 // on the same directive.
4828 if (checkOrderedOrderSpecified(*this, Clauses
))
4830 if (!LCs
.empty() && OC
&& OC
->getNumForLoops()) {
4831 for (const OMPLinearClause
*C
: LCs
) {
4832 Diag(C
->getBeginLoc(), diag::err_omp_linear_ordered
)
4833 << SourceRange(OC
->getBeginLoc(), OC
->getEndLoc());
4837 if (isOpenMPWorksharingDirective(DSAStack
->getCurrentDirective()) &&
4838 isOpenMPSimdDirective(DSAStack
->getCurrentDirective()) && OC
&&
4839 OC
->getNumForLoops()) {
4840 Diag(OC
->getBeginLoc(), diag::err_omp_ordered_simd
)
4841 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
4848 unsigned CompletedRegions
= 0;
4849 for (OpenMPDirectiveKind ThisCaptureRegion
: llvm::reverse(CaptureRegions
)) {
4850 // Mark all variables in private list clauses as used in inner region.
4851 // Required for proper codegen of combined directives.
4852 // TODO: add processing for other clauses.
4853 if (ThisCaptureRegion
!= OMPD_unknown
) {
4854 for (const clang::OMPClauseWithPreInit
*C
: PICs
) {
4855 OpenMPDirectiveKind CaptureRegion
= C
->getCaptureRegion();
4856 // Find the particular capture region for the clause if the
4857 // directive is a combined one with multiple capture regions.
4858 // If the directive is not a combined one, the capture region
4859 // associated with the clause is OMPD_unknown and is generated
4861 if (CaptureRegion
== ThisCaptureRegion
||
4862 CaptureRegion
== OMPD_unknown
) {
4863 if (auto *DS
= cast_or_null
<DeclStmt
>(C
->getPreInitStmt())) {
4864 for (Decl
*D
: DS
->decls())
4865 MarkVariableReferenced(D
->getLocation(), cast
<VarDecl
>(D
));
4870 if (ThisCaptureRegion
== OMPD_target
) {
4871 // Capture allocator traits in the target region. They are used implicitly
4872 // and, thus, are not captured by default.
4873 for (OMPClause
*C
: Clauses
) {
4874 if (const auto *UAC
= dyn_cast
<OMPUsesAllocatorsClause
>(C
)) {
4875 for (unsigned I
= 0, End
= UAC
->getNumberOfAllocators(); I
< End
;
4877 OMPUsesAllocatorsClause::Data D
= UAC
->getAllocatorData(I
);
4878 if (Expr
*E
= D
.AllocatorTraits
)
4879 MarkDeclarationsReferencedInExpr(E
);
4885 if (ThisCaptureRegion
== OMPD_parallel
) {
4886 // Capture temp arrays for inscan reductions and locals in aligned
4888 for (OMPClause
*C
: Clauses
) {
4889 if (auto *RC
= dyn_cast
<OMPReductionClause
>(C
)) {
4890 if (RC
->getModifier() != OMPC_REDUCTION_inscan
)
4892 for (Expr
*E
: RC
->copy_array_temps())
4893 MarkDeclarationsReferencedInExpr(E
);
4895 if (auto *AC
= dyn_cast
<OMPAlignedClause
>(C
)) {
4896 for (Expr
*E
: AC
->varlists())
4897 MarkDeclarationsReferencedInExpr(E
);
4901 if (++CompletedRegions
== CaptureRegions
.size())
4902 DSAStack
->setBodyComplete();
4903 SR
= ActOnCapturedRegionEnd(SR
.get());
4908 static bool checkCancelRegion(Sema
&SemaRef
, OpenMPDirectiveKind CurrentRegion
,
4909 OpenMPDirectiveKind CancelRegion
,
4910 SourceLocation StartLoc
) {
4911 // CancelRegion is only needed for cancel and cancellation_point.
4912 if (CurrentRegion
!= OMPD_cancel
&& CurrentRegion
!= OMPD_cancellation_point
)
4915 if (CancelRegion
== OMPD_parallel
|| CancelRegion
== OMPD_for
||
4916 CancelRegion
== OMPD_sections
|| CancelRegion
== OMPD_taskgroup
)
4919 SemaRef
.Diag(StartLoc
, diag::err_omp_wrong_cancel_region
)
4920 << getOpenMPDirectiveName(CancelRegion
);
4924 static bool checkNestingOfRegions(Sema
&SemaRef
, const DSAStackTy
*Stack
,
4925 OpenMPDirectiveKind CurrentRegion
,
4926 const DeclarationNameInfo
&CurrentName
,
4927 OpenMPDirectiveKind CancelRegion
,
4928 OpenMPBindClauseKind BindKind
,
4929 SourceLocation StartLoc
) {
4930 if (Stack
->getCurScope()) {
4931 OpenMPDirectiveKind ParentRegion
= Stack
->getParentDirective();
4932 OpenMPDirectiveKind OffendingRegion
= ParentRegion
;
4933 bool NestingProhibited
= false;
4934 bool CloseNesting
= true;
4935 bool OrphanSeen
= false;
4938 ShouldBeInParallelRegion
,
4939 ShouldBeInOrderedRegion
,
4940 ShouldBeInTargetRegion
,
4941 ShouldBeInTeamsRegion
,
4942 ShouldBeInLoopSimdRegion
,
4943 } Recommend
= NoRecommend
;
4944 if (isOpenMPSimdDirective(ParentRegion
) &&
4945 ((SemaRef
.LangOpts
.OpenMP
<= 45 && CurrentRegion
!= OMPD_ordered
) ||
4946 (SemaRef
.LangOpts
.OpenMP
>= 50 && CurrentRegion
!= OMPD_ordered
&&
4947 CurrentRegion
!= OMPD_simd
&& CurrentRegion
!= OMPD_atomic
&&
4948 CurrentRegion
!= OMPD_scan
))) {
4949 // OpenMP [2.16, Nesting of Regions]
4950 // OpenMP constructs may not be nested inside a simd region.
4951 // OpenMP [2.8.1,simd Construct, Restrictions]
4952 // An ordered construct with the simd clause is the only OpenMP
4953 // construct that can appear in the simd region.
4954 // Allowing a SIMD construct nested in another SIMD construct is an
4955 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4957 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4958 // The only OpenMP constructs that can be encountered during execution of
4959 // a simd region are the atomic construct, the loop construct, the simd
4960 // construct and the ordered construct with the simd clause.
4961 SemaRef
.Diag(StartLoc
, (CurrentRegion
!= OMPD_simd
)
4962 ? diag::err_omp_prohibited_region_simd
4963 : diag::warn_omp_nesting_simd
)
4964 << (SemaRef
.LangOpts
.OpenMP
>= 50 ? 1 : 0);
4965 return CurrentRegion
!= OMPD_simd
;
4967 if (ParentRegion
== OMPD_atomic
) {
4968 // OpenMP [2.16, Nesting of Regions]
4969 // OpenMP constructs may not be nested inside an atomic region.
4970 SemaRef
.Diag(StartLoc
, diag::err_omp_prohibited_region_atomic
);
4973 if (CurrentRegion
== OMPD_section
) {
4974 // OpenMP [2.7.2, sections Construct, Restrictions]
4975 // Orphaned section directives are prohibited. That is, the section
4976 // directives must appear within the sections construct and must not be
4977 // encountered elsewhere in the sections region.
4978 if (ParentRegion
!= OMPD_sections
&&
4979 ParentRegion
!= OMPD_parallel_sections
) {
4980 SemaRef
.Diag(StartLoc
, diag::err_omp_orphaned_section_directive
)
4981 << (ParentRegion
!= OMPD_unknown
)
4982 << getOpenMPDirectiveName(ParentRegion
);
4987 // Allow some constructs (except teams and cancellation constructs) to be
4988 // orphaned (they could be used in functions, called from OpenMP regions
4989 // with the required preconditions).
4990 if (ParentRegion
== OMPD_unknown
&&
4991 !isOpenMPNestingTeamsDirective(CurrentRegion
) &&
4992 CurrentRegion
!= OMPD_cancellation_point
&&
4993 CurrentRegion
!= OMPD_cancel
&& CurrentRegion
!= OMPD_scan
)
4995 if (CurrentRegion
== OMPD_cancellation_point
||
4996 CurrentRegion
== OMPD_cancel
) {
4997 // OpenMP [2.16, Nesting of Regions]
4998 // A cancellation point construct for which construct-type-clause is
4999 // taskgroup must be nested inside a task construct. A cancellation
5000 // point construct for which construct-type-clause is not taskgroup must
5001 // be closely nested inside an OpenMP construct that matches the type
5002 // specified in construct-type-clause.
5003 // A cancel construct for which construct-type-clause is taskgroup must be
5004 // nested inside a task construct. A cancel construct for which
5005 // construct-type-clause is not taskgroup must be closely nested inside an
5006 // OpenMP construct that matches the type specified in
5007 // construct-type-clause.
5009 !((CancelRegion
== OMPD_parallel
&&
5010 (ParentRegion
== OMPD_parallel
||
5011 ParentRegion
== OMPD_target_parallel
)) ||
5012 (CancelRegion
== OMPD_for
&&
5013 (ParentRegion
== OMPD_for
|| ParentRegion
== OMPD_parallel_for
||
5014 ParentRegion
== OMPD_target_parallel_for
||
5015 ParentRegion
== OMPD_distribute_parallel_for
||
5016 ParentRegion
== OMPD_teams_distribute_parallel_for
||
5017 ParentRegion
== OMPD_target_teams_distribute_parallel_for
)) ||
5018 (CancelRegion
== OMPD_taskgroup
&&
5019 (ParentRegion
== OMPD_task
||
5020 (SemaRef
.getLangOpts().OpenMP
>= 50 &&
5021 (ParentRegion
== OMPD_taskloop
||
5022 ParentRegion
== OMPD_master_taskloop
||
5023 ParentRegion
== OMPD_masked_taskloop
||
5024 ParentRegion
== OMPD_parallel_masked_taskloop
||
5025 ParentRegion
== OMPD_parallel_master_taskloop
)))) ||
5026 (CancelRegion
== OMPD_sections
&&
5027 (ParentRegion
== OMPD_section
|| ParentRegion
== OMPD_sections
||
5028 ParentRegion
== OMPD_parallel_sections
)));
5029 OrphanSeen
= ParentRegion
== OMPD_unknown
;
5030 } else if (CurrentRegion
== OMPD_master
|| CurrentRegion
== OMPD_masked
) {
5031 // OpenMP 5.1 [2.22, Nesting of Regions]
5032 // A masked region may not be closely nested inside a worksharing, loop,
5033 // atomic, task, or taskloop region.
5034 NestingProhibited
= isOpenMPWorksharingDirective(ParentRegion
) ||
5035 isOpenMPGenericLoopDirective(ParentRegion
) ||
5036 isOpenMPTaskingDirective(ParentRegion
);
5037 } else if (CurrentRegion
== OMPD_critical
&& CurrentName
.getName()) {
5038 // OpenMP [2.16, Nesting of Regions]
5039 // A critical region may not be nested (closely or otherwise) inside a
5040 // critical region with the same name. Note that this restriction is not
5041 // sufficient to prevent deadlock.
5042 SourceLocation PreviousCriticalLoc
;
5043 bool DeadLock
= Stack
->hasDirective(
5044 [CurrentName
, &PreviousCriticalLoc
](OpenMPDirectiveKind K
,
5045 const DeclarationNameInfo
&DNI
,
5046 SourceLocation Loc
) {
5047 if (K
== OMPD_critical
&& DNI
.getName() == CurrentName
.getName()) {
5048 PreviousCriticalLoc
= Loc
;
5053 false /* skip top directive */);
5055 SemaRef
.Diag(StartLoc
,
5056 diag::err_omp_prohibited_region_critical_same_name
)
5057 << CurrentName
.getName();
5058 if (PreviousCriticalLoc
.isValid())
5059 SemaRef
.Diag(PreviousCriticalLoc
,
5060 diag::note_omp_previous_critical_region
);
5063 } else if (CurrentRegion
== OMPD_barrier
) {
5064 // OpenMP 5.1 [2.22, Nesting of Regions]
5065 // A barrier region may not be closely nested inside a worksharing, loop,
5066 // task, taskloop, critical, ordered, atomic, or masked region.
5068 isOpenMPWorksharingDirective(ParentRegion
) ||
5069 isOpenMPGenericLoopDirective(ParentRegion
) ||
5070 isOpenMPTaskingDirective(ParentRegion
) ||
5071 ParentRegion
== OMPD_master
|| ParentRegion
== OMPD_masked
||
5072 ParentRegion
== OMPD_parallel_master
||
5073 ParentRegion
== OMPD_parallel_masked
||
5074 ParentRegion
== OMPD_critical
|| ParentRegion
== OMPD_ordered
;
5075 } else if (isOpenMPWorksharingDirective(CurrentRegion
) &&
5076 !isOpenMPParallelDirective(CurrentRegion
) &&
5077 !isOpenMPTeamsDirective(CurrentRegion
)) {
5078 // OpenMP 5.1 [2.22, Nesting of Regions]
5079 // A loop region that binds to a parallel region or a worksharing region
5080 // may not be closely nested inside a worksharing, loop, task, taskloop,
5081 // critical, ordered, atomic, or masked region.
5083 isOpenMPWorksharingDirective(ParentRegion
) ||
5084 isOpenMPGenericLoopDirective(ParentRegion
) ||
5085 isOpenMPTaskingDirective(ParentRegion
) ||
5086 ParentRegion
== OMPD_master
|| ParentRegion
== OMPD_masked
||
5087 ParentRegion
== OMPD_parallel_master
||
5088 ParentRegion
== OMPD_parallel_masked
||
5089 ParentRegion
== OMPD_critical
|| ParentRegion
== OMPD_ordered
;
5090 Recommend
= ShouldBeInParallelRegion
;
5091 } else if (CurrentRegion
== OMPD_ordered
) {
5092 // OpenMP [2.16, Nesting of Regions]
5093 // An ordered region may not be closely nested inside a critical,
5094 // atomic, or explicit task region.
5095 // An ordered region must be closely nested inside a loop region (or
5096 // parallel loop region) with an ordered clause.
5097 // OpenMP [2.8.1,simd Construct, Restrictions]
5098 // An ordered construct with the simd clause is the only OpenMP construct
5099 // that can appear in the simd region.
5100 NestingProhibited
= ParentRegion
== OMPD_critical
||
5101 isOpenMPTaskingDirective(ParentRegion
) ||
5102 !(isOpenMPSimdDirective(ParentRegion
) ||
5103 Stack
->isParentOrderedRegion());
5104 Recommend
= ShouldBeInOrderedRegion
;
5105 } else if (isOpenMPNestingTeamsDirective(CurrentRegion
)) {
5106 // OpenMP [2.16, Nesting of Regions]
5107 // If specified, a teams construct must be contained within a target
5110 (SemaRef
.LangOpts
.OpenMP
<= 45 && ParentRegion
!= OMPD_target
) ||
5111 (SemaRef
.LangOpts
.OpenMP
>= 50 && ParentRegion
!= OMPD_unknown
&&
5112 ParentRegion
!= OMPD_target
);
5113 OrphanSeen
= ParentRegion
== OMPD_unknown
;
5114 Recommend
= ShouldBeInTargetRegion
;
5115 } else if (CurrentRegion
== OMPD_scan
) {
5116 // OpenMP [2.16, Nesting of Regions]
5117 // If specified, a teams construct must be contained within a target
5120 SemaRef
.LangOpts
.OpenMP
< 50 ||
5121 (ParentRegion
!= OMPD_simd
&& ParentRegion
!= OMPD_for
&&
5122 ParentRegion
!= OMPD_for_simd
&& ParentRegion
!= OMPD_parallel_for
&&
5123 ParentRegion
!= OMPD_parallel_for_simd
);
5124 OrphanSeen
= ParentRegion
== OMPD_unknown
;
5125 Recommend
= ShouldBeInLoopSimdRegion
;
5127 if (!NestingProhibited
&&
5128 !isOpenMPTargetExecutionDirective(CurrentRegion
) &&
5129 !isOpenMPTargetDataManagementDirective(CurrentRegion
) &&
5130 (ParentRegion
== OMPD_teams
|| ParentRegion
== OMPD_target_teams
)) {
5131 // OpenMP [5.1, 2.22, Nesting of Regions]
5132 // distribute, distribute simd, distribute parallel worksharing-loop,
5133 // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5134 // including any parallel regions arising from combined constructs,
5135 // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5136 // only OpenMP regions that may be strictly nested inside the teams
5139 // As an extension, we permit atomic within teams as well.
5140 NestingProhibited
= !isOpenMPParallelDirective(CurrentRegion
) &&
5141 !isOpenMPDistributeDirective(CurrentRegion
) &&
5142 CurrentRegion
!= OMPD_loop
&&
5143 !(SemaRef
.getLangOpts().OpenMPExtensions
&&
5144 CurrentRegion
== OMPD_atomic
);
5145 Recommend
= ShouldBeInParallelRegion
;
5147 if (!NestingProhibited
&& CurrentRegion
== OMPD_loop
) {
5148 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5149 // If the bind clause is present on the loop construct and binding is
5150 // teams then the corresponding loop region must be strictly nested inside
5152 NestingProhibited
= BindKind
== OMPC_BIND_teams
&&
5153 ParentRegion
!= OMPD_teams
&&
5154 ParentRegion
!= OMPD_target_teams
;
5155 Recommend
= ShouldBeInTeamsRegion
;
5157 if (!NestingProhibited
&&
5158 isOpenMPNestingDistributeDirective(CurrentRegion
)) {
5159 // OpenMP 4.5 [2.17 Nesting of Regions]
5160 // The region associated with the distribute construct must be strictly
5161 // nested inside a teams region
5163 (ParentRegion
!= OMPD_teams
&& ParentRegion
!= OMPD_target_teams
);
5164 Recommend
= ShouldBeInTeamsRegion
;
5166 if (!NestingProhibited
&&
5167 (isOpenMPTargetExecutionDirective(CurrentRegion
) ||
5168 isOpenMPTargetDataManagementDirective(CurrentRegion
))) {
5169 // OpenMP 4.5 [2.17 Nesting of Regions]
5170 // If a target, target update, target data, target enter data, or
5171 // target exit data construct is encountered during execution of a
5172 // target region, the behavior is unspecified.
5173 NestingProhibited
= Stack
->hasDirective(
5174 [&OffendingRegion
](OpenMPDirectiveKind K
, const DeclarationNameInfo
&,
5176 if (isOpenMPTargetExecutionDirective(K
)) {
5177 OffendingRegion
= K
;
5182 false /* don't skip top directive */);
5183 CloseNesting
= false;
5185 if (NestingProhibited
) {
5187 SemaRef
.Diag(StartLoc
, diag::err_omp_orphaned_device_directive
)
5188 << getOpenMPDirectiveName(CurrentRegion
) << Recommend
;
5190 SemaRef
.Diag(StartLoc
, diag::err_omp_prohibited_region
)
5191 << CloseNesting
<< getOpenMPDirectiveName(OffendingRegion
)
5192 << Recommend
<< getOpenMPDirectiveName(CurrentRegion
);
5200 struct Kind2Unsigned
{
5201 using argument_type
= OpenMPDirectiveKind
;
5202 unsigned operator()(argument_type DK
) { return unsigned(DK
); }
5204 static bool checkIfClauses(Sema
&S
, OpenMPDirectiveKind Kind
,
5205 ArrayRef
<OMPClause
*> Clauses
,
5206 ArrayRef
<OpenMPDirectiveKind
> AllowedNameModifiers
) {
5207 bool ErrorFound
= false;
5208 unsigned NamedModifiersNumber
= 0;
5209 llvm::IndexedMap
<const OMPIfClause
*, Kind2Unsigned
> FoundNameModifiers
;
5210 FoundNameModifiers
.resize(llvm::omp::Directive_enumSize
+ 1);
5211 SmallVector
<SourceLocation
, 4> NameModifierLoc
;
5212 for (const OMPClause
*C
: Clauses
) {
5213 if (const auto *IC
= dyn_cast_or_null
<OMPIfClause
>(C
)) {
5214 // At most one if clause without a directive-name-modifier can appear on
5216 OpenMPDirectiveKind CurNM
= IC
->getNameModifier();
5217 if (FoundNameModifiers
[CurNM
]) {
5218 S
.Diag(C
->getBeginLoc(), diag::err_omp_more_one_clause
)
5219 << getOpenMPDirectiveName(Kind
) << getOpenMPClauseName(OMPC_if
)
5220 << (CurNM
!= OMPD_unknown
) << getOpenMPDirectiveName(CurNM
);
5222 } else if (CurNM
!= OMPD_unknown
) {
5223 NameModifierLoc
.push_back(IC
->getNameModifierLoc());
5224 ++NamedModifiersNumber
;
5226 FoundNameModifiers
[CurNM
] = IC
;
5227 if (CurNM
== OMPD_unknown
)
5229 // Check if the specified name modifier is allowed for the current
5231 // At most one if clause with the particular directive-name-modifier can
5232 // appear on the directive.
5233 if (!llvm::is_contained(AllowedNameModifiers
, CurNM
)) {
5234 S
.Diag(IC
->getNameModifierLoc(),
5235 diag::err_omp_wrong_if_directive_name_modifier
)
5236 << getOpenMPDirectiveName(CurNM
) << getOpenMPDirectiveName(Kind
);
5241 // If any if clause on the directive includes a directive-name-modifier then
5242 // all if clauses on the directive must include a directive-name-modifier.
5243 if (FoundNameModifiers
[OMPD_unknown
] && NamedModifiersNumber
> 0) {
5244 if (NamedModifiersNumber
== AllowedNameModifiers
.size()) {
5245 S
.Diag(FoundNameModifiers
[OMPD_unknown
]->getBeginLoc(),
5246 diag::err_omp_no_more_if_clause
);
5249 std::string
Sep(", ");
5250 unsigned AllowedCnt
= 0;
5251 unsigned TotalAllowedNum
=
5252 AllowedNameModifiers
.size() - NamedModifiersNumber
;
5253 for (unsigned Cnt
= 0, End
= AllowedNameModifiers
.size(); Cnt
< End
;
5255 OpenMPDirectiveKind NM
= AllowedNameModifiers
[Cnt
];
5256 if (!FoundNameModifiers
[NM
]) {
5258 Values
+= getOpenMPDirectiveName(NM
);
5260 if (AllowedCnt
+ 2 == TotalAllowedNum
)
5262 else if (AllowedCnt
+ 1 != TotalAllowedNum
)
5267 S
.Diag(FoundNameModifiers
[OMPD_unknown
]->getCondition()->getBeginLoc(),
5268 diag::err_omp_unnamed_if_clause
)
5269 << (TotalAllowedNum
> 1) << Values
;
5271 for (SourceLocation Loc
: NameModifierLoc
) {
5272 S
.Diag(Loc
, diag::note_omp_previous_named_if_clause
);
5279 static std::pair
<ValueDecl
*, bool> getPrivateItem(Sema
&S
, Expr
*&RefExpr
,
5280 SourceLocation
&ELoc
,
5281 SourceRange
&ERange
,
5282 bool AllowArraySection
,
5283 StringRef DiagType
) {
5284 if (RefExpr
->isTypeDependent() || RefExpr
->isValueDependent() ||
5285 RefExpr
->containsUnexpandedParameterPack())
5286 return std::make_pair(nullptr, true);
5288 // OpenMP [3.1, C/C++]
5289 // A list item is a variable name.
5290 // OpenMP [2.9.3.3, Restrictions, p.1]
5291 // A variable that is part of another variable (as an array or
5292 // structure element) cannot appear in a private clause.
5293 RefExpr
= RefExpr
->IgnoreParens();
5298 } IsArrayExpr
= NoArrayExpr
;
5299 if (AllowArraySection
) {
5300 if (auto *ASE
= dyn_cast_or_null
<ArraySubscriptExpr
>(RefExpr
)) {
5301 Expr
*Base
= ASE
->getBase()->IgnoreParenImpCasts();
5302 while (auto *TempASE
= dyn_cast
<ArraySubscriptExpr
>(Base
))
5303 Base
= TempASE
->getBase()->IgnoreParenImpCasts();
5305 IsArrayExpr
= ArraySubscript
;
5306 } else if (auto *OASE
= dyn_cast_or_null
<OMPArraySectionExpr
>(RefExpr
)) {
5307 Expr
*Base
= OASE
->getBase()->IgnoreParenImpCasts();
5308 while (auto *TempOASE
= dyn_cast
<OMPArraySectionExpr
>(Base
))
5309 Base
= TempOASE
->getBase()->IgnoreParenImpCasts();
5310 while (auto *TempASE
= dyn_cast
<ArraySubscriptExpr
>(Base
))
5311 Base
= TempASE
->getBase()->IgnoreParenImpCasts();
5313 IsArrayExpr
= OMPArraySection
;
5316 ELoc
= RefExpr
->getExprLoc();
5317 ERange
= RefExpr
->getSourceRange();
5318 RefExpr
= RefExpr
->IgnoreParenImpCasts();
5319 auto *DE
= dyn_cast_or_null
<DeclRefExpr
>(RefExpr
);
5320 auto *ME
= dyn_cast_or_null
<MemberExpr
>(RefExpr
);
5321 if ((!DE
|| !isa
<VarDecl
>(DE
->getDecl())) &&
5322 (S
.getCurrentThisType().isNull() || !ME
||
5323 !isa
<CXXThisExpr
>(ME
->getBase()->IgnoreParenImpCasts()) ||
5324 !isa
<FieldDecl
>(ME
->getMemberDecl()))) {
5325 if (IsArrayExpr
!= NoArrayExpr
) {
5326 S
.Diag(ELoc
, diag::err_omp_expected_base_var_name
)
5327 << IsArrayExpr
<< ERange
;
5328 } else if (!DiagType
.empty()) {
5329 unsigned DiagSelect
= S
.getLangOpts().CPlusPlus
5330 ? (S
.getCurrentThisType().isNull() ? 1 : 2)
5332 S
.Diag(ELoc
, diag::err_omp_expected_var_name_member_expr_with_type
)
5333 << DiagSelect
<< DiagType
<< ERange
;
5337 ? diag::err_omp_expected_var_name_member_expr_or_array_item
5338 : diag::err_omp_expected_var_name_member_expr
)
5339 << (S
.getCurrentThisType().isNull() ? 0 : 1) << ERange
;
5341 return std::make_pair(nullptr, false);
5343 return std::make_pair(
5344 getCanonicalDecl(DE
? DE
->getDecl() : ME
->getMemberDecl()), false);
5348 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5350 class AllocatorChecker final
: public ConstStmtVisitor
<AllocatorChecker
, bool> {
5351 DSAStackTy
*S
= nullptr;
5354 bool VisitDeclRefExpr(const DeclRefExpr
*E
) {
5355 return S
->isUsesAllocatorsDecl(E
->getDecl())
5356 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait
) ==
5357 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait
;
5359 bool VisitStmt(const Stmt
*S
) {
5360 for (const Stmt
*Child
: S
->children()) {
5361 if (Child
&& Visit(Child
))
5366 explicit AllocatorChecker(DSAStackTy
*S
) : S(S
) {}
5370 static void checkAllocateClauses(Sema
&S
, DSAStackTy
*Stack
,
5371 ArrayRef
<OMPClause
*> Clauses
) {
5372 assert(!S
.CurContext
->isDependentContext() &&
5373 "Expected non-dependent context.");
5374 auto AllocateRange
=
5375 llvm::make_filter_range(Clauses
, OMPAllocateClause::classof
);
5376 llvm::DenseMap
<CanonicalDeclPtr
<Decl
>, CanonicalDeclPtr
<VarDecl
>> DeclToCopy
;
5377 auto PrivateRange
= llvm::make_filter_range(Clauses
, [](const OMPClause
*C
) {
5378 return isOpenMPPrivate(C
->getClauseKind());
5380 for (OMPClause
*Cl
: PrivateRange
) {
5381 MutableArrayRef
<Expr
*>::iterator I
, It
, Et
;
5382 if (Cl
->getClauseKind() == OMPC_private
) {
5383 auto *PC
= cast
<OMPPrivateClause
>(Cl
);
5384 I
= PC
->private_copies().begin();
5385 It
= PC
->varlist_begin();
5386 Et
= PC
->varlist_end();
5387 } else if (Cl
->getClauseKind() == OMPC_firstprivate
) {
5388 auto *PC
= cast
<OMPFirstprivateClause
>(Cl
);
5389 I
= PC
->private_copies().begin();
5390 It
= PC
->varlist_begin();
5391 Et
= PC
->varlist_end();
5392 } else if (Cl
->getClauseKind() == OMPC_lastprivate
) {
5393 auto *PC
= cast
<OMPLastprivateClause
>(Cl
);
5394 I
= PC
->private_copies().begin();
5395 It
= PC
->varlist_begin();
5396 Et
= PC
->varlist_end();
5397 } else if (Cl
->getClauseKind() == OMPC_linear
) {
5398 auto *PC
= cast
<OMPLinearClause
>(Cl
);
5399 I
= PC
->privates().begin();
5400 It
= PC
->varlist_begin();
5401 Et
= PC
->varlist_end();
5402 } else if (Cl
->getClauseKind() == OMPC_reduction
) {
5403 auto *PC
= cast
<OMPReductionClause
>(Cl
);
5404 I
= PC
->privates().begin();
5405 It
= PC
->varlist_begin();
5406 Et
= PC
->varlist_end();
5407 } else if (Cl
->getClauseKind() == OMPC_task_reduction
) {
5408 auto *PC
= cast
<OMPTaskReductionClause
>(Cl
);
5409 I
= PC
->privates().begin();
5410 It
= PC
->varlist_begin();
5411 Et
= PC
->varlist_end();
5412 } else if (Cl
->getClauseKind() == OMPC_in_reduction
) {
5413 auto *PC
= cast
<OMPInReductionClause
>(Cl
);
5414 I
= PC
->privates().begin();
5415 It
= PC
->varlist_begin();
5416 Et
= PC
->varlist_end();
5418 llvm_unreachable("Expected private clause.");
5420 for (Expr
*E
: llvm::make_range(It
, Et
)) {
5425 SourceLocation ELoc
;
5427 Expr
*SimpleRefExpr
= E
;
5428 auto Res
= getPrivateItem(S
, SimpleRefExpr
, ELoc
, ERange
,
5429 /*AllowArraySection=*/true);
5430 DeclToCopy
.try_emplace(Res
.first
,
5431 cast
<VarDecl
>(cast
<DeclRefExpr
>(*I
)->getDecl()));
5435 for (OMPClause
*C
: AllocateRange
) {
5436 auto *AC
= cast
<OMPAllocateClause
>(C
);
5437 if (S
.getLangOpts().OpenMP
>= 50 &&
5438 !Stack
->hasRequiresDeclWithClause
<OMPDynamicAllocatorsClause
>() &&
5439 isOpenMPTargetExecutionDirective(Stack
->getCurrentDirective()) &&
5440 AC
->getAllocator()) {
5441 Expr
*Allocator
= AC
->getAllocator();
5442 // OpenMP, 2.12.5 target Construct
5443 // Memory allocators that do not appear in a uses_allocators clause cannot
5444 // appear as an allocator in an allocate clause or be used in the target
5445 // region unless a requires directive with the dynamic_allocators clause
5446 // is present in the same compilation unit.
5447 AllocatorChecker
Checker(Stack
);
5448 if (Checker
.Visit(Allocator
))
5449 S
.Diag(Allocator
->getExprLoc(),
5450 diag::err_omp_allocator_not_in_uses_allocators
)
5451 << Allocator
->getSourceRange();
5453 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind
=
5454 getAllocatorKind(S
, Stack
, AC
->getAllocator());
5455 // OpenMP, 2.11.4 allocate Clause, Restrictions.
5456 // For task, taskloop or target directives, allocation requests to memory
5457 // allocators with the trait access set to thread result in unspecified
5459 if (AllocatorKind
== OMPAllocateDeclAttr::OMPThreadMemAlloc
&&
5460 (isOpenMPTaskingDirective(Stack
->getCurrentDirective()) ||
5461 isOpenMPTargetExecutionDirective(Stack
->getCurrentDirective()))) {
5462 S
.Diag(AC
->getAllocator()->getExprLoc(),
5463 diag::warn_omp_allocate_thread_on_task_target_directive
)
5464 << getOpenMPDirectiveName(Stack
->getCurrentDirective());
5466 for (Expr
*E
: AC
->varlists()) {
5467 SourceLocation ELoc
;
5469 Expr
*SimpleRefExpr
= E
;
5470 auto Res
= getPrivateItem(S
, SimpleRefExpr
, ELoc
, ERange
);
5471 ValueDecl
*VD
= Res
.first
;
5472 DSAStackTy::DSAVarData Data
= Stack
->getTopDSA(VD
, /*FromParent=*/false);
5473 if (!isOpenMPPrivate(Data
.CKind
)) {
5474 S
.Diag(E
->getExprLoc(),
5475 diag::err_omp_expected_private_copy_for_allocate
);
5478 VarDecl
*PrivateVD
= DeclToCopy
[VD
];
5479 if (checkPreviousOMPAllocateAttribute(S
, Stack
, E
, PrivateVD
,
5480 AllocatorKind
, AC
->getAllocator()))
5482 // Placeholder until allocate clause supports align modifier.
5483 Expr
*Alignment
= nullptr;
5484 applyOMPAllocateAttribute(S
, PrivateVD
, AllocatorKind
, AC
->getAllocator(),
5485 Alignment
, E
->getSourceRange());
5491 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5493 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5494 /// context. DeclRefExpr used inside the new context are changed to refer to the
5495 /// captured variable instead.
5496 class CaptureVars
: public TreeTransform
<CaptureVars
> {
5497 using BaseTransform
= TreeTransform
<CaptureVars
>;
5500 CaptureVars(Sema
&Actions
) : BaseTransform(Actions
) {}
5502 bool AlwaysRebuild() { return true; }
5506 static VarDecl
*precomputeExpr(Sema
&Actions
,
5507 SmallVectorImpl
<Stmt
*> &BodyStmts
, Expr
*E
,
5509 Expr
*NewE
= AssertSuccess(CaptureVars(Actions
).TransformExpr(E
));
5510 VarDecl
*NewVar
= buildVarDecl(Actions
, {}, NewE
->getType(), Name
, nullptr,
5511 dyn_cast
<DeclRefExpr
>(E
->IgnoreImplicit()));
5512 auto *NewDeclStmt
= cast
<DeclStmt
>(AssertSuccess(
5513 Actions
.ActOnDeclStmt(Actions
.ConvertDeclToDeclGroup(NewVar
), {}, {})));
5514 Actions
.AddInitializerToDecl(NewDeclStmt
->getSingleDecl(), NewE
, false);
5515 BodyStmts
.push_back(NewDeclStmt
);
5519 /// Create a closure that computes the number of iterations of a loop.
5521 /// \param Actions The Sema object.
5522 /// \param LogicalTy Type for the logical iteration number.
5523 /// \param Rel Comparison operator of the loop condition.
5524 /// \param StartExpr Value of the loop counter at the first iteration.
5525 /// \param StopExpr Expression the loop counter is compared against in the loop
5526 /// condition. \param StepExpr Amount of increment after each iteration.
5528 /// \return Closure (CapturedStmt) of the distance calculation.
5529 static CapturedStmt
*buildDistanceFunc(Sema
&Actions
, QualType LogicalTy
,
5530 BinaryOperator::Opcode Rel
,
5531 Expr
*StartExpr
, Expr
*StopExpr
,
5533 ASTContext
&Ctx
= Actions
.getASTContext();
5534 TypeSourceInfo
*LogicalTSI
= Ctx
.getTrivialTypeSourceInfo(LogicalTy
);
5536 // Captured regions currently don't support return values, we use an
5537 // out-parameter instead. All inputs are implicit captures.
5538 // TODO: Instead of capturing each DeclRefExpr occurring in
5539 // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5540 QualType ResultTy
= Ctx
.getLValueReferenceType(LogicalTy
);
5541 Sema::CapturedParamNameType Params
[] = {{"Distance", ResultTy
},
5542 {StringRef(), QualType()}};
5543 Actions
.ActOnCapturedRegionStart({}, nullptr, CR_Default
, Params
);
5547 Sema::CompoundScopeRAII
CompoundScope(Actions
);
5548 CapturedDecl
*CS
= cast
<CapturedDecl
>(Actions
.CurContext
);
5550 // Get the LValue expression for the result.
5551 ImplicitParamDecl
*DistParam
= CS
->getParam(0);
5552 DeclRefExpr
*DistRef
= Actions
.BuildDeclRefExpr(
5553 DistParam
, LogicalTy
, VK_LValue
, {}, nullptr, nullptr, {}, nullptr);
5555 SmallVector
<Stmt
*, 4> BodyStmts
;
5557 // Capture all referenced variable references.
5558 // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5559 // CapturedStmt, we could compute them before and capture the result, to be
5560 // used jointly with the LoopVar function.
5561 VarDecl
*NewStart
= precomputeExpr(Actions
, BodyStmts
, StartExpr
, ".start");
5562 VarDecl
*NewStop
= precomputeExpr(Actions
, BodyStmts
, StopExpr
, ".stop");
5563 VarDecl
*NewStep
= precomputeExpr(Actions
, BodyStmts
, StepExpr
, ".step");
5564 auto BuildVarRef
= [&](VarDecl
*VD
) {
5565 return buildDeclRefExpr(Actions
, VD
, VD
->getType(), {});
5568 IntegerLiteral
*Zero
= IntegerLiteral::Create(
5569 Ctx
, llvm::APInt(Ctx
.getIntWidth(LogicalTy
), 0), LogicalTy
, {});
5570 IntegerLiteral
*One
= IntegerLiteral::Create(
5571 Ctx
, llvm::APInt(Ctx
.getIntWidth(LogicalTy
), 1), LogicalTy
, {});
5574 // When using a != comparison, the increment can be +1 or -1. This can be
5575 // dynamic at runtime, so we need to check for the direction.
5576 Expr
*IsNegStep
= AssertSuccess(
5577 Actions
.BuildBinOp(nullptr, {}, BO_LT
, BuildVarRef(NewStep
), Zero
));
5579 // Positive increment.
5580 Expr
*ForwardRange
= AssertSuccess(Actions
.BuildBinOp(
5581 nullptr, {}, BO_Sub
, BuildVarRef(NewStop
), BuildVarRef(NewStart
)));
5582 ForwardRange
= AssertSuccess(
5583 Actions
.BuildCStyleCastExpr({}, LogicalTSI
, {}, ForwardRange
));
5584 Expr
*ForwardDist
= AssertSuccess(Actions
.BuildBinOp(
5585 nullptr, {}, BO_Div
, ForwardRange
, BuildVarRef(NewStep
)));
5587 // Negative increment.
5588 Expr
*BackwardRange
= AssertSuccess(Actions
.BuildBinOp(
5589 nullptr, {}, BO_Sub
, BuildVarRef(NewStart
), BuildVarRef(NewStop
)));
5590 BackwardRange
= AssertSuccess(
5591 Actions
.BuildCStyleCastExpr({}, LogicalTSI
, {}, BackwardRange
));
5592 Expr
*NegIncAmount
= AssertSuccess(
5593 Actions
.BuildUnaryOp(nullptr, {}, UO_Minus
, BuildVarRef(NewStep
)));
5594 Expr
*BackwardDist
= AssertSuccess(
5595 Actions
.BuildBinOp(nullptr, {}, BO_Div
, BackwardRange
, NegIncAmount
));
5597 // Use the appropriate case.
5598 Dist
= AssertSuccess(Actions
.ActOnConditionalOp(
5599 {}, {}, IsNegStep
, BackwardDist
, ForwardDist
));
5601 assert((Rel
== BO_LT
|| Rel
== BO_LE
|| Rel
== BO_GE
|| Rel
== BO_GT
) &&
5602 "Expected one of these relational operators");
5604 // We can derive the direction from any other comparison operator. It is
5605 // non well-formed OpenMP if Step increments/decrements in the other
5606 // directions. Whether at least the first iteration passes the loop
5608 Expr
*HasAnyIteration
= AssertSuccess(Actions
.BuildBinOp(
5609 nullptr, {}, Rel
, BuildVarRef(NewStart
), BuildVarRef(NewStop
)));
5611 // Compute the range between first and last counter value.
5613 if (Rel
== BO_GE
|| Rel
== BO_GT
)
5614 Range
= AssertSuccess(Actions
.BuildBinOp(
5615 nullptr, {}, BO_Sub
, BuildVarRef(NewStart
), BuildVarRef(NewStop
)));
5617 Range
= AssertSuccess(Actions
.BuildBinOp(
5618 nullptr, {}, BO_Sub
, BuildVarRef(NewStop
), BuildVarRef(NewStart
)));
5620 // Ensure unsigned range space.
5622 AssertSuccess(Actions
.BuildCStyleCastExpr({}, LogicalTSI
, {}, Range
));
5624 if (Rel
== BO_LE
|| Rel
== BO_GE
) {
5625 // Add one to the range if the relational operator is inclusive.
5627 AssertSuccess(Actions
.BuildBinOp(nullptr, {}, BO_Add
, Range
, One
));
5630 // Divide by the absolute step amount. If the range is not a multiple of
5631 // the step size, rounding-up the effective upper bound ensures that the
5632 // last iteration is included.
5633 // Note that the rounding-up may cause an overflow in a temporry that
5634 // could be avoided, but would have occurred in a C-style for-loop as well.
5635 Expr
*Divisor
= BuildVarRef(NewStep
);
5636 if (Rel
== BO_GE
|| Rel
== BO_GT
)
5638 AssertSuccess(Actions
.BuildUnaryOp(nullptr, {}, UO_Minus
, Divisor
));
5639 Expr
*DivisorMinusOne
=
5640 AssertSuccess(Actions
.BuildBinOp(nullptr, {}, BO_Sub
, Divisor
, One
));
5641 Expr
*RangeRoundUp
= AssertSuccess(
5642 Actions
.BuildBinOp(nullptr, {}, BO_Add
, Range
, DivisorMinusOne
));
5643 Dist
= AssertSuccess(
5644 Actions
.BuildBinOp(nullptr, {}, BO_Div
, RangeRoundUp
, Divisor
));
5646 // If there is not at least one iteration, the range contains garbage. Fix
5647 // to zero in this case.
5648 Dist
= AssertSuccess(
5649 Actions
.ActOnConditionalOp({}, {}, HasAnyIteration
, Dist
, Zero
));
5652 // Assign the result to the out-parameter.
5653 Stmt
*ResultAssign
= AssertSuccess(Actions
.BuildBinOp(
5654 Actions
.getCurScope(), {}, BO_Assign
, DistRef
, Dist
));
5655 BodyStmts
.push_back(ResultAssign
);
5657 Body
= AssertSuccess(Actions
.ActOnCompoundStmt({}, {}, BodyStmts
, false));
5660 return cast
<CapturedStmt
>(
5661 AssertSuccess(Actions
.ActOnCapturedRegionEnd(Body
)));
5664 /// Create a closure that computes the loop variable from the logical iteration
5667 /// \param Actions The Sema object.
5668 /// \param LoopVarTy Type for the loop variable used for result value.
5669 /// \param LogicalTy Type for the logical iteration number.
5670 /// \param StartExpr Value of the loop counter at the first iteration.
5671 /// \param Step Amount of increment after each iteration.
5672 /// \param Deref Whether the loop variable is a dereference of the loop
5673 /// counter variable.
5675 /// \return Closure (CapturedStmt) of the loop value calculation.
5676 static CapturedStmt
*buildLoopVarFunc(Sema
&Actions
, QualType LoopVarTy
,
5678 DeclRefExpr
*StartExpr
, Expr
*Step
,
5680 ASTContext
&Ctx
= Actions
.getASTContext();
5682 // Pass the result as an out-parameter. Passing as return value would require
5683 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5684 // invoke a copy constructor.
5685 QualType TargetParamTy
= Ctx
.getLValueReferenceType(LoopVarTy
);
5686 Sema::CapturedParamNameType Params
[] = {{"LoopVar", TargetParamTy
},
5687 {"Logical", LogicalTy
},
5688 {StringRef(), QualType()}};
5689 Actions
.ActOnCapturedRegionStart({}, nullptr, CR_Default
, Params
);
5691 // Capture the initial iterator which represents the LoopVar value at the
5692 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5693 // it in every iteration, capture it by value before it is modified.
5694 VarDecl
*StartVar
= cast
<VarDecl
>(StartExpr
->getDecl());
5695 bool Invalid
= Actions
.tryCaptureVariable(StartVar
, {},
5696 Sema::TryCapture_ExplicitByVal
, {});
5698 assert(!Invalid
&& "Expecting capture-by-value to work.");
5702 Sema::CompoundScopeRAII
CompoundScope(Actions
);
5703 auto *CS
= cast
<CapturedDecl
>(Actions
.CurContext
);
5705 ImplicitParamDecl
*TargetParam
= CS
->getParam(0);
5706 DeclRefExpr
*TargetRef
= Actions
.BuildDeclRefExpr(
5707 TargetParam
, LoopVarTy
, VK_LValue
, {}, nullptr, nullptr, {}, nullptr);
5708 ImplicitParamDecl
*IndvarParam
= CS
->getParam(1);
5709 DeclRefExpr
*LogicalRef
= Actions
.BuildDeclRefExpr(
5710 IndvarParam
, LogicalTy
, VK_LValue
, {}, nullptr, nullptr, {}, nullptr);
5712 // Capture the Start expression.
5713 CaptureVars
Recap(Actions
);
5714 Expr
*NewStart
= AssertSuccess(Recap
.TransformExpr(StartExpr
));
5715 Expr
*NewStep
= AssertSuccess(Recap
.TransformExpr(Step
));
5717 Expr
*Skip
= AssertSuccess(
5718 Actions
.BuildBinOp(nullptr, {}, BO_Mul
, NewStep
, LogicalRef
));
5719 // TODO: Explicitly cast to the iterator's difference_type instead of
5720 // relying on implicit conversion.
5722 AssertSuccess(Actions
.BuildBinOp(nullptr, {}, BO_Add
, NewStart
, Skip
));
5725 // For range-based for-loops convert the loop counter value to a concrete
5726 // loop variable value by dereferencing the iterator.
5728 AssertSuccess(Actions
.BuildUnaryOp(nullptr, {}, UO_Deref
, Advanced
));
5731 // Assign the result to the output parameter.
5732 Body
= AssertSuccess(Actions
.BuildBinOp(Actions
.getCurScope(), {},
5733 BO_Assign
, TargetRef
, Advanced
));
5735 return cast
<CapturedStmt
>(
5736 AssertSuccess(Actions
.ActOnCapturedRegionEnd(Body
)));
5739 StmtResult
Sema::ActOnOpenMPCanonicalLoop(Stmt
*AStmt
) {
5740 ASTContext
&Ctx
= getASTContext();
5742 // Extract the common elements of ForStmt and CXXForRangeStmt:
5743 // Loop variable, repeat condition, increment
5745 VarDecl
*LIVDecl
, *LUVDecl
;
5746 if (auto *For
= dyn_cast
<ForStmt
>(AStmt
)) {
5747 Stmt
*Init
= For
->getInit();
5748 if (auto *LCVarDeclStmt
= dyn_cast
<DeclStmt
>(Init
)) {
5749 // For statement declares loop variable.
5750 LIVDecl
= cast
<VarDecl
>(LCVarDeclStmt
->getSingleDecl());
5751 } else if (auto *LCAssign
= dyn_cast
<BinaryOperator
>(Init
)) {
5752 // For statement reuses variable.
5753 assert(LCAssign
->getOpcode() == BO_Assign
&&
5754 "init part must be a loop variable assignment");
5755 auto *CounterRef
= cast
<DeclRefExpr
>(LCAssign
->getLHS());
5756 LIVDecl
= cast
<VarDecl
>(CounterRef
->getDecl());
5758 llvm_unreachable("Cannot determine loop variable");
5761 Cond
= For
->getCond();
5762 Inc
= For
->getInc();
5763 } else if (auto *RangeFor
= dyn_cast
<CXXForRangeStmt
>(AStmt
)) {
5764 DeclStmt
*BeginStmt
= RangeFor
->getBeginStmt();
5765 LIVDecl
= cast
<VarDecl
>(BeginStmt
->getSingleDecl());
5766 LUVDecl
= RangeFor
->getLoopVariable();
5768 Cond
= RangeFor
->getCond();
5769 Inc
= RangeFor
->getInc();
5771 llvm_unreachable("unhandled kind of loop");
5773 QualType CounterTy
= LIVDecl
->getType();
5774 QualType LVTy
= LUVDecl
->getType();
5776 // Analyze the loop condition.
5778 BinaryOperator::Opcode CondRel
;
5779 Cond
= Cond
->IgnoreImplicit();
5780 if (auto *CondBinExpr
= dyn_cast
<BinaryOperator
>(Cond
)) {
5781 LHS
= CondBinExpr
->getLHS();
5782 RHS
= CondBinExpr
->getRHS();
5783 CondRel
= CondBinExpr
->getOpcode();
5784 } else if (auto *CondCXXOp
= dyn_cast
<CXXOperatorCallExpr
>(Cond
)) {
5785 assert(CondCXXOp
->getNumArgs() == 2 && "Comparison should have 2 operands");
5786 LHS
= CondCXXOp
->getArg(0);
5787 RHS
= CondCXXOp
->getArg(1);
5788 switch (CondCXXOp
->getOperator()) {
5789 case OO_ExclaimEqual
:
5801 case OO_GreaterEqual
:
5805 llvm_unreachable("unexpected iterator operator");
5808 llvm_unreachable("unexpected loop condition");
5810 // Normalize such that the loop counter is on the LHS.
5811 if (!isa
<DeclRefExpr
>(LHS
->IgnoreImplicit()) ||
5812 cast
<DeclRefExpr
>(LHS
->IgnoreImplicit())->getDecl() != LIVDecl
) {
5813 std::swap(LHS
, RHS
);
5814 CondRel
= BinaryOperator::reverseComparisonOp(CondRel
);
5816 auto *CounterRef
= cast
<DeclRefExpr
>(LHS
->IgnoreImplicit());
5818 // Decide the bit width for the logical iteration counter. By default use the
5819 // unsigned ptrdiff_t integer size (for iterators and pointers).
5820 // TODO: For iterators, use iterator::difference_type,
5821 // std::iterator_traits<>::difference_type or decltype(it - end).
5822 QualType LogicalTy
= Ctx
.getUnsignedPointerDiffType();
5823 if (CounterTy
->isIntegerType()) {
5824 unsigned BitWidth
= Ctx
.getIntWidth(CounterTy
);
5825 LogicalTy
= Ctx
.getIntTypeForBitwidth(BitWidth
, false);
5828 // Analyze the loop increment.
5830 if (auto *IncUn
= dyn_cast
<UnaryOperator
>(Inc
)) {
5832 switch (IncUn
->getOpcode()) {
5842 llvm_unreachable("unhandled unary increment operator");
5844 Step
= IntegerLiteral::Create(
5845 Ctx
, llvm::APInt(Ctx
.getIntWidth(LogicalTy
), Direction
), LogicalTy
, {});
5846 } else if (auto *IncBin
= dyn_cast
<BinaryOperator
>(Inc
)) {
5847 if (IncBin
->getOpcode() == BO_AddAssign
) {
5848 Step
= IncBin
->getRHS();
5849 } else if (IncBin
->getOpcode() == BO_SubAssign
) {
5851 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus
, IncBin
->getRHS()));
5853 llvm_unreachable("unhandled binary increment operator");
5854 } else if (auto *CondCXXOp
= dyn_cast
<CXXOperatorCallExpr
>(Inc
)) {
5855 switch (CondCXXOp
->getOperator()) {
5857 Step
= IntegerLiteral::Create(
5858 Ctx
, llvm::APInt(Ctx
.getIntWidth(LogicalTy
), 1), LogicalTy
, {});
5861 Step
= IntegerLiteral::Create(
5862 Ctx
, llvm::APInt(Ctx
.getIntWidth(LogicalTy
), -1), LogicalTy
, {});
5865 Step
= CondCXXOp
->getArg(1);
5868 Step
= AssertSuccess(
5869 BuildUnaryOp(nullptr, {}, UO_Minus
, CondCXXOp
->getArg(1)));
5872 llvm_unreachable("unhandled overloaded increment operator");
5875 llvm_unreachable("unknown increment expression");
5877 CapturedStmt
*DistanceFunc
=
5878 buildDistanceFunc(*this, LogicalTy
, CondRel
, LHS
, RHS
, Step
);
5879 CapturedStmt
*LoopVarFunc
= buildLoopVarFunc(
5880 *this, LVTy
, LogicalTy
, CounterRef
, Step
, isa
<CXXForRangeStmt
>(AStmt
));
5881 DeclRefExpr
*LVRef
= BuildDeclRefExpr(LUVDecl
, LUVDecl
->getType(), VK_LValue
,
5882 {}, nullptr, nullptr, {}, nullptr);
5883 return OMPCanonicalLoop::create(getASTContext(), AStmt
, DistanceFunc
,
5884 LoopVarFunc
, LVRef
);
5887 StmtResult
Sema::ActOnOpenMPLoopnest(Stmt
*AStmt
) {
5888 // Handle a literal loop.
5889 if (isa
<ForStmt
>(AStmt
) || isa
<CXXForRangeStmt
>(AStmt
))
5890 return ActOnOpenMPCanonicalLoop(AStmt
);
5892 // If not a literal loop, it must be the result of a loop transformation.
5893 OMPExecutableDirective
*LoopTransform
= cast
<OMPExecutableDirective
>(AStmt
);
5895 isOpenMPLoopTransformationDirective(LoopTransform
->getDirectiveKind()) &&
5896 "Loop transformation directive expected");
5897 return LoopTransform
;
5900 static ExprResult
buildUserDefinedMapperRef(Sema
&SemaRef
, Scope
*S
,
5901 CXXScopeSpec
&MapperIdScopeSpec
,
5902 const DeclarationNameInfo
&MapperId
,
5904 Expr
*UnresolvedMapper
);
5906 /// Perform DFS through the structure/class data members trying to find
5907 /// member(s) with user-defined 'default' mapper and generate implicit map
5908 /// clauses for such members with the found 'default' mapper.
5910 processImplicitMapsWithDefaultMappers(Sema
&S
, DSAStackTy
*Stack
,
5911 SmallVectorImpl
<OMPClause
*> &Clauses
) {
5912 // Check for the deault mapper for data members.
5913 if (S
.getLangOpts().OpenMP
< 50)
5915 SmallVector
<OMPClause
*, 4> ImplicitMaps
;
5916 for (int Cnt
= 0, EndCnt
= Clauses
.size(); Cnt
< EndCnt
; ++Cnt
) {
5917 auto *C
= dyn_cast
<OMPMapClause
>(Clauses
[Cnt
]);
5920 SmallVector
<Expr
*, 4> SubExprs
;
5921 auto *MI
= C
->mapperlist_begin();
5922 for (auto I
= C
->varlist_begin(), End
= C
->varlist_end(); I
!= End
;
5924 // Expression is mapped using mapper - skip it.
5928 // Expression is dependent - skip it, build the mapper when it gets
5930 if (E
->isTypeDependent() || E
->isValueDependent() ||
5931 E
->containsUnexpandedParameterPack())
5933 // Array section - need to check for the mapping of the array section
5935 QualType CanonType
= E
->getType().getCanonicalType();
5936 if (CanonType
->isSpecificBuiltinType(BuiltinType::OMPArraySection
)) {
5937 const auto *OASE
= cast
<OMPArraySectionExpr
>(E
->IgnoreParenImpCasts());
5939 OMPArraySectionExpr::getBaseOriginalType(OASE
->getBase());
5941 if (const auto *ATy
= BaseType
->getAsArrayTypeUnsafe())
5942 ElemType
= ATy
->getElementType();
5944 ElemType
= BaseType
->getPointeeType();
5945 CanonType
= ElemType
;
5948 // DFS over data members in structures/classes.
5949 SmallVector
<std::pair
<QualType
, FieldDecl
*>, 4> Types(
5950 1, {CanonType
, nullptr});
5951 llvm::DenseMap
<const Type
*, Expr
*> Visited
;
5952 SmallVector
<std::pair
<FieldDecl
*, unsigned>, 4> ParentChain(
5954 while (!Types
.empty()) {
5957 std::tie(BaseType
, CurFD
) = Types
.pop_back_val();
5958 while (ParentChain
.back().second
== 0)
5959 ParentChain
.pop_back();
5960 --ParentChain
.back().second
;
5961 if (BaseType
.isNull())
5963 // Only structs/classes are allowed to have mappers.
5964 const RecordDecl
*RD
= BaseType
.getCanonicalType()->getAsRecordDecl();
5967 auto It
= Visited
.find(BaseType
.getTypePtr());
5968 if (It
== Visited
.end()) {
5969 // Try to find the associated user-defined mapper.
5970 CXXScopeSpec MapperIdScopeSpec
;
5971 DeclarationNameInfo DefaultMapperId
;
5972 DefaultMapperId
.setName(S
.Context
.DeclarationNames
.getIdentifier(
5973 &S
.Context
.Idents
.get("default")));
5974 DefaultMapperId
.setLoc(E
->getExprLoc());
5975 ExprResult ER
= buildUserDefinedMapperRef(
5976 S
, Stack
->getCurScope(), MapperIdScopeSpec
, DefaultMapperId
,
5977 BaseType
, /*UnresolvedMapper=*/nullptr);
5980 It
= Visited
.try_emplace(BaseType
.getTypePtr(), ER
.get()).first
;
5982 // Found default mapper.
5984 auto *OE
= new (S
.Context
) OpaqueValueExpr(E
->getExprLoc(), CanonType
,
5985 VK_LValue
, OK_Ordinary
, E
);
5986 OE
->setIsUnique(/*V=*/true);
5987 Expr
*BaseExpr
= OE
;
5988 for (const auto &P
: ParentChain
) {
5990 BaseExpr
= S
.BuildMemberExpr(
5991 BaseExpr
, /*IsArrow=*/false, E
->getExprLoc(),
5992 NestedNameSpecifierLoc(), SourceLocation(), P
.first
,
5993 DeclAccessPair::make(P
.first
, P
.first
->getAccess()),
5994 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5995 P
.first
->getType(), VK_LValue
, OK_Ordinary
);
5996 BaseExpr
= S
.DefaultLvalueConversion(BaseExpr
).get();
6000 BaseExpr
= S
.BuildMemberExpr(
6001 BaseExpr
, /*IsArrow=*/false, E
->getExprLoc(),
6002 NestedNameSpecifierLoc(), SourceLocation(), CurFD
,
6003 DeclAccessPair::make(CurFD
, CurFD
->getAccess()),
6004 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6005 CurFD
->getType(), VK_LValue
, OK_Ordinary
);
6006 SubExprs
.push_back(BaseExpr
);
6009 // Check for the "default" mapper for data members.
6010 bool FirstIter
= true;
6011 for (FieldDecl
*FD
: RD
->fields()) {
6014 QualType FieldTy
= FD
->getType();
6015 if (FieldTy
.isNull() ||
6016 !(FieldTy
->isStructureOrClassType() || FieldTy
->isUnionType()))
6020 ParentChain
.emplace_back(CurFD
, 1);
6022 ++ParentChain
.back().second
;
6024 Types
.emplace_back(FieldTy
, FD
);
6028 if (SubExprs
.empty())
6030 CXXScopeSpec MapperIdScopeSpec
;
6031 DeclarationNameInfo MapperId
;
6032 if (OMPClause
*NewClause
= S
.ActOnOpenMPMapClause(
6033 C
->getMapTypeModifiers(), C
->getMapTypeModifiersLoc(),
6034 MapperIdScopeSpec
, MapperId
, C
->getMapType(),
6035 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6036 SubExprs
, OMPVarListLocTy()))
6037 Clauses
.push_back(NewClause
);
6041 StmtResult
Sema::ActOnOpenMPExecutableDirective(
6042 OpenMPDirectiveKind Kind
, const DeclarationNameInfo
&DirName
,
6043 OpenMPDirectiveKind CancelRegion
, ArrayRef
<OMPClause
*> Clauses
,
6044 Stmt
*AStmt
, SourceLocation StartLoc
, SourceLocation EndLoc
) {
6045 StmtResult Res
= StmtError();
6046 OpenMPBindClauseKind BindKind
= OMPC_BIND_unknown
;
6047 if (const OMPBindClause
*BC
=
6048 OMPExecutableDirective::getSingleClause
<OMPBindClause
>(Clauses
))
6049 BindKind
= BC
->getBindKind();
6050 // First check CancelRegion which is then used in checkNestingOfRegions.
6051 if (checkCancelRegion(*this, Kind
, CancelRegion
, StartLoc
) ||
6052 checkNestingOfRegions(*this, DSAStack
, Kind
, DirName
, CancelRegion
,
6053 BindKind
, StartLoc
))
6056 llvm::SmallVector
<OMPClause
*, 8> ClausesWithImplicit
;
6057 VarsWithInheritedDSAType VarsWithInheritedDSA
;
6058 bool ErrorFound
= false;
6059 ClausesWithImplicit
.append(Clauses
.begin(), Clauses
.end());
6060 if (AStmt
&& !CurContext
->isDependentContext() && Kind
!= OMPD_atomic
&&
6061 Kind
!= OMPD_critical
&& Kind
!= OMPD_section
&& Kind
!= OMPD_master
&&
6062 Kind
!= OMPD_masked
&& !isOpenMPLoopTransformationDirective(Kind
)) {
6063 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
6065 // Check default data sharing attributes for referenced variables.
6066 DSAAttrChecker
DSAChecker(DSAStack
, *this, cast
<CapturedStmt
>(AStmt
));
6067 int ThisCaptureLevel
= getOpenMPCaptureLevels(Kind
);
6069 while (--ThisCaptureLevel
>= 0)
6070 S
= cast
<CapturedStmt
>(S
)->getCapturedStmt();
6071 DSAChecker
.Visit(S
);
6072 if (!isOpenMPTargetDataManagementDirective(Kind
) &&
6073 !isOpenMPTaskingDirective(Kind
)) {
6074 // Visit subcaptures to generate implicit clauses for captured vars.
6075 auto *CS
= cast
<CapturedStmt
>(AStmt
);
6076 SmallVector
<OpenMPDirectiveKind
, 4> CaptureRegions
;
6077 getOpenMPCaptureRegions(CaptureRegions
, Kind
);
6078 // Ignore outer tasking regions for target directives.
6079 if (CaptureRegions
.size() > 1 && CaptureRegions
.front() == OMPD_task
)
6080 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
6081 DSAChecker
.visitSubCaptures(CS
);
6083 if (DSAChecker
.isErrorFound())
6085 // Generate list of implicitly defined firstprivate variables.
6086 VarsWithInheritedDSA
= DSAChecker
.getVarsWithInheritedDSA();
6088 SmallVector
<Expr
*, 4> ImplicitFirstprivates(
6089 DSAChecker
.getImplicitFirstprivate().begin(),
6090 DSAChecker
.getImplicitFirstprivate().end());
6091 SmallVector
<Expr
*, 4> ImplicitPrivates(
6092 DSAChecker
.getImplicitPrivate().begin(),
6093 DSAChecker
.getImplicitPrivate().end());
6094 const unsigned DefaultmapKindNum
= OMPC_DEFAULTMAP_pointer
+ 1;
6095 SmallVector
<Expr
*, 4> ImplicitMaps
[DefaultmapKindNum
][OMPC_MAP_delete
];
6096 SmallVector
<OpenMPMapModifierKind
, NumberOfOMPMapClauseModifiers
>
6097 ImplicitMapModifiers
[DefaultmapKindNum
];
6098 SmallVector
<SourceLocation
, NumberOfOMPMapClauseModifiers
>
6099 ImplicitMapModifiersLoc
[DefaultmapKindNum
];
6100 // Get the original location of present modifier from Defaultmap clause.
6101 SourceLocation PresentModifierLocs
[DefaultmapKindNum
];
6102 for (OMPClause
*C
: Clauses
) {
6103 if (auto *DMC
= dyn_cast
<OMPDefaultmapClause
>(C
))
6104 if (DMC
->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present
)
6105 PresentModifierLocs
[DMC
->getDefaultmapKind()] =
6106 DMC
->getDefaultmapModifierLoc();
6108 for (unsigned VC
= 0; VC
< DefaultmapKindNum
; ++VC
) {
6109 auto Kind
= static_cast<OpenMPDefaultmapClauseKind
>(VC
);
6110 for (unsigned I
= 0; I
< OMPC_MAP_delete
; ++I
) {
6111 ArrayRef
<Expr
*> ImplicitMap
= DSAChecker
.getImplicitMap(
6112 Kind
, static_cast<OpenMPMapClauseKind
>(I
));
6113 ImplicitMaps
[VC
][I
].append(ImplicitMap
.begin(), ImplicitMap
.end());
6115 ArrayRef
<OpenMPMapModifierKind
> ImplicitModifier
=
6116 DSAChecker
.getImplicitMapModifier(Kind
);
6117 ImplicitMapModifiers
[VC
].append(ImplicitModifier
.begin(),
6118 ImplicitModifier
.end());
6119 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc
[VC
]),
6120 ImplicitModifier
.size(), PresentModifierLocs
[VC
]);
6122 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6123 for (OMPClause
*C
: Clauses
) {
6124 if (auto *IRC
= dyn_cast
<OMPInReductionClause
>(C
)) {
6125 for (Expr
*E
: IRC
->taskgroup_descriptors())
6127 ImplicitFirstprivates
.emplace_back(E
);
6129 // OpenMP 5.0, 2.10.1 task Construct
6130 // [detach clause]... The event-handle will be considered as if it was
6131 // specified on a firstprivate clause.
6132 if (auto *DC
= dyn_cast
<OMPDetachClause
>(C
))
6133 ImplicitFirstprivates
.push_back(DC
->getEventHandler());
6135 if (!ImplicitFirstprivates
.empty()) {
6136 if (OMPClause
*Implicit
= ActOnOpenMPFirstprivateClause(
6137 ImplicitFirstprivates
, SourceLocation(), SourceLocation(),
6138 SourceLocation())) {
6139 ClausesWithImplicit
.push_back(Implicit
);
6140 ErrorFound
= cast
<OMPFirstprivateClause
>(Implicit
)->varlist_size() !=
6141 ImplicitFirstprivates
.size();
6146 if (!ImplicitPrivates
.empty()) {
6147 if (OMPClause
*Implicit
=
6148 ActOnOpenMPPrivateClause(ImplicitPrivates
, SourceLocation(),
6149 SourceLocation(), SourceLocation())) {
6150 ClausesWithImplicit
.push_back(Implicit
);
6151 ErrorFound
= cast
<OMPPrivateClause
>(Implicit
)->varlist_size() !=
6152 ImplicitPrivates
.size();
6157 // OpenMP 5.0 [2.19.7]
6158 // If a list item appears in a reduction, lastprivate or linear
6159 // clause on a combined target construct then it is treated as
6160 // if it also appears in a map clause with a map-type of tofrom
6161 if (getLangOpts().OpenMP
>= 50 && Kind
!= OMPD_target
&&
6162 isOpenMPTargetExecutionDirective(Kind
)) {
6163 SmallVector
<Expr
*, 4> ImplicitExprs
;
6164 for (OMPClause
*C
: Clauses
) {
6165 if (auto *RC
= dyn_cast
<OMPReductionClause
>(C
))
6166 for (Expr
*E
: RC
->varlists())
6167 if (!isa
<DeclRefExpr
>(E
->IgnoreParenImpCasts()))
6168 ImplicitExprs
.emplace_back(E
);
6170 if (!ImplicitExprs
.empty()) {
6171 ArrayRef
<Expr
*> Exprs
= ImplicitExprs
;
6172 CXXScopeSpec MapperIdScopeSpec
;
6173 DeclarationNameInfo MapperId
;
6174 if (OMPClause
*Implicit
= ActOnOpenMPMapClause(
6175 OMPC_MAP_MODIFIER_unknown
, SourceLocation(), MapperIdScopeSpec
,
6176 MapperId
, OMPC_MAP_tofrom
,
6177 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6178 Exprs
, OMPVarListLocTy(), /*NoDiagnose=*/true))
6179 ClausesWithImplicit
.emplace_back(Implicit
);
6182 for (unsigned I
= 0, E
= DefaultmapKindNum
; I
< E
; ++I
) {
6183 int ClauseKindCnt
= -1;
6184 for (ArrayRef
<Expr
*> ImplicitMap
: ImplicitMaps
[I
]) {
6186 if (ImplicitMap
.empty())
6188 CXXScopeSpec MapperIdScopeSpec
;
6189 DeclarationNameInfo MapperId
;
6190 auto Kind
= static_cast<OpenMPMapClauseKind
>(ClauseKindCnt
);
6191 if (OMPClause
*Implicit
= ActOnOpenMPMapClause(
6192 ImplicitMapModifiers
[I
], ImplicitMapModifiersLoc
[I
],
6193 MapperIdScopeSpec
, MapperId
, Kind
, /*IsMapTypeImplicit=*/true,
6194 SourceLocation(), SourceLocation(), ImplicitMap
,
6195 OMPVarListLocTy())) {
6196 ClausesWithImplicit
.emplace_back(Implicit
);
6197 ErrorFound
|= cast
<OMPMapClause
>(Implicit
)->varlist_size() !=
6204 // Build expressions for implicit maps of data members with 'default'
6206 if (LangOpts
.OpenMP
>= 50)
6207 processImplicitMapsWithDefaultMappers(*this, DSAStack
,
6208 ClausesWithImplicit
);
6211 llvm::SmallVector
<OpenMPDirectiveKind
, 4> AllowedNameModifiers
;
6214 Res
= ActOnOpenMPParallelDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6216 AllowedNameModifiers
.push_back(OMPD_parallel
);
6219 Res
= ActOnOpenMPSimdDirective(ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
,
6220 VarsWithInheritedDSA
);
6221 if (LangOpts
.OpenMP
>= 50)
6222 AllowedNameModifiers
.push_back(OMPD_simd
);
6226 ActOnOpenMPTileDirective(ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
);
6229 Res
= ActOnOpenMPUnrollDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6233 Res
= ActOnOpenMPForDirective(ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
,
6234 VarsWithInheritedDSA
);
6237 Res
= ActOnOpenMPForSimdDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6238 EndLoc
, VarsWithInheritedDSA
);
6239 if (LangOpts
.OpenMP
>= 50)
6240 AllowedNameModifiers
.push_back(OMPD_simd
);
6243 Res
= ActOnOpenMPSectionsDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6247 assert(ClausesWithImplicit
.empty() &&
6248 "No clauses are allowed for 'omp section' directive");
6249 Res
= ActOnOpenMPSectionDirective(AStmt
, StartLoc
, EndLoc
);
6252 Res
= ActOnOpenMPSingleDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6256 assert(ClausesWithImplicit
.empty() &&
6257 "No clauses are allowed for 'omp master' directive");
6258 Res
= ActOnOpenMPMasterDirective(AStmt
, StartLoc
, EndLoc
);
6261 Res
= ActOnOpenMPMaskedDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6265 Res
= ActOnOpenMPCriticalDirective(DirName
, ClausesWithImplicit
, AStmt
,
6268 case OMPD_parallel_for
:
6269 Res
= ActOnOpenMPParallelForDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6270 EndLoc
, VarsWithInheritedDSA
);
6271 AllowedNameModifiers
.push_back(OMPD_parallel
);
6273 case OMPD_parallel_for_simd
:
6274 Res
= ActOnOpenMPParallelForSimdDirective(
6275 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6276 AllowedNameModifiers
.push_back(OMPD_parallel
);
6277 if (LangOpts
.OpenMP
>= 50)
6278 AllowedNameModifiers
.push_back(OMPD_simd
);
6280 case OMPD_parallel_master
:
6281 Res
= ActOnOpenMPParallelMasterDirective(ClausesWithImplicit
, AStmt
,
6283 AllowedNameModifiers
.push_back(OMPD_parallel
);
6285 case OMPD_parallel_masked
:
6286 Res
= ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit
, AStmt
,
6288 AllowedNameModifiers
.push_back(OMPD_parallel
);
6290 case OMPD_parallel_sections
:
6291 Res
= ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit
, AStmt
,
6293 AllowedNameModifiers
.push_back(OMPD_parallel
);
6297 ActOnOpenMPTaskDirective(ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
);
6298 AllowedNameModifiers
.push_back(OMPD_task
);
6300 case OMPD_taskyield
:
6301 assert(ClausesWithImplicit
.empty() &&
6302 "No clauses are allowed for 'omp taskyield' directive");
6303 assert(AStmt
== nullptr &&
6304 "No associated statement allowed for 'omp taskyield' directive");
6305 Res
= ActOnOpenMPTaskyieldDirective(StartLoc
, EndLoc
);
6308 assert(ClausesWithImplicit
.empty() &&
6309 "No clauses are allowed for 'omp barrier' directive");
6310 assert(AStmt
== nullptr &&
6311 "No associated statement allowed for 'omp barrier' directive");
6312 Res
= ActOnOpenMPBarrierDirective(StartLoc
, EndLoc
);
6315 assert(AStmt
== nullptr &&
6316 "No associated statement allowed for 'omp taskwait' directive");
6317 Res
= ActOnOpenMPTaskwaitDirective(ClausesWithImplicit
, StartLoc
, EndLoc
);
6319 case OMPD_taskgroup
:
6320 Res
= ActOnOpenMPTaskgroupDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6324 assert(AStmt
== nullptr &&
6325 "No associated statement allowed for 'omp flush' directive");
6326 Res
= ActOnOpenMPFlushDirective(ClausesWithImplicit
, StartLoc
, EndLoc
);
6329 assert(AStmt
== nullptr &&
6330 "No associated statement allowed for 'omp depobj' directive");
6331 Res
= ActOnOpenMPDepobjDirective(ClausesWithImplicit
, StartLoc
, EndLoc
);
6334 assert(AStmt
== nullptr &&
6335 "No associated statement allowed for 'omp scan' directive");
6336 Res
= ActOnOpenMPScanDirective(ClausesWithImplicit
, StartLoc
, EndLoc
);
6339 Res
= ActOnOpenMPOrderedDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6343 Res
= ActOnOpenMPAtomicDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6348 ActOnOpenMPTeamsDirective(ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
);
6351 Res
= ActOnOpenMPTargetDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6353 AllowedNameModifiers
.push_back(OMPD_target
);
6355 case OMPD_target_parallel
:
6356 Res
= ActOnOpenMPTargetParallelDirective(ClausesWithImplicit
, AStmt
,
6358 AllowedNameModifiers
.push_back(OMPD_target
);
6359 AllowedNameModifiers
.push_back(OMPD_parallel
);
6361 case OMPD_target_parallel_for
:
6362 Res
= ActOnOpenMPTargetParallelForDirective(
6363 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6364 AllowedNameModifiers
.push_back(OMPD_target
);
6365 AllowedNameModifiers
.push_back(OMPD_parallel
);
6367 case OMPD_cancellation_point
:
6368 assert(ClausesWithImplicit
.empty() &&
6369 "No clauses are allowed for 'omp cancellation point' directive");
6370 assert(AStmt
== nullptr && "No associated statement allowed for 'omp "
6371 "cancellation point' directive");
6372 Res
= ActOnOpenMPCancellationPointDirective(StartLoc
, EndLoc
, CancelRegion
);
6375 assert(AStmt
== nullptr &&
6376 "No associated statement allowed for 'omp cancel' directive");
6377 Res
= ActOnOpenMPCancelDirective(ClausesWithImplicit
, StartLoc
, EndLoc
,
6379 AllowedNameModifiers
.push_back(OMPD_cancel
);
6381 case OMPD_target_data
:
6382 Res
= ActOnOpenMPTargetDataDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6384 AllowedNameModifiers
.push_back(OMPD_target_data
);
6386 case OMPD_target_enter_data
:
6387 Res
= ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit
, StartLoc
,
6389 AllowedNameModifiers
.push_back(OMPD_target_enter_data
);
6391 case OMPD_target_exit_data
:
6392 Res
= ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit
, StartLoc
,
6394 AllowedNameModifiers
.push_back(OMPD_target_exit_data
);
6397 Res
= ActOnOpenMPTaskLoopDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6398 EndLoc
, VarsWithInheritedDSA
);
6399 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6401 case OMPD_taskloop_simd
:
6402 Res
= ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6403 EndLoc
, VarsWithInheritedDSA
);
6404 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6405 if (LangOpts
.OpenMP
>= 50)
6406 AllowedNameModifiers
.push_back(OMPD_simd
);
6408 case OMPD_master_taskloop
:
6409 Res
= ActOnOpenMPMasterTaskLoopDirective(
6410 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6411 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6413 case OMPD_masked_taskloop
:
6414 Res
= ActOnOpenMPMaskedTaskLoopDirective(
6415 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6416 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6418 case OMPD_master_taskloop_simd
:
6419 Res
= ActOnOpenMPMasterTaskLoopSimdDirective(
6420 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6421 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6422 if (LangOpts
.OpenMP
>= 50)
6423 AllowedNameModifiers
.push_back(OMPD_simd
);
6425 case OMPD_masked_taskloop_simd
:
6426 Res
= ActOnOpenMPMaskedTaskLoopSimdDirective(
6427 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6428 if (LangOpts
.OpenMP
>= 51) {
6429 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6430 AllowedNameModifiers
.push_back(OMPD_simd
);
6433 case OMPD_parallel_master_taskloop
:
6434 Res
= ActOnOpenMPParallelMasterTaskLoopDirective(
6435 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6436 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6437 AllowedNameModifiers
.push_back(OMPD_parallel
);
6439 case OMPD_parallel_masked_taskloop
:
6440 Res
= ActOnOpenMPParallelMaskedTaskLoopDirective(
6441 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6442 if (LangOpts
.OpenMP
>= 51) {
6443 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6444 AllowedNameModifiers
.push_back(OMPD_parallel
);
6447 case OMPD_parallel_master_taskloop_simd
:
6448 Res
= ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6449 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6450 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6451 AllowedNameModifiers
.push_back(OMPD_parallel
);
6452 if (LangOpts
.OpenMP
>= 50)
6453 AllowedNameModifiers
.push_back(OMPD_simd
);
6455 case OMPD_parallel_masked_taskloop_simd
:
6456 Res
= ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6457 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6458 if (LangOpts
.OpenMP
>= 51) {
6459 AllowedNameModifiers
.push_back(OMPD_taskloop
);
6460 AllowedNameModifiers
.push_back(OMPD_parallel
);
6461 AllowedNameModifiers
.push_back(OMPD_simd
);
6464 case OMPD_distribute
:
6465 Res
= ActOnOpenMPDistributeDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6466 EndLoc
, VarsWithInheritedDSA
);
6468 case OMPD_target_update
:
6469 Res
= ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit
, StartLoc
,
6471 AllowedNameModifiers
.push_back(OMPD_target_update
);
6473 case OMPD_distribute_parallel_for
:
6474 Res
= ActOnOpenMPDistributeParallelForDirective(
6475 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6476 AllowedNameModifiers
.push_back(OMPD_parallel
);
6478 case OMPD_distribute_parallel_for_simd
:
6479 Res
= ActOnOpenMPDistributeParallelForSimdDirective(
6480 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6481 AllowedNameModifiers
.push_back(OMPD_parallel
);
6482 if (LangOpts
.OpenMP
>= 50)
6483 AllowedNameModifiers
.push_back(OMPD_simd
);
6485 case OMPD_distribute_simd
:
6486 Res
= ActOnOpenMPDistributeSimdDirective(
6487 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6488 if (LangOpts
.OpenMP
>= 50)
6489 AllowedNameModifiers
.push_back(OMPD_simd
);
6491 case OMPD_target_parallel_for_simd
:
6492 Res
= ActOnOpenMPTargetParallelForSimdDirective(
6493 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6494 AllowedNameModifiers
.push_back(OMPD_target
);
6495 AllowedNameModifiers
.push_back(OMPD_parallel
);
6496 if (LangOpts
.OpenMP
>= 50)
6497 AllowedNameModifiers
.push_back(OMPD_simd
);
6499 case OMPD_target_simd
:
6500 Res
= ActOnOpenMPTargetSimdDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6501 EndLoc
, VarsWithInheritedDSA
);
6502 AllowedNameModifiers
.push_back(OMPD_target
);
6503 if (LangOpts
.OpenMP
>= 50)
6504 AllowedNameModifiers
.push_back(OMPD_simd
);
6506 case OMPD_teams_distribute
:
6507 Res
= ActOnOpenMPTeamsDistributeDirective(
6508 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6510 case OMPD_teams_distribute_simd
:
6511 Res
= ActOnOpenMPTeamsDistributeSimdDirective(
6512 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6513 if (LangOpts
.OpenMP
>= 50)
6514 AllowedNameModifiers
.push_back(OMPD_simd
);
6516 case OMPD_teams_distribute_parallel_for_simd
:
6517 Res
= ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6518 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6519 AllowedNameModifiers
.push_back(OMPD_parallel
);
6520 if (LangOpts
.OpenMP
>= 50)
6521 AllowedNameModifiers
.push_back(OMPD_simd
);
6523 case OMPD_teams_distribute_parallel_for
:
6524 Res
= ActOnOpenMPTeamsDistributeParallelForDirective(
6525 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6526 AllowedNameModifiers
.push_back(OMPD_parallel
);
6528 case OMPD_target_teams
:
6529 Res
= ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6531 AllowedNameModifiers
.push_back(OMPD_target
);
6533 case OMPD_target_teams_distribute
:
6534 Res
= ActOnOpenMPTargetTeamsDistributeDirective(
6535 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6536 AllowedNameModifiers
.push_back(OMPD_target
);
6538 case OMPD_target_teams_distribute_parallel_for
:
6539 Res
= ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6540 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6541 AllowedNameModifiers
.push_back(OMPD_target
);
6542 AllowedNameModifiers
.push_back(OMPD_parallel
);
6544 case OMPD_target_teams_distribute_parallel_for_simd
:
6545 Res
= ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6546 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6547 AllowedNameModifiers
.push_back(OMPD_target
);
6548 AllowedNameModifiers
.push_back(OMPD_parallel
);
6549 if (LangOpts
.OpenMP
>= 50)
6550 AllowedNameModifiers
.push_back(OMPD_simd
);
6552 case OMPD_target_teams_distribute_simd
:
6553 Res
= ActOnOpenMPTargetTeamsDistributeSimdDirective(
6554 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6555 AllowedNameModifiers
.push_back(OMPD_target
);
6556 if (LangOpts
.OpenMP
>= 50)
6557 AllowedNameModifiers
.push_back(OMPD_simd
);
6560 assert(AStmt
== nullptr &&
6561 "No associated statement allowed for 'omp interop' directive");
6562 Res
= ActOnOpenMPInteropDirective(ClausesWithImplicit
, StartLoc
, EndLoc
);
6565 Res
= ActOnOpenMPDispatchDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6569 Res
= ActOnOpenMPGenericLoopDirective(ClausesWithImplicit
, AStmt
, StartLoc
,
6570 EndLoc
, VarsWithInheritedDSA
);
6572 case OMPD_teams_loop
:
6573 Res
= ActOnOpenMPTeamsGenericLoopDirective(
6574 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6576 case OMPD_target_teams_loop
:
6577 Res
= ActOnOpenMPTargetTeamsGenericLoopDirective(
6578 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6580 case OMPD_parallel_loop
:
6581 Res
= ActOnOpenMPParallelGenericLoopDirective(
6582 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6584 case OMPD_target_parallel_loop
:
6585 Res
= ActOnOpenMPTargetParallelGenericLoopDirective(
6586 ClausesWithImplicit
, AStmt
, StartLoc
, EndLoc
, VarsWithInheritedDSA
);
6588 case OMPD_declare_target
:
6589 case OMPD_end_declare_target
:
6590 case OMPD_threadprivate
:
6592 case OMPD_declare_reduction
:
6593 case OMPD_declare_mapper
:
6594 case OMPD_declare_simd
:
6596 case OMPD_declare_variant
:
6597 case OMPD_begin_declare_variant
:
6598 case OMPD_end_declare_variant
:
6599 llvm_unreachable("OpenMP Directive is not allowed");
6602 llvm_unreachable("Unknown OpenMP directive");
6605 ErrorFound
= Res
.isInvalid() || ErrorFound
;
6607 // Check variables in the clauses if default(none) or
6608 // default(firstprivate) was specified.
6609 if (DSAStack
->getDefaultDSA() == DSA_none
||
6610 DSAStack
->getDefaultDSA() == DSA_private
||
6611 DSAStack
->getDefaultDSA() == DSA_firstprivate
) {
6612 DSAAttrChecker
DSAChecker(DSAStack
, *this, nullptr);
6613 for (OMPClause
*C
: Clauses
) {
6614 switch (C
->getClauseKind()) {
6615 case OMPC_num_threads
:
6616 case OMPC_dist_schedule
:
6617 // Do not analyse if no parent teams directive.
6618 if (isOpenMPTeamsDirective(Kind
))
6622 if (isOpenMPTeamsDirective(Kind
) &&
6623 cast
<OMPIfClause
>(C
)->getNameModifier() != OMPD_target
)
6625 if (isOpenMPParallelDirective(Kind
) &&
6626 isOpenMPTaskLoopDirective(Kind
) &&
6627 cast
<OMPIfClause
>(C
)->getNameModifier() != OMPD_parallel
)
6633 case OMPC_grainsize
:
6634 case OMPC_num_tasks
:
6637 case OMPC_novariants
:
6638 case OMPC_nocontext
:
6639 // Do not analyze if no parent parallel directive.
6640 if (isOpenMPParallelDirective(Kind
))
6645 case OMPC_num_teams
:
6646 case OMPC_thread_limit
:
6653 case OMPC_proc_bind
:
6655 case OMPC_firstprivate
:
6656 case OMPC_lastprivate
:
6658 case OMPC_reduction
:
6659 case OMPC_task_reduction
:
6660 case OMPC_in_reduction
:
6664 case OMPC_copyprivate
:
6667 case OMPC_mergeable
:
6684 case OMPC_defaultmap
:
6687 case OMPC_use_device_ptr
:
6688 case OMPC_use_device_addr
:
6689 case OMPC_is_device_ptr
:
6690 case OMPC_has_device_addr
:
6691 case OMPC_nontemporal
:
6694 case OMPC_inclusive
:
6695 case OMPC_exclusive
:
6696 case OMPC_uses_allocators
:
6701 case OMPC_allocator
:
6704 case OMPC_threadprivate
:
6707 case OMPC_unified_address
:
6708 case OMPC_unified_shared_memory
:
6709 case OMPC_reverse_offload
:
6710 case OMPC_dynamic_allocators
:
6711 case OMPC_atomic_default_mem_order
:
6712 case OMPC_device_type
:
6716 llvm_unreachable("Unexpected clause");
6718 for (Stmt
*CC
: C
->children()) {
6720 DSAChecker
.Visit(CC
);
6723 for (const auto &P
: DSAChecker
.getVarsWithInheritedDSA())
6724 VarsWithInheritedDSA
[P
.getFirst()] = P
.getSecond();
6726 for (const auto &P
: VarsWithInheritedDSA
) {
6727 if (P
.getFirst()->isImplicit() || isa
<OMPCapturedExprDecl
>(P
.getFirst()))
6730 if (DSAStack
->getDefaultDSA() == DSA_none
||
6731 DSAStack
->getDefaultDSA() == DSA_private
||
6732 DSAStack
->getDefaultDSA() == DSA_firstprivate
) {
6733 Diag(P
.second
->getExprLoc(), diag::err_omp_no_dsa_for_variable
)
6734 << P
.first
<< P
.second
->getSourceRange();
6735 Diag(DSAStack
->getDefaultDSALocation(), diag::note_omp_default_dsa_none
);
6736 } else if (getLangOpts().OpenMP
>= 50) {
6737 Diag(P
.second
->getExprLoc(),
6738 diag::err_omp_defaultmap_no_attr_for_variable
)
6739 << P
.first
<< P
.second
->getSourceRange();
6740 Diag(DSAStack
->getDefaultDSALocation(),
6741 diag::note_omp_defaultmap_attr_none
);
6745 if (!AllowedNameModifiers
.empty())
6746 ErrorFound
= checkIfClauses(*this, Kind
, Clauses
, AllowedNameModifiers
) ||
6752 if (!CurContext
->isDependentContext() &&
6753 isOpenMPTargetExecutionDirective(Kind
) &&
6754 !(DSAStack
->hasRequiresDeclWithClause
<OMPUnifiedSharedMemoryClause
>() ||
6755 DSAStack
->hasRequiresDeclWithClause
<OMPUnifiedAddressClause
>() ||
6756 DSAStack
->hasRequiresDeclWithClause
<OMPReverseOffloadClause
>() ||
6757 DSAStack
->hasRequiresDeclWithClause
<OMPDynamicAllocatorsClause
>())) {
6758 // Register target to DSA Stack.
6759 DSAStack
->addTargetDirLocation(StartLoc
);
6765 Sema::DeclGroupPtrTy
Sema::ActOnOpenMPDeclareSimdDirective(
6766 DeclGroupPtrTy DG
, OMPDeclareSimdDeclAttr::BranchStateTy BS
, Expr
*Simdlen
,
6767 ArrayRef
<Expr
*> Uniforms
, ArrayRef
<Expr
*> Aligneds
,
6768 ArrayRef
<Expr
*> Alignments
, ArrayRef
<Expr
*> Linears
,
6769 ArrayRef
<unsigned> LinModifiers
, ArrayRef
<Expr
*> Steps
, SourceRange SR
) {
6770 assert(Aligneds
.size() == Alignments
.size());
6771 assert(Linears
.size() == LinModifiers
.size());
6772 assert(Linears
.size() == Steps
.size());
6773 if (!DG
|| DG
.get().isNull())
6774 return DeclGroupPtrTy();
6776 const int SimdId
= 0;
6777 if (!DG
.get().isSingleDecl()) {
6778 Diag(SR
.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant
)
6782 Decl
*ADecl
= DG
.get().getSingleDecl();
6783 if (auto *FTD
= dyn_cast
<FunctionTemplateDecl
>(ADecl
))
6784 ADecl
= FTD
->getTemplatedDecl();
6786 auto *FD
= dyn_cast
<FunctionDecl
>(ADecl
);
6788 Diag(ADecl
->getLocation(), diag::err_omp_function_expected
) << SimdId
;
6789 return DeclGroupPtrTy();
6792 // OpenMP [2.8.2, declare simd construct, Description]
6793 // The parameter of the simdlen clause must be a constant positive integer
6797 SL
= VerifyPositiveIntegerConstantInClause(Simdlen
, OMPC_simdlen
);
6798 // OpenMP [2.8.2, declare simd construct, Description]
6799 // The special this pointer can be used as if was one of the arguments to the
6800 // function in any of the linear, aligned, or uniform clauses.
6801 // The uniform clause declares one or more arguments to have an invariant
6802 // value for all concurrent invocations of the function in the execution of a
6803 // single SIMD loop.
6804 llvm::DenseMap
<const Decl
*, const Expr
*> UniformedArgs
;
6805 const Expr
*UniformedLinearThis
= nullptr;
6806 for (const Expr
*E
: Uniforms
) {
6807 E
= E
->IgnoreParenImpCasts();
6808 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(E
))
6809 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl()))
6810 if (FD
->getNumParams() > PVD
->getFunctionScopeIndex() &&
6811 FD
->getParamDecl(PVD
->getFunctionScopeIndex())
6812 ->getCanonicalDecl() == PVD
->getCanonicalDecl()) {
6813 UniformedArgs
.try_emplace(PVD
->getCanonicalDecl(), E
);
6816 if (isa
<CXXThisExpr
>(E
)) {
6817 UniformedLinearThis
= E
;
6820 Diag(E
->getExprLoc(), diag::err_omp_param_or_this_in_clause
)
6821 << FD
->getDeclName() << (isa
<CXXMethodDecl
>(ADecl
) ? 1 : 0);
6823 // OpenMP [2.8.2, declare simd construct, Description]
6824 // The aligned clause declares that the object to which each list item points
6825 // is aligned to the number of bytes expressed in the optional parameter of
6826 // the aligned clause.
6827 // The special this pointer can be used as if was one of the arguments to the
6828 // function in any of the linear, aligned, or uniform clauses.
6829 // The type of list items appearing in the aligned clause must be array,
6830 // pointer, reference to array, or reference to pointer.
6831 llvm::DenseMap
<const Decl
*, const Expr
*> AlignedArgs
;
6832 const Expr
*AlignedThis
= nullptr;
6833 for (const Expr
*E
: Aligneds
) {
6834 E
= E
->IgnoreParenImpCasts();
6835 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(E
))
6836 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl())) {
6837 const VarDecl
*CanonPVD
= PVD
->getCanonicalDecl();
6838 if (FD
->getNumParams() > PVD
->getFunctionScopeIndex() &&
6839 FD
->getParamDecl(PVD
->getFunctionScopeIndex())
6840 ->getCanonicalDecl() == CanonPVD
) {
6841 // OpenMP [2.8.1, simd construct, Restrictions]
6842 // A list-item cannot appear in more than one aligned clause.
6843 if (AlignedArgs
.count(CanonPVD
) > 0) {
6844 Diag(E
->getExprLoc(), diag::err_omp_used_in_clause_twice
)
6845 << 1 << getOpenMPClauseName(OMPC_aligned
)
6846 << E
->getSourceRange();
6847 Diag(AlignedArgs
[CanonPVD
]->getExprLoc(),
6848 diag::note_omp_explicit_dsa
)
6849 << getOpenMPClauseName(OMPC_aligned
);
6852 AlignedArgs
[CanonPVD
] = E
;
6853 QualType QTy
= PVD
->getType()
6854 .getNonReferenceType()
6855 .getUnqualifiedType()
6856 .getCanonicalType();
6857 const Type
*Ty
= QTy
.getTypePtrOrNull();
6858 if (!Ty
|| (!Ty
->isArrayType() && !Ty
->isPointerType())) {
6859 Diag(E
->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr
)
6860 << QTy
<< getLangOpts().CPlusPlus
<< E
->getSourceRange();
6861 Diag(PVD
->getLocation(), diag::note_previous_decl
) << PVD
;
6866 if (isa
<CXXThisExpr
>(E
)) {
6868 Diag(E
->getExprLoc(), diag::err_omp_used_in_clause_twice
)
6869 << 2 << getOpenMPClauseName(OMPC_aligned
) << E
->getSourceRange();
6870 Diag(AlignedThis
->getExprLoc(), diag::note_omp_explicit_dsa
)
6871 << getOpenMPClauseName(OMPC_aligned
);
6876 Diag(E
->getExprLoc(), diag::err_omp_param_or_this_in_clause
)
6877 << FD
->getDeclName() << (isa
<CXXMethodDecl
>(ADecl
) ? 1 : 0);
6879 // The optional parameter of the aligned clause, alignment, must be a constant
6880 // positive integer expression. If no optional parameter is specified,
6881 // implementation-defined default alignments for SIMD instructions on the
6882 // target platforms are assumed.
6883 SmallVector
<const Expr
*, 4> NewAligns
;
6884 for (Expr
*E
: Alignments
) {
6887 Align
= VerifyPositiveIntegerConstantInClause(E
, OMPC_aligned
);
6888 NewAligns
.push_back(Align
.get());
6890 // OpenMP [2.8.2, declare simd construct, Description]
6891 // The linear clause declares one or more list items to be private to a SIMD
6892 // lane and to have a linear relationship with respect to the iteration space
6894 // The special this pointer can be used as if was one of the arguments to the
6895 // function in any of the linear, aligned, or uniform clauses.
6896 // When a linear-step expression is specified in a linear clause it must be
6897 // either a constant integer expression or an integer-typed parameter that is
6898 // specified in a uniform clause on the directive.
6899 llvm::DenseMap
<const Decl
*, const Expr
*> LinearArgs
;
6900 const bool IsUniformedThis
= UniformedLinearThis
!= nullptr;
6901 auto MI
= LinModifiers
.begin();
6902 for (const Expr
*E
: Linears
) {
6903 auto LinKind
= static_cast<OpenMPLinearClauseKind
>(*MI
);
6905 E
= E
->IgnoreParenImpCasts();
6906 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(E
))
6907 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl())) {
6908 const VarDecl
*CanonPVD
= PVD
->getCanonicalDecl();
6909 if (FD
->getNumParams() > PVD
->getFunctionScopeIndex() &&
6910 FD
->getParamDecl(PVD
->getFunctionScopeIndex())
6911 ->getCanonicalDecl() == CanonPVD
) {
6912 // OpenMP [2.15.3.7, linear Clause, Restrictions]
6913 // A list-item cannot appear in more than one linear clause.
6914 if (LinearArgs
.count(CanonPVD
) > 0) {
6915 Diag(E
->getExprLoc(), diag::err_omp_wrong_dsa
)
6916 << getOpenMPClauseName(OMPC_linear
)
6917 << getOpenMPClauseName(OMPC_linear
) << E
->getSourceRange();
6918 Diag(LinearArgs
[CanonPVD
]->getExprLoc(),
6919 diag::note_omp_explicit_dsa
)
6920 << getOpenMPClauseName(OMPC_linear
);
6923 // Each argument can appear in at most one uniform or linear clause.
6924 if (UniformedArgs
.count(CanonPVD
) > 0) {
6925 Diag(E
->getExprLoc(), diag::err_omp_wrong_dsa
)
6926 << getOpenMPClauseName(OMPC_linear
)
6927 << getOpenMPClauseName(OMPC_uniform
) << E
->getSourceRange();
6928 Diag(UniformedArgs
[CanonPVD
]->getExprLoc(),
6929 diag::note_omp_explicit_dsa
)
6930 << getOpenMPClauseName(OMPC_uniform
);
6933 LinearArgs
[CanonPVD
] = E
;
6934 if (E
->isValueDependent() || E
->isTypeDependent() ||
6935 E
->isInstantiationDependent() ||
6936 E
->containsUnexpandedParameterPack())
6938 (void)CheckOpenMPLinearDecl(CanonPVD
, E
->getExprLoc(), LinKind
,
6939 PVD
->getOriginalType(),
6940 /*IsDeclareSimd=*/true);
6944 if (isa
<CXXThisExpr
>(E
)) {
6945 if (UniformedLinearThis
) {
6946 Diag(E
->getExprLoc(), diag::err_omp_wrong_dsa
)
6947 << getOpenMPClauseName(OMPC_linear
)
6948 << getOpenMPClauseName(IsUniformedThis
? OMPC_uniform
: OMPC_linear
)
6949 << E
->getSourceRange();
6950 Diag(UniformedLinearThis
->getExprLoc(), diag::note_omp_explicit_dsa
)
6951 << getOpenMPClauseName(IsUniformedThis
? OMPC_uniform
6955 UniformedLinearThis
= E
;
6956 if (E
->isValueDependent() || E
->isTypeDependent() ||
6957 E
->isInstantiationDependent() || E
->containsUnexpandedParameterPack())
6959 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E
->getExprLoc(), LinKind
,
6960 E
->getType(), /*IsDeclareSimd=*/true);
6963 Diag(E
->getExprLoc(), diag::err_omp_param_or_this_in_clause
)
6964 << FD
->getDeclName() << (isa
<CXXMethodDecl
>(ADecl
) ? 1 : 0);
6966 Expr
*Step
= nullptr;
6967 Expr
*NewStep
= nullptr;
6968 SmallVector
<Expr
*, 4> NewSteps
;
6969 for (Expr
*E
: Steps
) {
6970 // Skip the same step expression, it was checked already.
6971 if (Step
== E
|| !E
) {
6972 NewSteps
.push_back(E
? NewStep
: nullptr);
6976 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(Step
))
6977 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl())) {
6978 const VarDecl
*CanonPVD
= PVD
->getCanonicalDecl();
6979 if (UniformedArgs
.count(CanonPVD
) == 0) {
6980 Diag(Step
->getExprLoc(), diag::err_omp_expected_uniform_param
)
6981 << Step
->getSourceRange();
6982 } else if (E
->isValueDependent() || E
->isTypeDependent() ||
6983 E
->isInstantiationDependent() ||
6984 E
->containsUnexpandedParameterPack() ||
6985 CanonPVD
->getType()->hasIntegerRepresentation()) {
6986 NewSteps
.push_back(Step
);
6988 Diag(Step
->getExprLoc(), diag::err_omp_expected_int_param
)
6989 << Step
->getSourceRange();
6994 if (Step
&& !Step
->isValueDependent() && !Step
->isTypeDependent() &&
6995 !Step
->isInstantiationDependent() &&
6996 !Step
->containsUnexpandedParameterPack()) {
6997 NewStep
= PerformOpenMPImplicitIntegerConversion(Step
->getExprLoc(), Step
)
7001 VerifyIntegerConstantExpression(NewStep
, /*FIXME*/ AllowFold
).get();
7003 NewSteps
.push_back(NewStep
);
7005 auto *NewAttr
= OMPDeclareSimdDeclAttr::CreateImplicit(
7006 Context
, BS
, SL
.get(), const_cast<Expr
**>(Uniforms
.data()),
7007 Uniforms
.size(), const_cast<Expr
**>(Aligneds
.data()), Aligneds
.size(),
7008 const_cast<Expr
**>(NewAligns
.data()), NewAligns
.size(),
7009 const_cast<Expr
**>(Linears
.data()), Linears
.size(),
7010 const_cast<unsigned *>(LinModifiers
.data()), LinModifiers
.size(),
7011 NewSteps
.data(), NewSteps
.size(), SR
);
7012 ADecl
->addAttr(NewAttr
);
7016 static void setPrototype(Sema
&S
, FunctionDecl
*FD
, FunctionDecl
*FDWithProto
,
7018 assert(NewType
->isFunctionProtoType() &&
7019 "Expected function type with prototype.");
7020 assert(FD
->getType()->isFunctionNoProtoType() &&
7021 "Expected function with type with no prototype.");
7022 assert(FDWithProto
->getType()->isFunctionProtoType() &&
7023 "Expected function with prototype.");
7024 // Synthesize parameters with the same types.
7025 FD
->setType(NewType
);
7026 SmallVector
<ParmVarDecl
*, 16> Params
;
7027 for (const ParmVarDecl
*P
: FDWithProto
->parameters()) {
7028 auto *Param
= ParmVarDecl::Create(S
.getASTContext(), FD
, SourceLocation(),
7029 SourceLocation(), nullptr, P
->getType(),
7030 /*TInfo=*/nullptr, SC_None
, nullptr);
7031 Param
->setScopeInfo(0, Params
.size());
7032 Param
->setImplicit();
7033 Params
.push_back(Param
);
7036 FD
->setParams(Params
);
7039 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl
*D
) {
7040 if (D
->isInvalidDecl())
7042 FunctionDecl
*FD
= nullptr;
7043 if (auto *UTemplDecl
= dyn_cast
<FunctionTemplateDecl
>(D
))
7044 FD
= UTemplDecl
->getTemplatedDecl();
7046 FD
= cast
<FunctionDecl
>(D
);
7047 assert(FD
&& "Expected a function declaration!");
7049 // If we are instantiating templates we do *not* apply scoped assumptions but
7050 // only global ones. We apply scoped assumption to the template definition
7052 if (!inTemplateInstantiation()) {
7053 for (AssumptionAttr
*AA
: OMPAssumeScoped
)
7056 for (AssumptionAttr
*AA
: OMPAssumeGlobal
)
7060 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo
&TI
)
7061 : TI(&TI
), NameSuffix(TI
.getMangledName()) {}
7063 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7064 Scope
*S
, Declarator
&D
, MultiTemplateParamsArg TemplateParamLists
,
7065 SmallVectorImpl
<FunctionDecl
*> &Bases
) {
7066 if (!D
.getIdentifier())
7069 OMPDeclareVariantScope
&DVScope
= OMPDeclareVariantScopes
.back();
7071 // Template specialization is an extension, check if we do it.
7072 bool IsTemplated
= !TemplateParamLists
.empty();
7074 !DVScope
.TI
->isExtensionActive(
7075 llvm::omp::TraitProperty::implementation_extension_allow_templates
))
7078 IdentifierInfo
*BaseII
= D
.getIdentifier();
7079 LookupResult
Lookup(*this, DeclarationName(BaseII
), D
.getIdentifierLoc(),
7080 LookupOrdinaryName
);
7081 LookupParsedName(Lookup
, S
, &D
.getCXXScopeSpec());
7083 TypeSourceInfo
*TInfo
= GetTypeForDeclarator(D
, S
);
7084 QualType FType
= TInfo
->getType();
7087 D
.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr
;
7089 D
.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval
;
7091 for (auto *Candidate
: Lookup
) {
7092 auto *CandidateDecl
= Candidate
->getUnderlyingDecl();
7093 FunctionDecl
*UDecl
= nullptr;
7094 if (IsTemplated
&& isa
<FunctionTemplateDecl
>(CandidateDecl
)) {
7095 auto *FTD
= cast
<FunctionTemplateDecl
>(CandidateDecl
);
7096 if (FTD
->getTemplateParameters()->size() == TemplateParamLists
.size())
7097 UDecl
= FTD
->getTemplatedDecl();
7098 } else if (!IsTemplated
)
7099 UDecl
= dyn_cast
<FunctionDecl
>(CandidateDecl
);
7103 // Don't specialize constexpr/consteval functions with
7104 // non-constexpr/consteval functions.
7105 if (UDecl
->isConstexpr() && !IsConstexpr
)
7107 if (UDecl
->isConsteval() && !IsConsteval
)
7110 QualType UDeclTy
= UDecl
->getType();
7111 if (!UDeclTy
->isDependentType()) {
7112 QualType NewType
= Context
.mergeFunctionTypes(
7113 FType
, UDeclTy
, /* OfBlockPointer */ false,
7114 /* Unqualified */ false, /* AllowCXX */ true);
7115 if (NewType
.isNull())
7120 Bases
.push_back(UDecl
);
7123 bool UseImplicitBase
= !DVScope
.TI
->isExtensionActive(
7124 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base
);
7125 // If no base was found we create a declaration that we use as base.
7126 if (Bases
.empty() && UseImplicitBase
) {
7127 D
.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration
);
7128 Decl
*BaseD
= HandleDeclarator(S
, D
, TemplateParamLists
);
7129 BaseD
->setImplicit(true);
7130 if (auto *BaseTemplD
= dyn_cast
<FunctionTemplateDecl
>(BaseD
))
7131 Bases
.push_back(BaseTemplD
->getTemplatedDecl());
7133 Bases
.push_back(cast
<FunctionDecl
>(BaseD
));
7136 std::string MangledName
;
7137 MangledName
+= D
.getIdentifier()->getName();
7138 MangledName
+= getOpenMPVariantManglingSeparatorStr();
7139 MangledName
+= DVScope
.NameSuffix
;
7140 IdentifierInfo
&VariantII
= Context
.Idents
.get(MangledName
);
7142 VariantII
.setMangledOpenMPVariantName(true);
7143 D
.SetIdentifier(&VariantII
, D
.getBeginLoc());
7146 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7147 Decl
*D
, SmallVectorImpl
<FunctionDecl
*> &Bases
) {
7148 // Do not mark function as is used to prevent its emission if this is the
7149 // only place where it is used.
7150 EnterExpressionEvaluationContext
Unevaluated(
7151 *this, Sema::ExpressionEvaluationContext::Unevaluated
);
7153 FunctionDecl
*FD
= nullptr;
7154 if (auto *UTemplDecl
= dyn_cast
<FunctionTemplateDecl
>(D
))
7155 FD
= UTemplDecl
->getTemplatedDecl();
7157 FD
= cast
<FunctionDecl
>(D
);
7158 auto *VariantFuncRef
= DeclRefExpr::Create(
7159 Context
, NestedNameSpecifierLoc(), SourceLocation(), FD
,
7160 /* RefersToEnclosingVariableOrCapture */ false,
7161 /* NameLoc */ FD
->getLocation(), FD
->getType(),
7162 ExprValueKind::VK_PRValue
);
7164 OMPDeclareVariantScope
&DVScope
= OMPDeclareVariantScopes
.back();
7165 auto *OMPDeclareVariantA
= OMPDeclareVariantAttr::CreateImplicit(
7166 Context
, VariantFuncRef
, DVScope
.TI
,
7167 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7168 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7169 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7170 for (FunctionDecl
*BaseFD
: Bases
)
7171 BaseFD
->addAttr(OMPDeclareVariantA
);
7174 ExprResult
Sema::ActOnOpenMPCall(ExprResult Call
, Scope
*Scope
,
7175 SourceLocation LParenLoc
,
7176 MultiExprArg ArgExprs
,
7177 SourceLocation RParenLoc
, Expr
*ExecConfig
) {
7178 // The common case is a regular call we do not want to specialize at all. Try
7179 // to make that case fast by bailing early.
7180 CallExpr
*CE
= dyn_cast
<CallExpr
>(Call
.get());
7184 FunctionDecl
*CalleeFnDecl
= CE
->getDirectCallee();
7188 if (!CalleeFnDecl
->hasAttr
<OMPDeclareVariantAttr
>())
7191 ASTContext
&Context
= getASTContext();
7192 std::function
<void(StringRef
)> DiagUnknownTrait
= [this,
7193 CE
](StringRef ISATrait
) {
7194 // TODO Track the selector locations in a way that is accessible here to
7195 // improve the diagnostic location.
7196 Diag(CE
->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait
)
7199 TargetOMPContext
OMPCtx(Context
, std::move(DiagUnknownTrait
),
7200 getCurFunctionDecl(), DSAStack
->getConstructTraits());
7202 QualType CalleeFnType
= CalleeFnDecl
->getType();
7204 SmallVector
<Expr
*, 4> Exprs
;
7205 SmallVector
<VariantMatchInfo
, 4> VMIs
;
7206 while (CalleeFnDecl
) {
7207 for (OMPDeclareVariantAttr
*A
:
7208 CalleeFnDecl
->specific_attrs
<OMPDeclareVariantAttr
>()) {
7209 Expr
*VariantRef
= A
->getVariantFuncRef();
7211 VariantMatchInfo VMI
;
7212 OMPTraitInfo
&TI
= A
->getTraitInfo();
7213 TI
.getAsVariantMatchInfo(Context
, VMI
);
7214 if (!isVariantApplicableInContext(VMI
, OMPCtx
,
7215 /* DeviceSetOnly */ false))
7218 VMIs
.push_back(VMI
);
7219 Exprs
.push_back(VariantRef
);
7222 CalleeFnDecl
= CalleeFnDecl
->getPreviousDecl();
7227 int BestIdx
= getBestVariantMatchForContext(VMIs
, OMPCtx
);
7230 Expr
*BestExpr
= cast
<DeclRefExpr
>(Exprs
[BestIdx
]);
7231 Decl
*BestDecl
= cast
<DeclRefExpr
>(BestExpr
)->getDecl();
7234 // Try to build a (member) call expression for the current best applicable
7235 // variant expression. We allow this to fail in which case we continue
7236 // with the next best variant expression. The fail case is part of the
7237 // implementation defined behavior in the OpenMP standard when it talks
7238 // about what differences in the function prototypes: "Any differences
7239 // that the specific OpenMP context requires in the prototype of the
7240 // variant from the base function prototype are implementation defined."
7241 // This wording is there to allow the specialized variant to have a
7242 // different type than the base function. This is intended and OK but if
7243 // we cannot create a call the difference is not in the "implementation
7244 // defined range" we allow.
7245 Sema::TentativeAnalysisScope
Trap(*this);
7247 if (auto *SpecializedMethod
= dyn_cast
<CXXMethodDecl
>(BestDecl
)) {
7248 auto *MemberCall
= dyn_cast
<CXXMemberCallExpr
>(CE
);
7249 BestExpr
= MemberExpr::CreateImplicit(
7250 Context
, MemberCall
->getImplicitObjectArgument(),
7251 /* IsArrow */ false, SpecializedMethod
, Context
.BoundMemberTy
,
7252 MemberCall
->getValueKind(), MemberCall
->getObjectKind());
7254 NewCall
= BuildCallExpr(Scope
, BestExpr
, LParenLoc
, ArgExprs
, RParenLoc
,
7256 if (NewCall
.isUsable()) {
7257 if (CallExpr
*NCE
= dyn_cast
<CallExpr
>(NewCall
.get())) {
7258 FunctionDecl
*NewCalleeFnDecl
= NCE
->getDirectCallee();
7259 QualType NewType
= Context
.mergeFunctionTypes(
7260 CalleeFnType
, NewCalleeFnDecl
->getType(),
7261 /* OfBlockPointer */ false,
7262 /* Unqualified */ false, /* AllowCXX */ true);
7263 if (!NewType
.isNull())
7265 // Don't use the call if the function type was not compatible.
7271 VMIs
.erase(VMIs
.begin() + BestIdx
);
7272 Exprs
.erase(Exprs
.begin() + BestIdx
);
7273 } while (!VMIs
.empty());
7275 if (!NewCall
.isUsable())
7277 return PseudoObjectExpr::Create(Context
, CE
, {NewCall
.get()}, 0);
7280 Optional
<std::pair
<FunctionDecl
*, Expr
*>>
7281 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG
,
7282 Expr
*VariantRef
, OMPTraitInfo
&TI
,
7283 unsigned NumAppendArgs
,
7285 if (!DG
|| DG
.get().isNull())
7288 const int VariantId
= 1;
7289 // Must be applied only to single decl.
7290 if (!DG
.get().isSingleDecl()) {
7291 Diag(SR
.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant
)
7295 Decl
*ADecl
= DG
.get().getSingleDecl();
7296 if (auto *FTD
= dyn_cast
<FunctionTemplateDecl
>(ADecl
))
7297 ADecl
= FTD
->getTemplatedDecl();
7299 // Decl must be a function.
7300 auto *FD
= dyn_cast
<FunctionDecl
>(ADecl
);
7302 Diag(ADecl
->getLocation(), diag::err_omp_function_expected
)
7307 auto &&HasMultiVersionAttributes
= [](const FunctionDecl
*FD
) {
7308 // The 'target' attribute needs to be separately checked because it does
7309 // not always signify a multiversion function declaration.
7310 return FD
->isMultiVersion() || FD
->hasAttr
<TargetAttr
>();
7312 // OpenMP is not compatible with multiversion function attributes.
7313 if (HasMultiVersionAttributes(FD
)) {
7314 Diag(FD
->getLocation(), diag::err_omp_declare_variant_incompat_attributes
)
7319 // Allow #pragma omp declare variant only if the function is not used.
7320 if (FD
->isUsed(false))
7321 Diag(SR
.getBegin(), diag::warn_omp_declare_variant_after_used
)
7322 << FD
->getLocation();
7324 // Check if the function was emitted already.
7325 const FunctionDecl
*Definition
;
7326 if (!FD
->isThisDeclarationADefinition() && FD
->isDefined(Definition
) &&
7327 (LangOpts
.EmitAllDecls
|| Context
.DeclMustBeEmitted(Definition
)))
7328 Diag(SR
.getBegin(), diag::warn_omp_declare_variant_after_emitted
)
7329 << FD
->getLocation();
7331 // The VariantRef must point to function.
7333 Diag(SR
.getBegin(), diag::err_omp_function_expected
) << VariantId
;
7337 auto ShouldDelayChecks
= [](Expr
*&E
, bool) {
7338 return E
&& (E
->isTypeDependent() || E
->isValueDependent() ||
7339 E
->containsUnexpandedParameterPack() ||
7340 E
->isInstantiationDependent());
7342 // Do not check templates, wait until instantiation.
7343 if (FD
->isDependentContext() || ShouldDelayChecks(VariantRef
, false) ||
7344 TI
.anyScoreOrCondition(ShouldDelayChecks
))
7345 return std::make_pair(FD
, VariantRef
);
7347 // Deal with non-constant score and user condition expressions.
7348 auto HandleNonConstantScoresAndConditions
= [this](Expr
*&E
,
7349 bool IsScore
) -> bool {
7350 if (!E
|| E
->isIntegerConstantExpr(Context
))
7354 // We warn on non-constant scores and pretend they were not present.
7355 Diag(E
->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant
)
7359 // We could replace a non-constant user condition with "false" but we
7360 // will soon need to handle these anyway for the dynamic version of
7361 // OpenMP context selectors.
7362 Diag(E
->getExprLoc(),
7363 diag::err_omp_declare_variant_user_condition_not_constant
)
7368 if (TI
.anyScoreOrCondition(HandleNonConstantScoresAndConditions
))
7371 QualType AdjustedFnType
= FD
->getType();
7372 if (NumAppendArgs
) {
7373 const auto *PTy
= AdjustedFnType
->getAsAdjusted
<FunctionProtoType
>();
7375 Diag(FD
->getLocation(), diag::err_omp_declare_variant_prototype_required
)
7379 // Adjust the function type to account for an extra omp_interop_t for each
7380 // specified in the append_args clause.
7381 const TypeDecl
*TD
= nullptr;
7382 LookupResult
Result(*this, &Context
.Idents
.get("omp_interop_t"),
7383 SR
.getBegin(), Sema::LookupOrdinaryName
);
7384 if (LookupName(Result
, getCurScope())) {
7385 NamedDecl
*ND
= Result
.getFoundDecl();
7386 TD
= dyn_cast_or_null
<TypeDecl
>(ND
);
7389 Diag(SR
.getBegin(), diag::err_omp_interop_type_not_found
) << SR
;
7392 QualType InteropType
= Context
.getTypeDeclType(TD
);
7393 if (PTy
->isVariadic()) {
7394 Diag(FD
->getLocation(), diag::err_omp_append_args_with_varargs
) << SR
;
7397 llvm::SmallVector
<QualType
, 8> Params
;
7398 Params
.append(PTy
->param_type_begin(), PTy
->param_type_end());
7399 Params
.insert(Params
.end(), NumAppendArgs
, InteropType
);
7400 AdjustedFnType
= Context
.getFunctionType(PTy
->getReturnType(), Params
,
7401 PTy
->getExtProtoInfo());
7404 // Convert VariantRef expression to the type of the original function to
7405 // resolve possible conflicts.
7406 ExprResult VariantRefCast
= VariantRef
;
7407 if (LangOpts
.CPlusPlus
) {
7409 auto *Method
= dyn_cast
<CXXMethodDecl
>(FD
);
7410 if (Method
&& !Method
->isStatic()) {
7411 const Type
*ClassType
=
7412 Context
.getTypeDeclType(Method
->getParent()).getTypePtr();
7413 FnPtrType
= Context
.getMemberPointerType(AdjustedFnType
, ClassType
);
7416 // Build adrr_of unary op to correctly handle type checks for member
7418 Sema::TentativeAnalysisScope
Trap(*this);
7419 ER
= CreateBuiltinUnaryOp(VariantRef
->getBeginLoc(), UO_AddrOf
,
7422 if (!ER
.isUsable()) {
7423 Diag(VariantRef
->getExprLoc(), diag::err_omp_function_expected
)
7424 << VariantId
<< VariantRef
->getSourceRange();
7427 VariantRef
= ER
.get();
7429 FnPtrType
= Context
.getPointerType(AdjustedFnType
);
7431 QualType VarianPtrType
= Context
.getPointerType(VariantRef
->getType());
7432 if (VarianPtrType
.getUnqualifiedType() != FnPtrType
.getUnqualifiedType()) {
7433 ImplicitConversionSequence ICS
= TryImplicitConversion(
7434 VariantRef
, FnPtrType
.getUnqualifiedType(),
7435 /*SuppressUserConversions=*/false, AllowedExplicit::None
,
7436 /*InOverloadResolution=*/false,
7438 /*AllowObjCWritebackConversion=*/false);
7439 if (ICS
.isFailure()) {
7440 Diag(VariantRef
->getExprLoc(),
7441 diag::err_omp_declare_variant_incompat_types
)
7442 << VariantRef
->getType()
7443 << ((Method
&& !Method
->isStatic()) ? FnPtrType
: FD
->getType())
7444 << (NumAppendArgs
? 1 : 0) << VariantRef
->getSourceRange();
7447 VariantRefCast
= PerformImplicitConversion(
7448 VariantRef
, FnPtrType
.getUnqualifiedType(), AA_Converting
);
7449 if (!VariantRefCast
.isUsable())
7452 // Drop previously built artificial addr_of unary op for member functions.
7453 if (Method
&& !Method
->isStatic()) {
7454 Expr
*PossibleAddrOfVariantRef
= VariantRefCast
.get();
7455 if (auto *UO
= dyn_cast
<UnaryOperator
>(
7456 PossibleAddrOfVariantRef
->IgnoreImplicit()))
7457 VariantRefCast
= UO
->getSubExpr();
7461 ExprResult ER
= CheckPlaceholderExpr(VariantRefCast
.get());
7462 if (!ER
.isUsable() ||
7463 !ER
.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7464 Diag(VariantRef
->getExprLoc(), diag::err_omp_function_expected
)
7465 << VariantId
<< VariantRef
->getSourceRange();
7469 // The VariantRef must point to function.
7470 auto *DRE
= dyn_cast
<DeclRefExpr
>(ER
.get()->IgnoreParenImpCasts());
7472 Diag(VariantRef
->getExprLoc(), diag::err_omp_function_expected
)
7473 << VariantId
<< VariantRef
->getSourceRange();
7476 auto *NewFD
= dyn_cast_or_null
<FunctionDecl
>(DRE
->getDecl());
7478 Diag(VariantRef
->getExprLoc(), diag::err_omp_function_expected
)
7479 << VariantId
<< VariantRef
->getSourceRange();
7483 if (FD
->getCanonicalDecl() == NewFD
->getCanonicalDecl()) {
7484 Diag(VariantRef
->getExprLoc(),
7485 diag::err_omp_declare_variant_same_base_function
)
7486 << VariantRef
->getSourceRange();
7490 // Check if function types are compatible in C.
7491 if (!LangOpts
.CPlusPlus
) {
7493 Context
.mergeFunctionTypes(AdjustedFnType
, NewFD
->getType());
7494 if (NewType
.isNull()) {
7495 Diag(VariantRef
->getExprLoc(),
7496 diag::err_omp_declare_variant_incompat_types
)
7497 << NewFD
->getType() << FD
->getType() << (NumAppendArgs
? 1 : 0)
7498 << VariantRef
->getSourceRange();
7501 if (NewType
->isFunctionProtoType()) {
7502 if (FD
->getType()->isFunctionNoProtoType())
7503 setPrototype(*this, FD
, NewFD
, NewType
);
7504 else if (NewFD
->getType()->isFunctionNoProtoType())
7505 setPrototype(*this, NewFD
, FD
, NewType
);
7509 // Check if variant function is not marked with declare variant directive.
7510 if (NewFD
->hasAttrs() && NewFD
->hasAttr
<OMPDeclareVariantAttr
>()) {
7511 Diag(VariantRef
->getExprLoc(),
7512 diag::warn_omp_declare_variant_marked_as_declare_variant
)
7513 << VariantRef
->getSourceRange();
7515 NewFD
->specific_attr_begin
<OMPDeclareVariantAttr
>()->getRange();
7516 Diag(SR
.getBegin(), diag::note_omp_marked_declare_variant_here
) << SR
;
7520 enum DoesntSupport
{
7529 if (const auto *CXXFD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
7530 if (CXXFD
->isVirtual()) {
7531 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7536 if (isa
<CXXConstructorDecl
>(FD
)) {
7537 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7542 if (isa
<CXXDestructorDecl
>(FD
)) {
7543 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7549 if (FD
->isDeleted()) {
7550 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7555 if (FD
->isDefaulted()) {
7556 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7561 if (FD
->isConstexpr()) {
7562 Diag(FD
->getLocation(), diag::err_omp_declare_variant_doesnt_support
)
7563 << (NewFD
->isConsteval() ? ConstevalFuncs
: ConstexprFuncs
);
7567 // Check general compatibility.
7568 if (areMultiversionVariantFunctionsCompatible(
7569 FD
, NewFD
, PartialDiagnostic::NullDiagnostic(),
7570 PartialDiagnosticAt(SourceLocation(),
7571 PartialDiagnostic::NullDiagnostic()),
7572 PartialDiagnosticAt(
7573 VariantRef
->getExprLoc(),
7574 PDiag(diag::err_omp_declare_variant_doesnt_support
)),
7575 PartialDiagnosticAt(VariantRef
->getExprLoc(),
7576 PDiag(diag::err_omp_declare_variant_diff
)
7577 << FD
->getLocation()),
7578 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7579 /*CLinkageMayDiffer=*/true))
7581 return std::make_pair(FD
, cast
<Expr
>(DRE
));
7584 void Sema::ActOnOpenMPDeclareVariantDirective(
7585 FunctionDecl
*FD
, Expr
*VariantRef
, OMPTraitInfo
&TI
,
7586 ArrayRef
<Expr
*> AdjustArgsNothing
,
7587 ArrayRef
<Expr
*> AdjustArgsNeedDevicePtr
,
7588 ArrayRef
<OMPInteropInfo
> AppendArgs
, SourceLocation AdjustArgsLoc
,
7589 SourceLocation AppendArgsLoc
, SourceRange SR
) {
7591 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7592 // An adjust_args clause or append_args clause can only be specified if the
7593 // dispatch selector of the construct selector set appears in the match
7596 SmallVector
<Expr
*, 8> AllAdjustArgs
;
7597 llvm::append_range(AllAdjustArgs
, AdjustArgsNothing
);
7598 llvm::append_range(AllAdjustArgs
, AdjustArgsNeedDevicePtr
);
7600 if (!AllAdjustArgs
.empty() || !AppendArgs
.empty()) {
7601 VariantMatchInfo VMI
;
7602 TI
.getAsVariantMatchInfo(Context
, VMI
);
7603 if (!llvm::is_contained(
7604 VMI
.ConstructTraits
,
7605 llvm::omp::TraitProperty::construct_dispatch_dispatch
)) {
7606 if (!AllAdjustArgs
.empty())
7607 Diag(AdjustArgsLoc
, diag::err_omp_clause_requires_dispatch_construct
)
7608 << getOpenMPClauseName(OMPC_adjust_args
);
7609 if (!AppendArgs
.empty())
7610 Diag(AppendArgsLoc
, diag::err_omp_clause_requires_dispatch_construct
)
7611 << getOpenMPClauseName(OMPC_append_args
);
7616 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7617 // Each argument can only appear in a single adjust_args clause for each
7618 // declare variant directive.
7619 llvm::SmallPtrSet
<const VarDecl
*, 4> AdjustVars
;
7621 for (Expr
*E
: AllAdjustArgs
) {
7622 E
= E
->IgnoreParenImpCasts();
7623 if (const auto *DRE
= dyn_cast
<DeclRefExpr
>(E
)) {
7624 if (const auto *PVD
= dyn_cast
<ParmVarDecl
>(DRE
->getDecl())) {
7625 const VarDecl
*CanonPVD
= PVD
->getCanonicalDecl();
7626 if (FD
->getNumParams() > PVD
->getFunctionScopeIndex() &&
7627 FD
->getParamDecl(PVD
->getFunctionScopeIndex())
7628 ->getCanonicalDecl() == CanonPVD
) {
7629 // It's a parameter of the function, check duplicates.
7630 if (!AdjustVars
.insert(CanonPVD
).second
) {
7631 Diag(DRE
->getLocation(), diag::err_omp_adjust_arg_multiple_clauses
)
7639 // Anything that is not a function parameter is an error.
7640 Diag(E
->getExprLoc(), diag::err_omp_param_or_this_in_clause
) << FD
<< 0;
7644 auto *NewAttr
= OMPDeclareVariantAttr::CreateImplicit(
7645 Context
, VariantRef
, &TI
, const_cast<Expr
**>(AdjustArgsNothing
.data()),
7646 AdjustArgsNothing
.size(),
7647 const_cast<Expr
**>(AdjustArgsNeedDevicePtr
.data()),
7648 AdjustArgsNeedDevicePtr
.size(),
7649 const_cast<OMPInteropInfo
*>(AppendArgs
.data()), AppendArgs
.size(), SR
);
7650 FD
->addAttr(NewAttr
);
7653 StmtResult
Sema::ActOnOpenMPParallelDirective(ArrayRef
<OMPClause
*> Clauses
,
7655 SourceLocation StartLoc
,
7656 SourceLocation EndLoc
) {
7660 auto *CS
= cast
<CapturedStmt
>(AStmt
);
7661 // 1.2.2 OpenMP Language Terminology
7662 // Structured block - An executable statement with a single entry at the
7663 // top and a single exit at the bottom.
7664 // The point of exit cannot be a branch out of the structured block.
7665 // longjmp() and throw() must not violate the entry/exit criteria.
7666 CS
->getCapturedDecl()->setNothrow();
7668 setFunctionHasBranchProtectedScope();
7670 return OMPParallelDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
7671 DSAStack
->getTaskgroupReductionRef(),
7672 DSAStack
->isCancelRegion());
7676 /// Iteration space of a single for loop.
7677 struct LoopIterationSpace final
{
7678 /// True if the condition operator is the strict compare operator (<, > or
7680 bool IsStrictCompare
= false;
7681 /// Condition of the loop.
7682 Expr
*PreCond
= nullptr;
7683 /// This expression calculates the number of iterations in the loop.
7684 /// It is always possible to calculate it before starting the loop.
7685 Expr
*NumIterations
= nullptr;
7686 /// The loop counter variable.
7687 Expr
*CounterVar
= nullptr;
7688 /// Private loop counter variable.
7689 Expr
*PrivateCounterVar
= nullptr;
7690 /// This is initializer for the initial value of #CounterVar.
7691 Expr
*CounterInit
= nullptr;
7692 /// This is step for the #CounterVar used to generate its update:
7693 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7694 Expr
*CounterStep
= nullptr;
7695 /// Should step be subtracted?
7696 bool Subtract
= false;
7697 /// Source range of the loop init.
7698 SourceRange InitSrcRange
;
7699 /// Source range of the loop condition.
7700 SourceRange CondSrcRange
;
7701 /// Source range of the loop increment.
7702 SourceRange IncSrcRange
;
7703 /// Minimum value that can have the loop control variable. Used to support
7704 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7705 /// since only such variables can be used in non-loop invariant expressions.
7706 Expr
*MinValue
= nullptr;
7707 /// Maximum value that can have the loop control variable. Used to support
7708 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7709 /// since only such variables can be used in non-loop invariant expressions.
7710 Expr
*MaxValue
= nullptr;
7711 /// true, if the lower bound depends on the outer loop control var.
7712 bool IsNonRectangularLB
= false;
7713 /// true, if the upper bound depends on the outer loop control var.
7714 bool IsNonRectangularUB
= false;
7715 /// Index of the loop this loop depends on and forms non-rectangular loop
7717 unsigned LoopDependentIdx
= 0;
7718 /// Final condition for the non-rectangular loop nest support. It is used to
7719 /// check that the number of iterations for this particular counter must be
7721 Expr
*FinalCondition
= nullptr;
7724 /// Helper class for checking canonical form of the OpenMP loops and
7725 /// extracting iteration space of each loop in the loop nest, that will be used
7726 /// for IR generation.
7727 class OpenMPIterationSpaceChecker
{
7728 /// Reference to Sema.
7730 /// Does the loop associated directive support non-rectangular loops?
7731 bool SupportsNonRectangular
;
7732 /// Data-sharing stack.
7734 /// A location for diagnostics (when there is no some better location).
7735 SourceLocation DefaultLoc
;
7736 /// A location for diagnostics (when increment is not compatible).
7737 SourceLocation ConditionLoc
;
7738 /// A source location for referring to loop init later.
7739 SourceRange InitSrcRange
;
7740 /// A source location for referring to condition later.
7741 SourceRange ConditionSrcRange
;
7742 /// A source location for referring to increment later.
7743 SourceRange IncrementSrcRange
;
7745 ValueDecl
*LCDecl
= nullptr;
7746 /// Reference to loop variable.
7747 Expr
*LCRef
= nullptr;
7748 /// Lower bound (initializer for the var).
7752 /// Loop step (increment).
7753 Expr
*Step
= nullptr;
7754 /// This flag is true when condition is one of:
7759 /// This will have no value when the condition is !=
7760 llvm::Optional
<bool> TestIsLessOp
;
7761 /// This flag is true when condition is strict ( < or > ).
7762 bool TestIsStrictOp
= false;
7763 /// This flag is true when step is subtracted on each iteration.
7764 bool SubtractStep
= false;
7765 /// The outer loop counter this loop depends on (if any).
7766 const ValueDecl
*DepDecl
= nullptr;
7767 /// Contains number of loop (starts from 1) on which loop counter init
7768 /// expression of this loop depends on.
7769 Optional
<unsigned> InitDependOnLC
;
7770 /// Contains number of loop (starts from 1) on which loop counter condition
7771 /// expression of this loop depends on.
7772 Optional
<unsigned> CondDependOnLC
;
7773 /// Checks if the provide statement depends on the loop counter.
7774 Optional
<unsigned> doesDependOnLoopCounter(const Stmt
*S
, bool IsInitializer
);
7775 /// Original condition required for checking of the exit condition for
7776 /// non-rectangular loop.
7777 Expr
*Condition
= nullptr;
7780 OpenMPIterationSpaceChecker(Sema
&SemaRef
, bool SupportsNonRectangular
,
7781 DSAStackTy
&Stack
, SourceLocation DefaultLoc
)
7782 : SemaRef(SemaRef
), SupportsNonRectangular(SupportsNonRectangular
),
7783 Stack(Stack
), DefaultLoc(DefaultLoc
), ConditionLoc(DefaultLoc
) {}
7784 /// Check init-expr for canonical loop form and save loop counter
7785 /// variable - #Var and its initialization value - #LB.
7786 bool checkAndSetInit(Stmt
*S
, bool EmitDiags
= true);
7787 /// Check test-expr for canonical form, save upper-bound (#UB), flags
7788 /// for less/greater and for strict/non-strict comparison.
7789 bool checkAndSetCond(Expr
*S
);
7790 /// Check incr-expr for canonical loop form and return true if it
7791 /// does not conform, otherwise save loop step (#Step).
7792 bool checkAndSetInc(Expr
*S
);
7793 /// Return the loop counter variable.
7794 ValueDecl
*getLoopDecl() const { return LCDecl
; }
7795 /// Return the reference expression to loop counter variable.
7796 Expr
*getLoopDeclRefExpr() const { return LCRef
; }
7797 /// Source range of the loop init.
7798 SourceRange
getInitSrcRange() const { return InitSrcRange
; }
7799 /// Source range of the loop condition.
7800 SourceRange
getConditionSrcRange() const { return ConditionSrcRange
; }
7801 /// Source range of the loop increment.
7802 SourceRange
getIncrementSrcRange() const { return IncrementSrcRange
; }
7803 /// True if the step should be subtracted.
7804 bool shouldSubtractStep() const { return SubtractStep
; }
7805 /// True, if the compare operator is strict (<, > or !=).
7806 bool isStrictTestOp() const { return TestIsStrictOp
; }
7807 /// Build the expression to calculate the number of iterations.
7808 Expr
*buildNumIterations(
7809 Scope
*S
, ArrayRef
<LoopIterationSpace
> ResultIterSpaces
, bool LimitedType
,
7810 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const;
7811 /// Build the precondition expression for the loops.
7813 buildPreCond(Scope
*S
, Expr
*Cond
,
7814 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const;
7815 /// Build reference expression to the counter be used for codegen.
7817 buildCounterVar(llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
,
7818 DSAStackTy
&DSA
) const;
7819 /// Build reference expression to the private counter be used for
7821 Expr
*buildPrivateCounterVar() const;
7822 /// Build initialization of the counter be used for codegen.
7823 Expr
*buildCounterInit() const;
7824 /// Build step of the counter be used for codegen.
7825 Expr
*buildCounterStep() const;
7826 /// Build loop data with counter value for depend clauses in ordered
7829 buildOrderedLoopData(Scope
*S
, Expr
*Counter
,
7830 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
,
7831 SourceLocation Loc
, Expr
*Inc
= nullptr,
7832 OverloadedOperatorKind OOK
= OO_Amp
);
7833 /// Builds the minimum value for the loop counter.
7834 std::pair
<Expr
*, Expr
*> buildMinMaxValues(
7835 Scope
*S
, llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const;
7836 /// Builds final condition for the non-rectangular loops.
7837 Expr
*buildFinalCondition(Scope
*S
) const;
7838 /// Return true if any expression is dependent.
7839 bool dependent() const;
7840 /// Returns true if the initializer forms non-rectangular loop.
7841 bool doesInitDependOnLC() const { return InitDependOnLC
.has_value(); }
7842 /// Returns true if the condition forms non-rectangular loop.
7843 bool doesCondDependOnLC() const { return CondDependOnLC
.has_value(); }
7844 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7845 unsigned getLoopDependentIdx() const {
7846 return InitDependOnLC
.value_or(CondDependOnLC
.value_or(0));
7850 /// Check the right-hand side of an assignment in the increment
7852 bool checkAndSetIncRHS(Expr
*RHS
);
7853 /// Helper to set loop counter variable and its initializer.
7854 bool setLCDeclAndLB(ValueDecl
*NewLCDecl
, Expr
*NewDeclRefExpr
, Expr
*NewLB
,
7856 /// Helper to set upper bound.
7857 bool setUB(Expr
*NewUB
, llvm::Optional
<bool> LessOp
, bool StrictOp
,
7858 SourceRange SR
, SourceLocation SL
);
7859 /// Helper to set loop increment.
7860 bool setStep(Expr
*NewStep
, bool Subtract
);
7863 bool OpenMPIterationSpaceChecker::dependent() const {
7865 assert(!LB
&& !UB
&& !Step
);
7868 return LCDecl
->getType()->isDependentType() ||
7869 (LB
&& LB
->isValueDependent()) || (UB
&& UB
->isValueDependent()) ||
7870 (Step
&& Step
->isValueDependent());
7873 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl
*NewLCDecl
,
7875 Expr
*NewLB
, bool EmitDiags
) {
7876 // State consistency checking to ensure correct usage.
7877 assert(LCDecl
== nullptr && LB
== nullptr && LCRef
== nullptr &&
7878 UB
== nullptr && Step
== nullptr && !TestIsLessOp
&& !TestIsStrictOp
);
7879 if (!NewLCDecl
|| !NewLB
|| NewLB
->containsErrors())
7881 LCDecl
= getCanonicalDecl(NewLCDecl
);
7882 LCRef
= NewLCRefExpr
;
7883 if (auto *CE
= dyn_cast_or_null
<CXXConstructExpr
>(NewLB
))
7884 if (const CXXConstructorDecl
*Ctor
= CE
->getConstructor())
7885 if ((Ctor
->isCopyOrMoveConstructor() ||
7886 Ctor
->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7887 CE
->getNumArgs() > 0 && CE
->getArg(0) != nullptr)
7888 NewLB
= CE
->getArg(0)->IgnoreParenImpCasts();
7891 InitDependOnLC
= doesDependOnLoopCounter(LB
, /*IsInitializer=*/true);
7895 bool OpenMPIterationSpaceChecker::setUB(Expr
*NewUB
,
7896 llvm::Optional
<bool> LessOp
,
7897 bool StrictOp
, SourceRange SR
,
7898 SourceLocation SL
) {
7899 // State consistency checking to ensure correct usage.
7900 assert(LCDecl
!= nullptr && LB
!= nullptr && UB
== nullptr &&
7901 Step
== nullptr && !TestIsLessOp
&& !TestIsStrictOp
);
7902 if (!NewUB
|| NewUB
->containsErrors())
7906 TestIsLessOp
= LessOp
;
7907 TestIsStrictOp
= StrictOp
;
7908 ConditionSrcRange
= SR
;
7910 CondDependOnLC
= doesDependOnLoopCounter(UB
, /*IsInitializer=*/false);
7914 bool OpenMPIterationSpaceChecker::setStep(Expr
*NewStep
, bool Subtract
) {
7915 // State consistency checking to ensure correct usage.
7916 assert(LCDecl
!= nullptr && LB
!= nullptr && Step
== nullptr);
7917 if (!NewStep
|| NewStep
->containsErrors())
7919 if (!NewStep
->isValueDependent()) {
7920 // Check that the step is integer expression.
7921 SourceLocation StepLoc
= NewStep
->getBeginLoc();
7922 ExprResult Val
= SemaRef
.PerformOpenMPImplicitIntegerConversion(
7923 StepLoc
, getExprAsWritten(NewStep
));
7924 if (Val
.isInvalid())
7926 NewStep
= Val
.get();
7928 // OpenMP [2.6, Canonical Loop Form, Restrictions]
7929 // If test-expr is of form var relational-op b and relational-op is < or
7930 // <= then incr-expr must cause var to increase on each iteration of the
7931 // loop. If test-expr is of form var relational-op b and relational-op is
7932 // > or >= then incr-expr must cause var to decrease on each iteration of
7934 // If test-expr is of form b relational-op var and relational-op is < or
7935 // <= then incr-expr must cause var to decrease on each iteration of the
7936 // loop. If test-expr is of form b relational-op var and relational-op is
7937 // > or >= then incr-expr must cause var to increase on each iteration of
7939 Optional
<llvm::APSInt
> Result
=
7940 NewStep
->getIntegerConstantExpr(SemaRef
.Context
);
7941 bool IsUnsigned
= !NewStep
->getType()->hasSignedIntegerRepresentation();
7943 Result
&& Result
->isSigned() && (Subtract
!= Result
->isNegative());
7945 Result
&& Result
->isSigned() && (Subtract
== Result
->isNegative());
7946 bool IsConstZero
= Result
&& !Result
->getBoolValue();
7948 // != with increment is treated as <; != with decrement is treated as >
7950 TestIsLessOp
= IsConstPos
|| (IsUnsigned
&& !Subtract
);
7953 (TestIsLessOp
.value() ? (IsConstNeg
|| (IsUnsigned
&& Subtract
))
7954 : (IsConstPos
|| (IsUnsigned
&& !Subtract
))))) {
7955 SemaRef
.Diag(NewStep
->getExprLoc(),
7956 diag::err_omp_loop_incr_not_compatible
)
7957 << LCDecl
<< TestIsLessOp
.value() << NewStep
->getSourceRange();
7958 SemaRef
.Diag(ConditionLoc
,
7959 diag::note_omp_loop_cond_requres_compatible_incr
)
7960 << TestIsLessOp
.value() << ConditionSrcRange
;
7963 if (TestIsLessOp
.value() == Subtract
) {
7965 SemaRef
.CreateBuiltinUnaryOp(NewStep
->getExprLoc(), UO_Minus
, NewStep
)
7967 Subtract
= !Subtract
;
7972 SubtractStep
= Subtract
;
7977 /// Checker for the non-rectangular loops. Checks if the initializer or
7978 /// condition expression references loop counter variable.
7979 class LoopCounterRefChecker final
7980 : public ConstStmtVisitor
<LoopCounterRefChecker
, bool> {
7983 const ValueDecl
*CurLCDecl
= nullptr;
7984 const ValueDecl
*DepDecl
= nullptr;
7985 const ValueDecl
*PrevDepDecl
= nullptr;
7986 bool IsInitializer
= true;
7987 bool SupportsNonRectangular
;
7988 unsigned BaseLoopId
= 0;
7989 bool checkDecl(const Expr
*E
, const ValueDecl
*VD
) {
7990 if (getCanonicalDecl(VD
) == getCanonicalDecl(CurLCDecl
)) {
7991 SemaRef
.Diag(E
->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter
)
7992 << (IsInitializer
? 0 : 1);
7995 const auto &&Data
= Stack
.isLoopControlVariable(VD
);
7996 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7997 // The type of the loop iterator on which we depend may not have a random
7998 // access iterator type.
7999 if (Data
.first
&& VD
->getType()->isRecordType()) {
8000 SmallString
<128> Name
;
8001 llvm::raw_svector_ostream
OS(Name
);
8002 VD
->getNameForDiagnostic(OS
, SemaRef
.getPrintingPolicy(),
8003 /*Qualified=*/true);
8004 SemaRef
.Diag(E
->getExprLoc(),
8005 diag::err_omp_wrong_dependency_iterator_type
)
8007 SemaRef
.Diag(VD
->getLocation(), diag::note_previous_decl
) << VD
;
8010 if (Data
.first
&& !SupportsNonRectangular
) {
8011 SemaRef
.Diag(E
->getExprLoc(), diag::err_omp_invariant_dependency
);
8015 (DepDecl
|| (PrevDepDecl
&&
8016 getCanonicalDecl(VD
) != getCanonicalDecl(PrevDepDecl
)))) {
8017 if (!DepDecl
&& PrevDepDecl
)
8018 DepDecl
= PrevDepDecl
;
8019 SmallString
<128> Name
;
8020 llvm::raw_svector_ostream
OS(Name
);
8021 DepDecl
->getNameForDiagnostic(OS
, SemaRef
.getPrintingPolicy(),
8022 /*Qualified=*/true);
8023 SemaRef
.Diag(E
->getExprLoc(),
8024 diag::err_omp_invariant_or_linear_dependency
)
8030 BaseLoopId
= Data
.first
;
8036 bool VisitDeclRefExpr(const DeclRefExpr
*E
) {
8037 const ValueDecl
*VD
= E
->getDecl();
8038 if (isa
<VarDecl
>(VD
))
8039 return checkDecl(E
, VD
);
8042 bool VisitMemberExpr(const MemberExpr
*E
) {
8043 if (isa
<CXXThisExpr
>(E
->getBase()->IgnoreParens())) {
8044 const ValueDecl
*VD
= E
->getMemberDecl();
8045 if (isa
<VarDecl
>(VD
) || isa
<FieldDecl
>(VD
))
8046 return checkDecl(E
, VD
);
8050 bool VisitStmt(const Stmt
*S
) {
8052 for (const Stmt
*Child
: S
->children())
8053 Res
= (Child
&& Visit(Child
)) || Res
;
8056 explicit LoopCounterRefChecker(Sema
&SemaRef
, DSAStackTy
&Stack
,
8057 const ValueDecl
*CurLCDecl
, bool IsInitializer
,
8058 const ValueDecl
*PrevDepDecl
= nullptr,
8059 bool SupportsNonRectangular
= true)
8060 : SemaRef(SemaRef
), Stack(Stack
), CurLCDecl(CurLCDecl
),
8061 PrevDepDecl(PrevDepDecl
), IsInitializer(IsInitializer
),
8062 SupportsNonRectangular(SupportsNonRectangular
) {}
8063 unsigned getBaseLoopId() const {
8064 assert(CurLCDecl
&& "Expected loop dependency.");
8067 const ValueDecl
*getDepDecl() const {
8068 assert(CurLCDecl
&& "Expected loop dependency.");
8075 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt
*S
,
8076 bool IsInitializer
) {
8077 // Check for the non-rectangular loops.
8078 LoopCounterRefChecker
LoopStmtChecker(SemaRef
, Stack
, LCDecl
, IsInitializer
,
8079 DepDecl
, SupportsNonRectangular
);
8080 if (LoopStmtChecker
.Visit(S
)) {
8081 DepDecl
= LoopStmtChecker
.getDepDecl();
8082 return LoopStmtChecker
.getBaseLoopId();
8087 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt
*S
, bool EmitDiags
) {
8088 // Check init-expr for canonical loop form and save loop counter
8089 // variable - #Var and its initialization value - #LB.
8090 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8092 // integer-type var = lb
8093 // random-access-iterator-type var = lb
8094 // pointer-type var = lb
8098 SemaRef
.Diag(DefaultLoc
, diag::err_omp_loop_not_canonical_init
);
8102 if (auto *ExprTemp
= dyn_cast
<ExprWithCleanups
>(S
))
8103 if (!ExprTemp
->cleanupsHaveSideEffects())
8104 S
= ExprTemp
->getSubExpr();
8106 InitSrcRange
= S
->getSourceRange();
8107 if (Expr
*E
= dyn_cast
<Expr
>(S
))
8108 S
= E
->IgnoreParens();
8109 if (auto *BO
= dyn_cast
<BinaryOperator
>(S
)) {
8110 if (BO
->getOpcode() == BO_Assign
) {
8111 Expr
*LHS
= BO
->getLHS()->IgnoreParens();
8112 if (auto *DRE
= dyn_cast
<DeclRefExpr
>(LHS
)) {
8113 if (auto *CED
= dyn_cast
<OMPCapturedExprDecl
>(DRE
->getDecl()))
8114 if (auto *ME
= dyn_cast
<MemberExpr
>(getExprAsWritten(CED
->getInit())))
8115 return setLCDeclAndLB(ME
->getMemberDecl(), ME
, BO
->getRHS(),
8117 return setLCDeclAndLB(DRE
->getDecl(), DRE
, BO
->getRHS(), EmitDiags
);
8119 if (auto *ME
= dyn_cast
<MemberExpr
>(LHS
)) {
8120 if (ME
->isArrow() &&
8121 isa
<CXXThisExpr
>(ME
->getBase()->IgnoreParenImpCasts()))
8122 return setLCDeclAndLB(ME
->getMemberDecl(), ME
, BO
->getRHS(),
8126 } else if (auto *DS
= dyn_cast
<DeclStmt
>(S
)) {
8127 if (DS
->isSingleDecl()) {
8128 if (auto *Var
= dyn_cast_or_null
<VarDecl
>(DS
->getSingleDecl())) {
8129 if (Var
->hasInit() && !Var
->getType()->isReferenceType()) {
8130 // Accept non-canonical init form here but emit ext. warning.
8131 if (Var
->getInitStyle() != VarDecl::CInit
&& EmitDiags
)
8132 SemaRef
.Diag(S
->getBeginLoc(),
8133 diag::ext_omp_loop_not_canonical_init
)
8134 << S
->getSourceRange();
8135 return setLCDeclAndLB(
8137 buildDeclRefExpr(SemaRef
, Var
,
8138 Var
->getType().getNonReferenceType(),
8140 Var
->getInit(), EmitDiags
);
8144 } else if (auto *CE
= dyn_cast
<CXXOperatorCallExpr
>(S
)) {
8145 if (CE
->getOperator() == OO_Equal
) {
8146 Expr
*LHS
= CE
->getArg(0);
8147 if (auto *DRE
= dyn_cast
<DeclRefExpr
>(LHS
)) {
8148 if (auto *CED
= dyn_cast
<OMPCapturedExprDecl
>(DRE
->getDecl()))
8149 if (auto *ME
= dyn_cast
<MemberExpr
>(getExprAsWritten(CED
->getInit())))
8150 return setLCDeclAndLB(ME
->getMemberDecl(), ME
, BO
->getRHS(),
8152 return setLCDeclAndLB(DRE
->getDecl(), DRE
, CE
->getArg(1), EmitDiags
);
8154 if (auto *ME
= dyn_cast
<MemberExpr
>(LHS
)) {
8155 if (ME
->isArrow() &&
8156 isa
<CXXThisExpr
>(ME
->getBase()->IgnoreParenImpCasts()))
8157 return setLCDeclAndLB(ME
->getMemberDecl(), ME
, BO
->getRHS(),
8163 if (dependent() || SemaRef
.CurContext
->isDependentContext())
8166 SemaRef
.Diag(S
->getBeginLoc(), diag::err_omp_loop_not_canonical_init
)
8167 << S
->getSourceRange();
8172 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8173 /// variable (which may be the loop variable) if possible.
8174 static const ValueDecl
*getInitLCDecl(const Expr
*E
) {
8177 E
= getExprAsWritten(E
);
8178 if (const auto *CE
= dyn_cast_or_null
<CXXConstructExpr
>(E
))
8179 if (const CXXConstructorDecl
*Ctor
= CE
->getConstructor())
8180 if ((Ctor
->isCopyOrMoveConstructor() ||
8181 Ctor
->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8182 CE
->getNumArgs() > 0 && CE
->getArg(0) != nullptr)
8183 E
= CE
->getArg(0)->IgnoreParenImpCasts();
8184 if (const auto *DRE
= dyn_cast_or_null
<DeclRefExpr
>(E
)) {
8185 if (const auto *VD
= dyn_cast
<VarDecl
>(DRE
->getDecl()))
8186 return getCanonicalDecl(VD
);
8188 if (const auto *ME
= dyn_cast_or_null
<MemberExpr
>(E
))
8189 if (ME
->isArrow() && isa
<CXXThisExpr
>(ME
->getBase()->IgnoreParenImpCasts()))
8190 return getCanonicalDecl(ME
->getMemberDecl());
8194 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr
*S
) {
8195 // Check test-expr for canonical form, save upper-bound UB, flags for
8196 // less/greater and for strict/non-strict comparison.
8197 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8198 // var relational-op b
8199 // b relational-op var
8201 bool IneqCondIsCanonical
= SemaRef
.getLangOpts().OpenMP
>= 50;
8203 SemaRef
.Diag(DefaultLoc
, diag::err_omp_loop_not_canonical_cond
)
8204 << (IneqCondIsCanonical
? 1 : 0) << LCDecl
;
8208 S
= getExprAsWritten(S
);
8209 SourceLocation CondLoc
= S
->getBeginLoc();
8210 auto &&CheckAndSetCond
= [this, IneqCondIsCanonical
](
8211 BinaryOperatorKind Opcode
, const Expr
*LHS
,
8212 const Expr
*RHS
, SourceRange SR
,
8213 SourceLocation OpLoc
) -> llvm::Optional
<bool> {
8214 if (BinaryOperator::isRelationalOp(Opcode
)) {
8215 if (getInitLCDecl(LHS
) == LCDecl
)
8216 return setUB(const_cast<Expr
*>(RHS
),
8217 (Opcode
== BO_LT
|| Opcode
== BO_LE
),
8218 (Opcode
== BO_LT
|| Opcode
== BO_GT
), SR
, OpLoc
);
8219 if (getInitLCDecl(RHS
) == LCDecl
)
8220 return setUB(const_cast<Expr
*>(LHS
),
8221 (Opcode
== BO_GT
|| Opcode
== BO_GE
),
8222 (Opcode
== BO_LT
|| Opcode
== BO_GT
), SR
, OpLoc
);
8223 } else if (IneqCondIsCanonical
&& Opcode
== BO_NE
) {
8224 return setUB(const_cast<Expr
*>(getInitLCDecl(LHS
) == LCDecl
? RHS
: LHS
),
8225 /*LessOp=*/llvm::None
,
8226 /*StrictOp=*/true, SR
, OpLoc
);
8230 llvm::Optional
<bool> Res
;
8231 if (auto *RBO
= dyn_cast
<CXXRewrittenBinaryOperator
>(S
)) {
8232 CXXRewrittenBinaryOperator::DecomposedForm DF
= RBO
->getDecomposedForm();
8233 Res
= CheckAndSetCond(DF
.Opcode
, DF
.LHS
, DF
.RHS
, RBO
->getSourceRange(),
8234 RBO
->getOperatorLoc());
8235 } else if (auto *BO
= dyn_cast
<BinaryOperator
>(S
)) {
8236 Res
= CheckAndSetCond(BO
->getOpcode(), BO
->getLHS(), BO
->getRHS(),
8237 BO
->getSourceRange(), BO
->getOperatorLoc());
8238 } else if (auto *CE
= dyn_cast
<CXXOperatorCallExpr
>(S
)) {
8239 if (CE
->getNumArgs() == 2) {
8240 Res
= CheckAndSetCond(
8241 BinaryOperator::getOverloadedOpcode(CE
->getOperator()), CE
->getArg(0),
8242 CE
->getArg(1), CE
->getSourceRange(), CE
->getOperatorLoc());
8247 if (dependent() || SemaRef
.CurContext
->isDependentContext())
8249 SemaRef
.Diag(CondLoc
, diag::err_omp_loop_not_canonical_cond
)
8250 << (IneqCondIsCanonical
? 1 : 0) << S
->getSourceRange() << LCDecl
;
8254 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr
*RHS
) {
8255 // RHS of canonical loop form increment can be:
8260 RHS
= RHS
->IgnoreParenImpCasts();
8261 if (auto *BO
= dyn_cast
<BinaryOperator
>(RHS
)) {
8262 if (BO
->isAdditiveOp()) {
8263 bool IsAdd
= BO
->getOpcode() == BO_Add
;
8264 if (getInitLCDecl(BO
->getLHS()) == LCDecl
)
8265 return setStep(BO
->getRHS(), !IsAdd
);
8266 if (IsAdd
&& getInitLCDecl(BO
->getRHS()) == LCDecl
)
8267 return setStep(BO
->getLHS(), /*Subtract=*/false);
8269 } else if (auto *CE
= dyn_cast
<CXXOperatorCallExpr
>(RHS
)) {
8270 bool IsAdd
= CE
->getOperator() == OO_Plus
;
8271 if ((IsAdd
|| CE
->getOperator() == OO_Minus
) && CE
->getNumArgs() == 2) {
8272 if (getInitLCDecl(CE
->getArg(0)) == LCDecl
)
8273 return setStep(CE
->getArg(1), !IsAdd
);
8274 if (IsAdd
&& getInitLCDecl(CE
->getArg(1)) == LCDecl
)
8275 return setStep(CE
->getArg(0), /*Subtract=*/false);
8278 if (dependent() || SemaRef
.CurContext
->isDependentContext())
8280 SemaRef
.Diag(RHS
->getBeginLoc(), diag::err_omp_loop_not_canonical_incr
)
8281 << RHS
->getSourceRange() << LCDecl
;
8285 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr
*S
) {
8286 // Check incr-expr for canonical loop form and return true if it
8287 // does not conform.
8288 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8300 SemaRef
.Diag(DefaultLoc
, diag::err_omp_loop_not_canonical_incr
) << LCDecl
;
8303 if (auto *ExprTemp
= dyn_cast
<ExprWithCleanups
>(S
))
8304 if (!ExprTemp
->cleanupsHaveSideEffects())
8305 S
= ExprTemp
->getSubExpr();
8307 IncrementSrcRange
= S
->getSourceRange();
8308 S
= S
->IgnoreParens();
8309 if (auto *UO
= dyn_cast
<UnaryOperator
>(S
)) {
8310 if (UO
->isIncrementDecrementOp() &&
8311 getInitLCDecl(UO
->getSubExpr()) == LCDecl
)
8312 return setStep(SemaRef
8313 .ActOnIntegerConstant(UO
->getBeginLoc(),
8314 (UO
->isDecrementOp() ? -1 : 1))
8316 /*Subtract=*/false);
8317 } else if (auto *BO
= dyn_cast
<BinaryOperator
>(S
)) {
8318 switch (BO
->getOpcode()) {
8321 if (getInitLCDecl(BO
->getLHS()) == LCDecl
)
8322 return setStep(BO
->getRHS(), BO
->getOpcode() == BO_SubAssign
);
8325 if (getInitLCDecl(BO
->getLHS()) == LCDecl
)
8326 return checkAndSetIncRHS(BO
->getRHS());
8331 } else if (auto *CE
= dyn_cast
<CXXOperatorCallExpr
>(S
)) {
8332 switch (CE
->getOperator()) {
8335 if (getInitLCDecl(CE
->getArg(0)) == LCDecl
)
8336 return setStep(SemaRef
8337 .ActOnIntegerConstant(
8339 ((CE
->getOperator() == OO_MinusMinus
) ? -1 : 1))
8341 /*Subtract=*/false);
8345 if (getInitLCDecl(CE
->getArg(0)) == LCDecl
)
8346 return setStep(CE
->getArg(1), CE
->getOperator() == OO_MinusEqual
);
8349 if (getInitLCDecl(CE
->getArg(0)) == LCDecl
)
8350 return checkAndSetIncRHS(CE
->getArg(1));
8356 if (dependent() || SemaRef
.CurContext
->isDependentContext())
8358 SemaRef
.Diag(S
->getBeginLoc(), diag::err_omp_loop_not_canonical_incr
)
8359 << S
->getSourceRange() << LCDecl
;
8364 tryBuildCapture(Sema
&SemaRef
, Expr
*Capture
,
8365 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) {
8366 if (SemaRef
.CurContext
->isDependentContext() || Capture
->containsErrors())
8368 if (Capture
->isEvaluatable(SemaRef
.Context
, Expr::SE_AllowSideEffects
))
8369 return SemaRef
.PerformImplicitConversion(
8370 Capture
->IgnoreImpCasts(), Capture
->getType(), Sema::AA_Converting
,
8371 /*AllowExplicit=*/true);
8372 auto I
= Captures
.find(Capture
);
8373 if (I
!= Captures
.end())
8374 return buildCapture(SemaRef
, Capture
, I
->second
);
8375 DeclRefExpr
*Ref
= nullptr;
8376 ExprResult Res
= buildCapture(SemaRef
, Capture
, Ref
);
8377 Captures
[Capture
] = Ref
;
8381 /// Calculate number of iterations, transforming to unsigned, if number of
8382 /// iterations may be larger than the original type.
8384 calculateNumIters(Sema
&SemaRef
, Scope
*S
, SourceLocation DefaultLoc
,
8385 Expr
*Lower
, Expr
*Upper
, Expr
*Step
, QualType LCTy
,
8386 bool TestIsStrictOp
, bool RoundToStep
,
8387 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) {
8388 ExprResult NewStep
= tryBuildCapture(SemaRef
, Step
, Captures
);
8389 if (!NewStep
.isUsable())
8391 llvm::APSInt LRes
, SRes
;
8392 bool IsLowerConst
= false, IsStepConst
= false;
8393 if (Optional
<llvm::APSInt
> Res
=
8394 Lower
->getIntegerConstantExpr(SemaRef
.Context
)) {
8396 IsLowerConst
= true;
8398 if (Optional
<llvm::APSInt
> Res
=
8399 Step
->getIntegerConstantExpr(SemaRef
.Context
)) {
8403 bool NoNeedToConvert
= IsLowerConst
&& !RoundToStep
&&
8404 ((!TestIsStrictOp
&& LRes
.isNonNegative()) ||
8405 (TestIsStrictOp
&& LRes
.isStrictlyPositive()));
8406 bool NeedToReorganize
= false;
8407 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8408 if (!NoNeedToConvert
&& IsLowerConst
&&
8409 (TestIsStrictOp
|| (RoundToStep
&& IsStepConst
))) {
8410 NoNeedToConvert
= true;
8412 unsigned BW
= LRes
.getBitWidth() > SRes
.getBitWidth()
8413 ? LRes
.getBitWidth()
8414 : SRes
.getBitWidth();
8415 LRes
= LRes
.extend(BW
+ 1);
8416 LRes
.setIsSigned(true);
8417 SRes
= SRes
.extend(BW
+ 1);
8418 SRes
.setIsSigned(true);
8420 NoNeedToConvert
= LRes
.trunc(BW
).extend(BW
+ 1) == LRes
;
8421 LRes
= LRes
.trunc(BW
);
8423 if (TestIsStrictOp
) {
8424 unsigned BW
= LRes
.getBitWidth();
8425 LRes
= LRes
.extend(BW
+ 1);
8426 LRes
.setIsSigned(true);
8429 NoNeedToConvert
&& LRes
.trunc(BW
).extend(BW
+ 1) == LRes
;
8430 // truncate to the original bitwidth.
8431 LRes
= LRes
.trunc(BW
);
8433 NeedToReorganize
= NoNeedToConvert
;
8436 bool IsUpperConst
= false;
8437 if (Optional
<llvm::APSInt
> Res
=
8438 Upper
->getIntegerConstantExpr(SemaRef
.Context
)) {
8440 IsUpperConst
= true;
8442 if (NoNeedToConvert
&& IsLowerConst
&& IsUpperConst
&&
8443 (!RoundToStep
|| IsStepConst
)) {
8444 unsigned BW
= LRes
.getBitWidth() > URes
.getBitWidth() ? LRes
.getBitWidth()
8445 : URes
.getBitWidth();
8446 LRes
= LRes
.extend(BW
+ 1);
8447 LRes
.setIsSigned(true);
8448 URes
= URes
.extend(BW
+ 1);
8449 URes
.setIsSigned(true);
8451 NoNeedToConvert
= URes
.trunc(BW
).extend(BW
+ 1) == URes
;
8452 NeedToReorganize
= NoNeedToConvert
;
8454 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8455 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8457 if ((!NoNeedToConvert
|| (LRes
.isNegative() && !IsUpperConst
)) &&
8458 !LCTy
->isDependentType() && LCTy
->isIntegerType()) {
8459 QualType LowerTy
= Lower
->getType();
8460 QualType UpperTy
= Upper
->getType();
8461 uint64_t LowerSize
= SemaRef
.Context
.getTypeSize(LowerTy
);
8462 uint64_t UpperSize
= SemaRef
.Context
.getTypeSize(UpperTy
);
8463 if ((LowerSize
<= UpperSize
&& UpperTy
->hasSignedIntegerRepresentation()) ||
8464 (LowerSize
> UpperSize
&& LowerTy
->hasSignedIntegerRepresentation())) {
8465 QualType CastType
= SemaRef
.Context
.getIntTypeForBitwidth(
8466 LowerSize
> UpperSize
? LowerSize
: UpperSize
, /*Signed=*/0);
8469 .PerformImplicitConversion(
8470 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Upper
).get(),
8471 CastType
, Sema::AA_Converting
)
8473 Lower
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Lower
).get();
8474 NewStep
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, NewStep
.get());
8477 if (!Lower
|| !Upper
|| NewStep
.isInvalid())
8481 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8483 if (NeedToReorganize
) {
8489 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Sub
, Diff
.get(), NewStep
.get());
8490 if (!Diff
.isUsable())
8494 // Lower - Step [+ 1]
8496 Diff
= SemaRef
.BuildBinOp(
8497 S
, DefaultLoc
, BO_Add
, Diff
.get(),
8498 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get());
8499 if (!Diff
.isUsable())
8502 Diff
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Diff
.get());
8503 if (!Diff
.isUsable())
8506 // Upper - (Lower - Step [+ 1]).
8507 Diff
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Sub
, Upper
, Diff
.get());
8508 if (!Diff
.isUsable())
8511 Diff
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Sub
, Upper
, Lower
);
8513 if (!Diff
.isUsable() && LCTy
->getAsCXXRecordDecl()) {
8514 // BuildBinOp already emitted error, this one is to point user to upper
8515 // and lower bound, and to tell what is passed to 'operator-'.
8516 SemaRef
.Diag(Upper
->getBeginLoc(), diag::err_omp_loop_diff_cxx
)
8517 << Upper
->getSourceRange() << Lower
->getSourceRange();
8521 if (!Diff
.isUsable())
8524 // Upper - Lower [- 1]
8526 Diff
= SemaRef
.BuildBinOp(
8527 S
, DefaultLoc
, BO_Sub
, Diff
.get(),
8528 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get());
8529 if (!Diff
.isUsable())
8533 // Upper - Lower [- 1] + Step
8535 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Add
, Diff
.get(), NewStep
.get());
8536 if (!Diff
.isUsable())
8541 // Parentheses (for dumping/debugging purposes only).
8542 Diff
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Diff
.get());
8543 if (!Diff
.isUsable())
8546 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8547 Diff
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Div
, Diff
.get(), NewStep
.get());
8548 if (!Diff
.isUsable())
8554 /// Build the expression to calculate the number of iterations.
8555 Expr
*OpenMPIterationSpaceChecker::buildNumIterations(
8556 Scope
*S
, ArrayRef
<LoopIterationSpace
> ResultIterSpaces
, bool LimitedType
,
8557 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const {
8558 QualType VarType
= LCDecl
->getType().getNonReferenceType();
8559 if (!VarType
->isIntegerType() && !VarType
->isPointerType() &&
8560 !SemaRef
.getLangOpts().CPlusPlus
)
8564 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8565 // max(LB(MinVal), LB(MaxVal))
8566 if (InitDependOnLC
) {
8567 const LoopIterationSpace
&IS
= ResultIterSpaces
[*InitDependOnLC
- 1];
8568 if (!IS
.MinValue
|| !IS
.MaxValue
)
8571 ExprResult MinValue
=
8572 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, IS
.MinValue
);
8573 if (!MinValue
.isUsable())
8576 ExprResult LBMinVal
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Assign
,
8577 IS
.CounterVar
, MinValue
.get());
8578 if (!LBMinVal
.isUsable())
8580 // OuterVar = Min, LBVal
8582 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Comma
, LBMinVal
.get(), LBVal
);
8583 if (!LBMinVal
.isUsable())
8585 // (OuterVar = Min, LBVal)
8586 LBMinVal
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, LBMinVal
.get());
8587 if (!LBMinVal
.isUsable())
8591 ExprResult MaxValue
=
8592 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, IS
.MaxValue
);
8593 if (!MaxValue
.isUsable())
8596 ExprResult LBMaxVal
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Assign
,
8597 IS
.CounterVar
, MaxValue
.get());
8598 if (!LBMaxVal
.isUsable())
8600 // OuterVar = Max, LBVal
8602 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Comma
, LBMaxVal
.get(), LBVal
);
8603 if (!LBMaxVal
.isUsable())
8605 // (OuterVar = Max, LBVal)
8606 LBMaxVal
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, LBMaxVal
.get());
8607 if (!LBMaxVal
.isUsable())
8610 Expr
*LBMin
= tryBuildCapture(SemaRef
, LBMinVal
.get(), Captures
).get();
8611 Expr
*LBMax
= tryBuildCapture(SemaRef
, LBMaxVal
.get(), Captures
).get();
8612 if (!LBMin
|| !LBMax
)
8614 // LB(MinVal) < LB(MaxVal)
8615 ExprResult MinLessMaxRes
=
8616 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_LT
, LBMin
, LBMax
);
8617 if (!MinLessMaxRes
.isUsable())
8620 tryBuildCapture(SemaRef
, MinLessMaxRes
.get(), Captures
).get();
8623 if (*TestIsLessOp
) {
8624 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8626 ExprResult MinLB
= SemaRef
.ActOnConditionalOp(DefaultLoc
, DefaultLoc
,
8627 MinLessMax
, LBMin
, LBMax
);
8628 if (!MinLB
.isUsable())
8630 LBVal
= MinLB
.get();
8632 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8634 ExprResult MaxLB
= SemaRef
.ActOnConditionalOp(DefaultLoc
, DefaultLoc
,
8635 MinLessMax
, LBMax
, LBMin
);
8636 if (!MaxLB
.isUsable())
8638 LBVal
= MaxLB
.get();
8641 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8642 // min(UB(MinVal), UB(MaxVal))
8643 if (CondDependOnLC
) {
8644 const LoopIterationSpace
&IS
= ResultIterSpaces
[*CondDependOnLC
- 1];
8645 if (!IS
.MinValue
|| !IS
.MaxValue
)
8648 ExprResult MinValue
=
8649 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, IS
.MinValue
);
8650 if (!MinValue
.isUsable())
8653 ExprResult UBMinVal
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Assign
,
8654 IS
.CounterVar
, MinValue
.get());
8655 if (!UBMinVal
.isUsable())
8657 // OuterVar = Min, UBVal
8659 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Comma
, UBMinVal
.get(), UBVal
);
8660 if (!UBMinVal
.isUsable())
8662 // (OuterVar = Min, UBVal)
8663 UBMinVal
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, UBMinVal
.get());
8664 if (!UBMinVal
.isUsable())
8668 ExprResult MaxValue
=
8669 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, IS
.MaxValue
);
8670 if (!MaxValue
.isUsable())
8673 ExprResult UBMaxVal
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Assign
,
8674 IS
.CounterVar
, MaxValue
.get());
8675 if (!UBMaxVal
.isUsable())
8677 // OuterVar = Max, UBVal
8679 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Comma
, UBMaxVal
.get(), UBVal
);
8680 if (!UBMaxVal
.isUsable())
8682 // (OuterVar = Max, UBVal)
8683 UBMaxVal
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, UBMaxVal
.get());
8684 if (!UBMaxVal
.isUsable())
8687 Expr
*UBMin
= tryBuildCapture(SemaRef
, UBMinVal
.get(), Captures
).get();
8688 Expr
*UBMax
= tryBuildCapture(SemaRef
, UBMaxVal
.get(), Captures
).get();
8689 if (!UBMin
|| !UBMax
)
8691 // UB(MinVal) > UB(MaxVal)
8692 ExprResult MinGreaterMaxRes
=
8693 SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_GT
, UBMin
, UBMax
);
8694 if (!MinGreaterMaxRes
.isUsable())
8696 Expr
*MinGreaterMax
=
8697 tryBuildCapture(SemaRef
, MinGreaterMaxRes
.get(), Captures
).get();
8700 if (*TestIsLessOp
) {
8701 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8703 ExprResult MaxUB
= SemaRef
.ActOnConditionalOp(
8704 DefaultLoc
, DefaultLoc
, MinGreaterMax
, UBMin
, UBMax
);
8705 if (!MaxUB
.isUsable())
8707 UBVal
= MaxUB
.get();
8709 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8711 ExprResult MinUB
= SemaRef
.ActOnConditionalOp(
8712 DefaultLoc
, DefaultLoc
, MinGreaterMax
, UBMax
, UBMin
);
8713 if (!MinUB
.isUsable())
8715 UBVal
= MinUB
.get();
8718 Expr
*UBExpr
= TestIsLessOp
.value() ? UBVal
: LBVal
;
8719 Expr
*LBExpr
= TestIsLessOp
.value() ? LBVal
: UBVal
;
8720 Expr
*Upper
= tryBuildCapture(SemaRef
, UBExpr
, Captures
).get();
8721 Expr
*Lower
= tryBuildCapture(SemaRef
, LBExpr
, Captures
).get();
8722 if (!Upper
|| !Lower
)
8725 ExprResult Diff
= calculateNumIters(SemaRef
, S
, DefaultLoc
, Lower
, Upper
,
8726 Step
, VarType
, TestIsStrictOp
,
8727 /*RoundToStep=*/true, Captures
);
8728 if (!Diff
.isUsable())
8731 // OpenMP runtime requires 32-bit or 64-bit loop variables.
8732 QualType Type
= Diff
.get()->getType();
8733 ASTContext
&C
= SemaRef
.Context
;
8734 bool UseVarType
= VarType
->hasIntegerRepresentation() &&
8735 C
.getTypeSize(Type
) > C
.getTypeSize(VarType
);
8736 if (!Type
->isIntegerType() || UseVarType
) {
8738 UseVarType
? C
.getTypeSize(VarType
) : C
.getTypeSize(Type
);
8739 bool IsSigned
= UseVarType
? VarType
->hasSignedIntegerRepresentation()
8740 : Type
->hasSignedIntegerRepresentation();
8741 Type
= C
.getIntTypeForBitwidth(NewSize
, IsSigned
);
8742 if (!SemaRef
.Context
.hasSameType(Diff
.get()->getType(), Type
)) {
8743 Diff
= SemaRef
.PerformImplicitConversion(
8744 Diff
.get(), Type
, Sema::AA_Converting
, /*AllowExplicit=*/true);
8745 if (!Diff
.isUsable())
8750 unsigned NewSize
= (C
.getTypeSize(Type
) > 32) ? 64 : 32;
8751 if (NewSize
!= C
.getTypeSize(Type
)) {
8752 if (NewSize
< C
.getTypeSize(Type
)) {
8753 assert(NewSize
== 64 && "incorrect loop var size");
8754 SemaRef
.Diag(DefaultLoc
, diag::warn_omp_loop_64_bit_var
)
8755 << InitSrcRange
<< ConditionSrcRange
;
8757 QualType NewType
= C
.getIntTypeForBitwidth(
8758 NewSize
, Type
->hasSignedIntegerRepresentation() ||
8759 C
.getTypeSize(Type
) < NewSize
);
8760 if (!SemaRef
.Context
.hasSameType(Diff
.get()->getType(), NewType
)) {
8761 Diff
= SemaRef
.PerformImplicitConversion(Diff
.get(), NewType
,
8762 Sema::AA_Converting
, true);
8763 if (!Diff
.isUsable())
8772 std::pair
<Expr
*, Expr
*> OpenMPIterationSpaceChecker::buildMinMaxValues(
8773 Scope
*S
, llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const {
8774 // Do not build for iterators, they cannot be used in non-rectangular loop
8776 if (LCDecl
->getType()->isRecordType())
8777 return std::make_pair(nullptr, nullptr);
8778 // If we subtract, the min is in the condition, otherwise the min is in the
8780 Expr
*MinExpr
= nullptr;
8781 Expr
*MaxExpr
= nullptr;
8782 Expr
*LBExpr
= TestIsLessOp
.value() ? LB
: UB
;
8783 Expr
*UBExpr
= TestIsLessOp
.value() ? UB
: LB
;
8784 bool LBNonRect
= TestIsLessOp
.value() ? InitDependOnLC
.has_value()
8785 : CondDependOnLC
.has_value();
8786 bool UBNonRect
= TestIsLessOp
.value() ? CondDependOnLC
.has_value()
8787 : InitDependOnLC
.has_value();
8789 LBNonRect
? LBExpr
: tryBuildCapture(SemaRef
, LBExpr
, Captures
).get();
8791 UBNonRect
? UBExpr
: tryBuildCapture(SemaRef
, UBExpr
, Captures
).get();
8792 if (!Upper
|| !Lower
)
8793 return std::make_pair(nullptr, nullptr);
8800 // Build minimum/maximum value based on number of iterations.
8801 QualType VarType
= LCDecl
->getType().getNonReferenceType();
8803 ExprResult Diff
= calculateNumIters(SemaRef
, S
, DefaultLoc
, Lower
, Upper
,
8804 Step
, VarType
, TestIsStrictOp
,
8805 /*RoundToStep=*/false, Captures
);
8806 if (!Diff
.isUsable())
8807 return std::make_pair(nullptr, nullptr);
8809 // ((Upper - Lower [- 1]) / Step) * Step
8810 // Parentheses (for dumping/debugging purposes only).
8811 Diff
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Diff
.get());
8812 if (!Diff
.isUsable())
8813 return std::make_pair(nullptr, nullptr);
8815 ExprResult NewStep
= tryBuildCapture(SemaRef
, Step
, Captures
);
8816 if (!NewStep
.isUsable())
8817 return std::make_pair(nullptr, nullptr);
8818 Diff
= SemaRef
.BuildBinOp(S
, DefaultLoc
, BO_Mul
, Diff
.get(), NewStep
.get());
8819 if (!Diff
.isUsable())
8820 return std::make_pair(nullptr, nullptr);
8822 // Parentheses (for dumping/debugging purposes only).
8823 Diff
= SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Diff
.get());
8824 if (!Diff
.isUsable())
8825 return std::make_pair(nullptr, nullptr);
8827 // Convert to the ptrdiff_t, if original type is pointer.
8828 if (VarType
->isAnyPointerType() &&
8829 !SemaRef
.Context
.hasSameType(
8830 Diff
.get()->getType(),
8831 SemaRef
.Context
.getUnsignedPointerDiffType())) {
8832 Diff
= SemaRef
.PerformImplicitConversion(
8833 Diff
.get(), SemaRef
.Context
.getUnsignedPointerDiffType(),
8834 Sema::AA_Converting
, /*AllowExplicit=*/true);
8836 if (!Diff
.isUsable())
8837 return std::make_pair(nullptr, nullptr);
8839 if (*TestIsLessOp
) {
8841 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8842 Diff
= SemaRef
.BuildBinOp(
8843 S
, DefaultLoc
, BO_Add
,
8844 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Lower
).get(),
8846 if (!Diff
.isUsable())
8847 return std::make_pair(nullptr, nullptr);
8850 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8851 Diff
= SemaRef
.BuildBinOp(
8852 S
, DefaultLoc
, BO_Sub
,
8853 SemaRef
.ActOnParenExpr(DefaultLoc
, DefaultLoc
, Upper
).get(),
8855 if (!Diff
.isUsable())
8856 return std::make_pair(nullptr, nullptr);
8859 // Convert to the original type.
8860 if (SemaRef
.Context
.hasSameType(Diff
.get()->getType(), VarType
))
8861 Diff
= SemaRef
.PerformImplicitConversion(Diff
.get(), VarType
,
8862 Sema::AA_Converting
,
8863 /*AllowExplicit=*/true);
8864 if (!Diff
.isUsable())
8865 return std::make_pair(nullptr, nullptr);
8867 Sema::TentativeAnalysisScope
Trap(SemaRef
);
8868 Diff
= SemaRef
.ActOnFinishFullExpr(Diff
.get(), /*DiscardedValue=*/false);
8869 if (!Diff
.isUsable())
8870 return std::make_pair(nullptr, nullptr);
8873 MaxExpr
= Diff
.get();
8875 MinExpr
= Diff
.get();
8877 return std::make_pair(MinExpr
, MaxExpr
);
8880 Expr
*OpenMPIterationSpaceChecker::buildFinalCondition(Scope
*S
) const {
8881 if (InitDependOnLC
|| CondDependOnLC
)
8886 Expr
*OpenMPIterationSpaceChecker::buildPreCond(
8887 Scope
*S
, Expr
*Cond
,
8888 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) const {
8889 // Do not build a precondition when the condition/initialization is dependent
8890 // to prevent pessimistic early loop exit.
8891 // TODO: this can be improved by calculating min/max values but not sure that
8892 // it will be very effective.
8893 if (CondDependOnLC
|| InitDependOnLC
)
8895 .PerformImplicitConversion(
8896 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get(),
8897 SemaRef
.Context
.BoolTy
, /*Action=*/Sema::AA_Casting
,
8898 /*AllowExplicit=*/true)
8901 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8902 Sema::TentativeAnalysisScope
Trap(SemaRef
);
8904 ExprResult NewLB
= tryBuildCapture(SemaRef
, LB
, Captures
);
8905 ExprResult NewUB
= tryBuildCapture(SemaRef
, UB
, Captures
);
8906 if (!NewLB
.isUsable() || !NewUB
.isUsable())
8909 ExprResult CondExpr
= SemaRef
.BuildBinOp(
8911 TestIsLessOp
.value() ? (TestIsStrictOp
? BO_LT
: BO_LE
)
8912 : (TestIsStrictOp
? BO_GT
: BO_GE
),
8913 NewLB
.get(), NewUB
.get());
8914 if (CondExpr
.isUsable()) {
8915 if (!SemaRef
.Context
.hasSameUnqualifiedType(CondExpr
.get()->getType(),
8916 SemaRef
.Context
.BoolTy
))
8917 CondExpr
= SemaRef
.PerformImplicitConversion(
8918 CondExpr
.get(), SemaRef
.Context
.BoolTy
, /*Action=*/Sema::AA_Casting
,
8919 /*AllowExplicit=*/true);
8922 // Otherwise use original loop condition and evaluate it in runtime.
8923 return CondExpr
.isUsable() ? CondExpr
.get() : Cond
;
8926 /// Build reference expression to the counter be used for codegen.
8927 DeclRefExpr
*OpenMPIterationSpaceChecker::buildCounterVar(
8928 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
,
8929 DSAStackTy
&DSA
) const {
8930 auto *VD
= dyn_cast
<VarDecl
>(LCDecl
);
8932 VD
= SemaRef
.isOpenMPCapturedDecl(LCDecl
);
8933 DeclRefExpr
*Ref
= buildDeclRefExpr(
8934 SemaRef
, VD
, VD
->getType().getNonReferenceType(), DefaultLoc
);
8935 const DSAStackTy::DSAVarData Data
=
8936 DSA
.getTopDSA(LCDecl
, /*FromParent=*/false);
8937 // If the loop control decl is explicitly marked as private, do not mark it
8938 // as captured again.
8939 if (!isOpenMPPrivate(Data
.CKind
) || !Data
.RefExpr
)
8940 Captures
.insert(std::make_pair(LCRef
, Ref
));
8943 return cast
<DeclRefExpr
>(LCRef
);
8946 Expr
*OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8947 if (LCDecl
&& !LCDecl
->isInvalidDecl()) {
8948 QualType Type
= LCDecl
->getType().getNonReferenceType();
8949 VarDecl
*PrivateVar
= buildVarDecl(
8950 SemaRef
, DefaultLoc
, Type
, LCDecl
->getName(),
8951 LCDecl
->hasAttrs() ? &LCDecl
->getAttrs() : nullptr,
8952 isa
<VarDecl
>(LCDecl
)
8953 ? buildDeclRefExpr(SemaRef
, cast
<VarDecl
>(LCDecl
), Type
, DefaultLoc
)
8955 if (PrivateVar
->isInvalidDecl())
8957 return buildDeclRefExpr(SemaRef
, PrivateVar
, Type
, DefaultLoc
);
8962 /// Build initialization of the counter to be used for codegen.
8963 Expr
*OpenMPIterationSpaceChecker::buildCounterInit() const { return LB
; }
8965 /// Build step of the counter be used for codegen.
8966 Expr
*OpenMPIterationSpaceChecker::buildCounterStep() const { return Step
; }
8968 Expr
*OpenMPIterationSpaceChecker::buildOrderedLoopData(
8969 Scope
*S
, Expr
*Counter
,
8970 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
, SourceLocation Loc
,
8971 Expr
*Inc
, OverloadedOperatorKind OOK
) {
8972 Expr
*Cnt
= SemaRef
.DefaultLvalueConversion(Counter
).get();
8976 assert((OOK
== OO_Plus
|| OOK
== OO_Minus
) &&
8977 "Expected only + or - operations for depend clauses.");
8978 BinaryOperatorKind BOK
= (OOK
== OO_Plus
) ? BO_Add
: BO_Sub
;
8979 Cnt
= SemaRef
.BuildBinOp(S
, Loc
, BOK
, Cnt
, Inc
).get();
8983 QualType VarType
= LCDecl
->getType().getNonReferenceType();
8984 if (!VarType
->isIntegerType() && !VarType
->isPointerType() &&
8985 !SemaRef
.getLangOpts().CPlusPlus
)
8989 TestIsLessOp
.value() ? Cnt
: tryBuildCapture(SemaRef
, LB
, Captures
).get();
8991 TestIsLessOp
.value() ? tryBuildCapture(SemaRef
, LB
, Captures
).get() : Cnt
;
8992 if (!Upper
|| !Lower
)
8995 ExprResult Diff
= calculateNumIters(
8996 SemaRef
, S
, DefaultLoc
, Lower
, Upper
, Step
, VarType
,
8997 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures
);
8998 if (!Diff
.isUsable())
9005 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc
, Stmt
*Init
) {
9006 assert(getLangOpts().OpenMP
&& "OpenMP is not active.");
9007 assert(Init
&& "Expected loop in canonical form.");
9008 unsigned AssociatedLoops
= DSAStack
->getAssociatedLoops();
9009 if (AssociatedLoops
> 0 &&
9010 isOpenMPLoopDirective(DSAStack
->getCurrentDirective())) {
9011 DSAStack
->loopStart();
9012 OpenMPIterationSpaceChecker
ISC(*this, /*SupportsNonRectangular=*/true,
9014 if (!ISC
.checkAndSetInit(Init
, /*EmitDiags=*/false)) {
9015 if (ValueDecl
*D
= ISC
.getLoopDecl()) {
9016 auto *VD
= dyn_cast
<VarDecl
>(D
);
9017 DeclRefExpr
*PrivateRef
= nullptr;
9019 if (VarDecl
*Private
= isOpenMPCapturedDecl(D
)) {
9022 PrivateRef
= buildCapture(*this, D
, ISC
.getLoopDeclRefExpr(),
9023 /*WithInit=*/false);
9024 VD
= cast
<VarDecl
>(PrivateRef
->getDecl());
9027 DSAStack
->addLoopControlVariable(D
, VD
);
9028 const Decl
*LD
= DSAStack
->getPossiblyLoopCunter();
9029 if (LD
!= D
->getCanonicalDecl()) {
9030 DSAStack
->resetPossibleLoopCounter();
9031 if (auto *Var
= dyn_cast_or_null
<VarDecl
>(LD
))
9032 MarkDeclarationsReferencedInExpr(
9033 buildDeclRefExpr(*this, const_cast<VarDecl
*>(Var
),
9034 Var
->getType().getNonLValueExprType(Context
),
9035 ForLoc
, /*RefersToCapture=*/true));
9037 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
9038 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9039 // Referenced in a Construct, C/C++]. The loop iteration variable in the
9040 // associated for-loop of a simd construct with just one associated
9041 // for-loop may be listed in a linear clause with a constant-linear-step
9042 // that is the increment of the associated for-loop. The loop iteration
9043 // variable(s) in the associated for-loop(s) of a for or parallel for
9044 // construct may be listed in a private or lastprivate clause.
9045 DSAStackTy::DSAVarData DVar
=
9046 DSAStack
->getTopDSA(D
, /*FromParent=*/false);
9047 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9048 // is declared in the loop and it is predetermined as a private.
9049 Expr
*LoopDeclRefExpr
= ISC
.getLoopDeclRefExpr();
9050 OpenMPClauseKind PredeterminedCKind
=
9051 isOpenMPSimdDirective(DKind
)
9052 ? (DSAStack
->hasMutipleLoops() ? OMPC_lastprivate
: OMPC_linear
)
9054 if (((isOpenMPSimdDirective(DKind
) && DVar
.CKind
!= OMPC_unknown
&&
9055 DVar
.CKind
!= PredeterminedCKind
&& DVar
.RefExpr
&&
9056 (LangOpts
.OpenMP
<= 45 || (DVar
.CKind
!= OMPC_lastprivate
&&
9057 DVar
.CKind
!= OMPC_private
))) ||
9058 ((isOpenMPWorksharingDirective(DKind
) || DKind
== OMPD_taskloop
||
9059 DKind
== OMPD_master_taskloop
|| DKind
== OMPD_masked_taskloop
||
9060 DKind
== OMPD_parallel_master_taskloop
||
9061 DKind
== OMPD_parallel_masked_taskloop
||
9062 isOpenMPDistributeDirective(DKind
)) &&
9063 !isOpenMPSimdDirective(DKind
) && DVar
.CKind
!= OMPC_unknown
&&
9064 DVar
.CKind
!= OMPC_private
&& DVar
.CKind
!= OMPC_lastprivate
)) &&
9065 (DVar
.CKind
!= OMPC_private
|| DVar
.RefExpr
)) {
9066 Diag(Init
->getBeginLoc(), diag::err_omp_loop_var_dsa
)
9067 << getOpenMPClauseName(DVar
.CKind
)
9068 << getOpenMPDirectiveName(DKind
)
9069 << getOpenMPClauseName(PredeterminedCKind
);
9070 if (DVar
.RefExpr
== nullptr)
9071 DVar
.CKind
= PredeterminedCKind
;
9072 reportOriginalDsa(*this, DSAStack
, D
, DVar
,
9073 /*IsLoopIterVar=*/true);
9074 } else if (LoopDeclRefExpr
) {
9075 // Make the loop iteration variable private (for worksharing
9076 // constructs), linear (for simd directives with the only one
9077 // associated loop) or lastprivate (for simd directives with several
9078 // collapsed or ordered loops).
9079 if (DVar
.CKind
== OMPC_unknown
)
9080 DSAStack
->addDSA(D
, LoopDeclRefExpr
, PredeterminedCKind
,
9085 DSAStack
->setAssociatedLoops(AssociatedLoops
- 1);
9089 /// Called on a for stmt to check and extract its iteration space
9090 /// for further processing (such as collapsing).
9091 static bool checkOpenMPIterationSpace(
9092 OpenMPDirectiveKind DKind
, Stmt
*S
, Sema
&SemaRef
, DSAStackTy
&DSA
,
9093 unsigned CurrentNestedLoopCount
, unsigned NestedLoopCount
,
9094 unsigned TotalNestedLoopCount
, Expr
*CollapseLoopCountExpr
,
9095 Expr
*OrderedLoopCountExpr
,
9096 Sema::VarsWithInheritedDSAType
&VarsWithImplicitDSA
,
9097 llvm::MutableArrayRef
<LoopIterationSpace
> ResultIterSpaces
,
9098 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) {
9099 bool SupportsNonRectangular
= !isOpenMPLoopTransformationDirective(DKind
);
9100 // OpenMP [2.9.1, Canonical Loop Form]
9101 // for (init-expr; test-expr; incr-expr) structured-block
9102 // for (range-decl: range-expr) structured-block
9103 if (auto *CanonLoop
= dyn_cast_or_null
<OMPCanonicalLoop
>(S
))
9104 S
= CanonLoop
->getLoopStmt();
9105 auto *For
= dyn_cast_or_null
<ForStmt
>(S
);
9106 auto *CXXFor
= dyn_cast_or_null
<CXXForRangeStmt
>(S
);
9107 // Ranged for is supported only in OpenMP 5.0.
9108 if (!For
&& (SemaRef
.LangOpts
.OpenMP
<= 45 || !CXXFor
)) {
9109 SemaRef
.Diag(S
->getBeginLoc(), diag::err_omp_not_for
)
9110 << (CollapseLoopCountExpr
!= nullptr || OrderedLoopCountExpr
!= nullptr)
9111 << getOpenMPDirectiveName(DKind
) << TotalNestedLoopCount
9112 << (CurrentNestedLoopCount
> 0) << CurrentNestedLoopCount
;
9113 if (TotalNestedLoopCount
> 1) {
9114 if (CollapseLoopCountExpr
&& OrderedLoopCountExpr
)
9115 SemaRef
.Diag(DSA
.getConstructLoc(),
9116 diag::note_omp_collapse_ordered_expr
)
9117 << 2 << CollapseLoopCountExpr
->getSourceRange()
9118 << OrderedLoopCountExpr
->getSourceRange();
9119 else if (CollapseLoopCountExpr
)
9120 SemaRef
.Diag(CollapseLoopCountExpr
->getExprLoc(),
9121 diag::note_omp_collapse_ordered_expr
)
9122 << 0 << CollapseLoopCountExpr
->getSourceRange();
9124 SemaRef
.Diag(OrderedLoopCountExpr
->getExprLoc(),
9125 diag::note_omp_collapse_ordered_expr
)
9126 << 1 << OrderedLoopCountExpr
->getSourceRange();
9130 assert(((For
&& For
->getBody()) || (CXXFor
&& CXXFor
->getBody())) &&
9132 // Postpone analysis in dependent contexts for ranged for loops.
9133 if (CXXFor
&& SemaRef
.CurContext
->isDependentContext())
9136 OpenMPIterationSpaceChecker
ISC(SemaRef
, SupportsNonRectangular
, DSA
,
9137 For
? For
->getForLoc() : CXXFor
->getForLoc());
9140 Stmt
*Init
= For
? For
->getInit() : CXXFor
->getBeginStmt();
9141 if (ISC
.checkAndSetInit(Init
))
9144 bool HasErrors
= false;
9146 // Check loop variable's type.
9147 if (ValueDecl
*LCDecl
= ISC
.getLoopDecl()) {
9148 // OpenMP [2.6, Canonical Loop Form]
9149 // Var is one of the following:
9150 // A variable of signed or unsigned integer type.
9151 // For C++, a variable of a random access iterator type.
9152 // For C, a variable of a pointer type.
9153 QualType VarType
= LCDecl
->getType().getNonReferenceType();
9154 if (!VarType
->isDependentType() && !VarType
->isIntegerType() &&
9155 !VarType
->isPointerType() &&
9156 !(SemaRef
.getLangOpts().CPlusPlus
&& VarType
->isOverloadableType())) {
9157 SemaRef
.Diag(Init
->getBeginLoc(), diag::err_omp_loop_variable_type
)
9158 << SemaRef
.getLangOpts().CPlusPlus
;
9162 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9164 // The loop iteration variable(s) in the associated for-loop(s) of a for or
9165 // parallel for construct is (are) private.
9166 // The loop iteration variable in the associated for-loop of a simd
9167 // construct with just one associated for-loop is linear with a
9168 // constant-linear-step that is the increment of the associated for-loop.
9169 // Exclude loop var from the list of variables with implicitly defined data
9170 // sharing attributes.
9171 VarsWithImplicitDSA
.erase(LCDecl
);
9173 assert(isOpenMPLoopDirective(DKind
) && "DSA for non-loop vars");
9176 HasErrors
|= ISC
.checkAndSetCond(For
? For
->getCond() : CXXFor
->getCond());
9179 HasErrors
|= ISC
.checkAndSetInc(For
? For
->getInc() : CXXFor
->getInc());
9182 if (ISC
.dependent() || SemaRef
.CurContext
->isDependentContext() || HasErrors
)
9185 // Build the loop's iteration space representation.
9186 ResultIterSpaces
[CurrentNestedLoopCount
].PreCond
= ISC
.buildPreCond(
9187 DSA
.getCurScope(), For
? For
->getCond() : CXXFor
->getCond(), Captures
);
9188 ResultIterSpaces
[CurrentNestedLoopCount
].NumIterations
=
9189 ISC
.buildNumIterations(DSA
.getCurScope(), ResultIterSpaces
,
9190 (isOpenMPWorksharingDirective(DKind
) ||
9191 isOpenMPGenericLoopDirective(DKind
) ||
9192 isOpenMPTaskLoopDirective(DKind
) ||
9193 isOpenMPDistributeDirective(DKind
) ||
9194 isOpenMPLoopTransformationDirective(DKind
)),
9196 ResultIterSpaces
[CurrentNestedLoopCount
].CounterVar
=
9197 ISC
.buildCounterVar(Captures
, DSA
);
9198 ResultIterSpaces
[CurrentNestedLoopCount
].PrivateCounterVar
=
9199 ISC
.buildPrivateCounterVar();
9200 ResultIterSpaces
[CurrentNestedLoopCount
].CounterInit
= ISC
.buildCounterInit();
9201 ResultIterSpaces
[CurrentNestedLoopCount
].CounterStep
= ISC
.buildCounterStep();
9202 ResultIterSpaces
[CurrentNestedLoopCount
].InitSrcRange
= ISC
.getInitSrcRange();
9203 ResultIterSpaces
[CurrentNestedLoopCount
].CondSrcRange
=
9204 ISC
.getConditionSrcRange();
9205 ResultIterSpaces
[CurrentNestedLoopCount
].IncSrcRange
=
9206 ISC
.getIncrementSrcRange();
9207 ResultIterSpaces
[CurrentNestedLoopCount
].Subtract
= ISC
.shouldSubtractStep();
9208 ResultIterSpaces
[CurrentNestedLoopCount
].IsStrictCompare
=
9209 ISC
.isStrictTestOp();
9210 std::tie(ResultIterSpaces
[CurrentNestedLoopCount
].MinValue
,
9211 ResultIterSpaces
[CurrentNestedLoopCount
].MaxValue
) =
9212 ISC
.buildMinMaxValues(DSA
.getCurScope(), Captures
);
9213 ResultIterSpaces
[CurrentNestedLoopCount
].FinalCondition
=
9214 ISC
.buildFinalCondition(DSA
.getCurScope());
9215 ResultIterSpaces
[CurrentNestedLoopCount
].IsNonRectangularLB
=
9216 ISC
.doesInitDependOnLC();
9217 ResultIterSpaces
[CurrentNestedLoopCount
].IsNonRectangularUB
=
9218 ISC
.doesCondDependOnLC();
9219 ResultIterSpaces
[CurrentNestedLoopCount
].LoopDependentIdx
=
9220 ISC
.getLoopDependentIdx();
9223 (ResultIterSpaces
[CurrentNestedLoopCount
].PreCond
== nullptr ||
9224 ResultIterSpaces
[CurrentNestedLoopCount
].NumIterations
== nullptr ||
9225 ResultIterSpaces
[CurrentNestedLoopCount
].CounterVar
== nullptr ||
9226 ResultIterSpaces
[CurrentNestedLoopCount
].PrivateCounterVar
== nullptr ||
9227 ResultIterSpaces
[CurrentNestedLoopCount
].CounterInit
== nullptr ||
9228 ResultIterSpaces
[CurrentNestedLoopCount
].CounterStep
== nullptr);
9229 if (!HasErrors
&& DSA
.isOrderedRegion()) {
9230 if (DSA
.getOrderedRegionParam().second
->getNumForLoops()) {
9231 if (CurrentNestedLoopCount
<
9232 DSA
.getOrderedRegionParam().second
->getLoopNumIterations().size()) {
9233 DSA
.getOrderedRegionParam().second
->setLoopNumIterations(
9234 CurrentNestedLoopCount
,
9235 ResultIterSpaces
[CurrentNestedLoopCount
].NumIterations
);
9236 DSA
.getOrderedRegionParam().second
->setLoopCounter(
9237 CurrentNestedLoopCount
,
9238 ResultIterSpaces
[CurrentNestedLoopCount
].CounterVar
);
9241 for (auto &Pair
: DSA
.getDoacrossDependClauses()) {
9242 if (CurrentNestedLoopCount
>= Pair
.first
->getNumLoops()) {
9243 // Erroneous case - clause has some problems.
9246 if (Pair
.first
->getDependencyKind() == OMPC_DEPEND_sink
&&
9247 Pair
.second
.size() <= CurrentNestedLoopCount
) {
9248 // Erroneous case - clause has some problems.
9249 Pair
.first
->setLoopData(CurrentNestedLoopCount
, nullptr);
9253 if (Pair
.first
->getDependencyKind() == OMPC_DEPEND_source
)
9254 CntValue
= ISC
.buildOrderedLoopData(
9256 ResultIterSpaces
[CurrentNestedLoopCount
].CounterVar
, Captures
,
9257 Pair
.first
->getDependencyLoc());
9259 CntValue
= ISC
.buildOrderedLoopData(
9261 ResultIterSpaces
[CurrentNestedLoopCount
].CounterVar
, Captures
,
9262 Pair
.first
->getDependencyLoc(),
9263 Pair
.second
[CurrentNestedLoopCount
].first
,
9264 Pair
.second
[CurrentNestedLoopCount
].second
);
9265 Pair
.first
->setLoopData(CurrentNestedLoopCount
, CntValue
);
9272 /// Build 'VarRef = Start.
9274 buildCounterInit(Sema
&SemaRef
, Scope
*S
, SourceLocation Loc
, ExprResult VarRef
,
9275 ExprResult Start
, bool IsNonRectangularLB
,
9276 llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) {
9277 // Build 'VarRef = Start.
9278 ExprResult NewStart
= IsNonRectangularLB
9280 : tryBuildCapture(SemaRef
, Start
.get(), Captures
);
9281 if (!NewStart
.isUsable())
9283 if (!SemaRef
.Context
.hasSameType(NewStart
.get()->getType(),
9284 VarRef
.get()->getType())) {
9285 NewStart
= SemaRef
.PerformImplicitConversion(
9286 NewStart
.get(), VarRef
.get()->getType(), Sema::AA_Converting
,
9287 /*AllowExplicit=*/true);
9288 if (!NewStart
.isUsable())
9293 SemaRef
.BuildBinOp(S
, Loc
, BO_Assign
, VarRef
.get(), NewStart
.get());
9297 /// Build 'VarRef = Start + Iter * Step'.
9298 static ExprResult
buildCounterUpdate(
9299 Sema
&SemaRef
, Scope
*S
, SourceLocation Loc
, ExprResult VarRef
,
9300 ExprResult Start
, ExprResult Iter
, ExprResult Step
, bool Subtract
,
9301 bool IsNonRectangularLB
,
9302 llvm::MapVector
<const Expr
*, DeclRefExpr
*> *Captures
= nullptr) {
9303 // Add parentheses (for debugging purposes only).
9304 Iter
= SemaRef
.ActOnParenExpr(Loc
, Loc
, Iter
.get());
9305 if (!VarRef
.isUsable() || !Start
.isUsable() || !Iter
.isUsable() ||
9309 ExprResult NewStep
= Step
;
9311 NewStep
= tryBuildCapture(SemaRef
, Step
.get(), *Captures
);
9312 if (NewStep
.isInvalid())
9315 SemaRef
.BuildBinOp(S
, Loc
, BO_Mul
, Iter
.get(), NewStep
.get());
9316 if (!Update
.isUsable())
9319 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9320 // 'VarRef = Start (+|-) Iter * Step'.
9321 if (!Start
.isUsable())
9323 ExprResult NewStart
= SemaRef
.ActOnParenExpr(Loc
, Loc
, Start
.get());
9324 if (!NewStart
.isUsable())
9326 if (Captures
&& !IsNonRectangularLB
)
9327 NewStart
= tryBuildCapture(SemaRef
, Start
.get(), *Captures
);
9328 if (NewStart
.isInvalid())
9331 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9332 ExprResult SavedUpdate
= Update
;
9333 ExprResult UpdateVal
;
9334 if (VarRef
.get()->getType()->isOverloadableType() ||
9335 NewStart
.get()->getType()->isOverloadableType() ||
9336 Update
.get()->getType()->isOverloadableType()) {
9337 Sema::TentativeAnalysisScope
Trap(SemaRef
);
9340 SemaRef
.BuildBinOp(S
, Loc
, BO_Assign
, VarRef
.get(), NewStart
.get());
9341 if (Update
.isUsable()) {
9343 SemaRef
.BuildBinOp(S
, Loc
, Subtract
? BO_SubAssign
: BO_AddAssign
,
9344 VarRef
.get(), SavedUpdate
.get());
9345 if (UpdateVal
.isUsable()) {
9346 Update
= SemaRef
.CreateBuiltinBinOp(Loc
, BO_Comma
, Update
.get(),
9352 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9353 if (!Update
.isUsable() || !UpdateVal
.isUsable()) {
9354 Update
= SemaRef
.BuildBinOp(S
, Loc
, Subtract
? BO_Sub
: BO_Add
,
9355 NewStart
.get(), SavedUpdate
.get());
9356 if (!Update
.isUsable())
9359 if (!SemaRef
.Context
.hasSameType(Update
.get()->getType(),
9360 VarRef
.get()->getType())) {
9361 Update
= SemaRef
.PerformImplicitConversion(
9362 Update
.get(), VarRef
.get()->getType(), Sema::AA_Converting
, true);
9363 if (!Update
.isUsable())
9367 Update
= SemaRef
.BuildBinOp(S
, Loc
, BO_Assign
, VarRef
.get(), Update
.get());
9372 /// Convert integer expression \a E to make it have at least \a Bits
9374 static ExprResult
widenIterationCount(unsigned Bits
, Expr
*E
, Sema
&SemaRef
) {
9377 ASTContext
&C
= SemaRef
.Context
;
9378 QualType OldType
= E
->getType();
9379 unsigned HasBits
= C
.getTypeSize(OldType
);
9380 if (HasBits
>= Bits
)
9381 return ExprResult(E
);
9382 // OK to convert to signed, because new type has more bits than old.
9383 QualType NewType
= C
.getIntTypeForBitwidth(Bits
, /* Signed */ true);
9384 return SemaRef
.PerformImplicitConversion(E
, NewType
, Sema::AA_Converting
,
9388 /// Check if the given expression \a E is a constant integer that fits
9389 /// into \a Bits bits.
9390 static bool fitsInto(unsigned Bits
, bool Signed
, const Expr
*E
, Sema
&SemaRef
) {
9393 if (Optional
<llvm::APSInt
> Result
=
9394 E
->getIntegerConstantExpr(SemaRef
.Context
))
9395 return Signed
? Result
->isSignedIntN(Bits
) : Result
->isIntN(Bits
);
9399 /// Build preinits statement for the given declarations.
9400 static Stmt
*buildPreInits(ASTContext
&Context
,
9401 MutableArrayRef
<Decl
*> PreInits
) {
9402 if (!PreInits
.empty()) {
9403 return new (Context
) DeclStmt(
9404 DeclGroupRef::Create(Context
, PreInits
.begin(), PreInits
.size()),
9405 SourceLocation(), SourceLocation());
9410 /// Build preinits statement for the given declarations.
9412 buildPreInits(ASTContext
&Context
,
9413 const llvm::MapVector
<const Expr
*, DeclRefExpr
*> &Captures
) {
9414 if (!Captures
.empty()) {
9415 SmallVector
<Decl
*, 16> PreInits
;
9416 for (const auto &Pair
: Captures
)
9417 PreInits
.push_back(Pair
.second
->getDecl());
9418 return buildPreInits(Context
, PreInits
);
9423 /// Build postupdate expression for the given list of postupdates expressions.
9424 static Expr
*buildPostUpdate(Sema
&S
, ArrayRef
<Expr
*> PostUpdates
) {
9425 Expr
*PostUpdate
= nullptr;
9426 if (!PostUpdates
.empty()) {
9427 for (Expr
*E
: PostUpdates
) {
9428 Expr
*ConvE
= S
.BuildCStyleCastExpr(
9430 S
.Context
.getTrivialTypeSourceInfo(S
.Context
.VoidTy
),
9433 PostUpdate
= PostUpdate
9434 ? S
.CreateBuiltinBinOp(ConvE
->getExprLoc(), BO_Comma
,
9443 /// Called on a for stmt to check itself and nested loops (if any).
9444 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9445 /// number of collapsed loops otherwise.
9447 checkOpenMPLoop(OpenMPDirectiveKind DKind
, Expr
*CollapseLoopCountExpr
,
9448 Expr
*OrderedLoopCountExpr
, Stmt
*AStmt
, Sema
&SemaRef
,
9450 Sema::VarsWithInheritedDSAType
&VarsWithImplicitDSA
,
9451 OMPLoopBasedDirective::HelperExprs
&Built
) {
9452 unsigned NestedLoopCount
= 1;
9453 bool SupportsNonPerfectlyNested
= (SemaRef
.LangOpts
.OpenMP
>= 50) &&
9454 !isOpenMPLoopTransformationDirective(DKind
);
9456 if (CollapseLoopCountExpr
) {
9457 // Found 'collapse' clause - calculate collapse number.
9458 Expr::EvalResult Result
;
9459 if (!CollapseLoopCountExpr
->isValueDependent() &&
9460 CollapseLoopCountExpr
->EvaluateAsInt(Result
, SemaRef
.getASTContext())) {
9461 NestedLoopCount
= Result
.Val
.getInt().getLimitedValue();
9463 Built
.clear(/*Size=*/1);
9467 unsigned OrderedLoopCount
= 1;
9468 if (OrderedLoopCountExpr
) {
9469 // Found 'ordered' clause - calculate collapse number.
9470 Expr::EvalResult EVResult
;
9471 if (!OrderedLoopCountExpr
->isValueDependent() &&
9472 OrderedLoopCountExpr
->EvaluateAsInt(EVResult
,
9473 SemaRef
.getASTContext())) {
9474 llvm::APSInt Result
= EVResult
.Val
.getInt();
9475 if (Result
.getLimitedValue() < NestedLoopCount
) {
9476 SemaRef
.Diag(OrderedLoopCountExpr
->getExprLoc(),
9477 diag::err_omp_wrong_ordered_loop_count
)
9478 << OrderedLoopCountExpr
->getSourceRange();
9479 SemaRef
.Diag(CollapseLoopCountExpr
->getExprLoc(),
9480 diag::note_collapse_loop_count
)
9481 << CollapseLoopCountExpr
->getSourceRange();
9483 OrderedLoopCount
= Result
.getLimitedValue();
9485 Built
.clear(/*Size=*/1);
9489 // This is helper routine for loop directives (e.g., 'for', 'simd',
9490 // 'for simd', etc.).
9491 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
9492 unsigned NumLoops
= std::max(OrderedLoopCount
, NestedLoopCount
);
9493 SmallVector
<LoopIterationSpace
, 4> IterSpaces(NumLoops
);
9494 if (!OMPLoopBasedDirective::doForAllLoops(
9495 AStmt
->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind
)),
9496 SupportsNonPerfectlyNested
, NumLoops
,
9497 [DKind
, &SemaRef
, &DSA
, NumLoops
, NestedLoopCount
,
9498 CollapseLoopCountExpr
, OrderedLoopCountExpr
, &VarsWithImplicitDSA
,
9499 &IterSpaces
, &Captures
](unsigned Cnt
, Stmt
*CurStmt
) {
9500 if (checkOpenMPIterationSpace(
9501 DKind
, CurStmt
, SemaRef
, DSA
, Cnt
, NestedLoopCount
,
9502 NumLoops
, CollapseLoopCountExpr
, OrderedLoopCountExpr
,
9503 VarsWithImplicitDSA
, IterSpaces
, Captures
))
9505 if (Cnt
> 0 && Cnt
>= NestedLoopCount
&&
9506 IterSpaces
[Cnt
].CounterVar
) {
9507 // Handle initialization of captured loop iterator variables.
9508 auto *DRE
= cast
<DeclRefExpr
>(IterSpaces
[Cnt
].CounterVar
);
9509 if (isa
<OMPCapturedExprDecl
>(DRE
->getDecl())) {
9510 Captures
[DRE
] = DRE
;
9515 [&SemaRef
, &Captures
](OMPLoopTransformationDirective
*Transform
) {
9516 Stmt
*DependentPreInits
= Transform
->getPreInits();
9517 if (!DependentPreInits
)
9519 for (Decl
*C
: cast
<DeclStmt
>(DependentPreInits
)->getDeclGroup()) {
9520 auto *D
= cast
<VarDecl
>(C
);
9521 DeclRefExpr
*Ref
= buildDeclRefExpr(SemaRef
, D
, D
->getType(),
9522 Transform
->getBeginLoc());
9523 Captures
[Ref
] = Ref
;
9528 Built
.clear(/* size */ NestedLoopCount
);
9530 if (SemaRef
.CurContext
->isDependentContext())
9531 return NestedLoopCount
;
9533 // An example of what is generated for the following code:
9535 // #pragma omp simd collapse(2) ordered(2)
9536 // for (i = 0; i < NI; ++i)
9537 // for (k = 0; k < NK; ++k)
9538 // for (j = J0; j < NJ; j+=2) {
9542 // We generate the code below.
9543 // Note: the loop body may be outlined in CodeGen.
9544 // Note: some counters may be C++ classes, operator- is used to find number of
9545 // iterations and operator+= to calculate counter value.
9546 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9547 // or i64 is currently supported).
9549 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9550 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9551 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9552 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9553 // // similar updates for vars in clauses (e.g. 'linear')
9554 // <loop body (using local i and j)>
9556 // i = NI; // assign final values of counters
9560 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9561 // the iteration counts of the collapsed for loops.
9562 // Precondition tests if there is at least one iteration (all conditions are
9564 auto PreCond
= ExprResult(IterSpaces
[0].PreCond
);
9565 Expr
*N0
= IterSpaces
[0].NumIterations
;
9566 ExprResult LastIteration32
=
9567 widenIterationCount(/*Bits=*/32,
9569 .PerformImplicitConversion(
9570 N0
->IgnoreImpCasts(), N0
->getType(),
9571 Sema::AA_Converting
, /*AllowExplicit=*/true)
9574 ExprResult LastIteration64
= widenIterationCount(
9577 .PerformImplicitConversion(N0
->IgnoreImpCasts(), N0
->getType(),
9578 Sema::AA_Converting
,
9579 /*AllowExplicit=*/true)
9583 if (!LastIteration32
.isUsable() || !LastIteration64
.isUsable())
9584 return NestedLoopCount
;
9586 ASTContext
&C
= SemaRef
.Context
;
9587 bool AllCountsNeedLessThan32Bits
= C
.getTypeSize(N0
->getType()) < 32;
9589 Scope
*CurScope
= DSA
.getCurScope();
9590 for (unsigned Cnt
= 1; Cnt
< NestedLoopCount
; ++Cnt
) {
9591 if (PreCond
.isUsable()) {
9593 SemaRef
.BuildBinOp(CurScope
, PreCond
.get()->getExprLoc(), BO_LAnd
,
9594 PreCond
.get(), IterSpaces
[Cnt
].PreCond
);
9596 Expr
*N
= IterSpaces
[Cnt
].NumIterations
;
9597 SourceLocation Loc
= N
->getExprLoc();
9598 AllCountsNeedLessThan32Bits
&= C
.getTypeSize(N
->getType()) < 32;
9599 if (LastIteration32
.isUsable())
9600 LastIteration32
= SemaRef
.BuildBinOp(
9601 CurScope
, Loc
, BO_Mul
, LastIteration32
.get(),
9603 .PerformImplicitConversion(N
->IgnoreImpCasts(), N
->getType(),
9604 Sema::AA_Converting
,
9605 /*AllowExplicit=*/true)
9607 if (LastIteration64
.isUsable())
9608 LastIteration64
= SemaRef
.BuildBinOp(
9609 CurScope
, Loc
, BO_Mul
, LastIteration64
.get(),
9611 .PerformImplicitConversion(N
->IgnoreImpCasts(), N
->getType(),
9612 Sema::AA_Converting
,
9613 /*AllowExplicit=*/true)
9617 // Choose either the 32-bit or 64-bit version.
9618 ExprResult LastIteration
= LastIteration64
;
9619 if (SemaRef
.getLangOpts().OpenMPOptimisticCollapse
||
9620 (LastIteration32
.isUsable() &&
9621 C
.getTypeSize(LastIteration32
.get()->getType()) == 32 &&
9622 (AllCountsNeedLessThan32Bits
|| NestedLoopCount
== 1 ||
9625 LastIteration32
.get()->getType()->hasSignedIntegerRepresentation(),
9626 LastIteration64
.get(), SemaRef
))))
9627 LastIteration
= LastIteration32
;
9628 QualType VType
= LastIteration
.get()->getType();
9629 QualType RealVType
= VType
;
9630 QualType StrideVType
= VType
;
9631 if (isOpenMPTaskLoopDirective(DKind
)) {
9633 SemaRef
.Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9635 SemaRef
.Context
.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9638 if (!LastIteration
.isUsable())
9641 // Save the number of iterations.
9642 ExprResult NumIterations
= LastIteration
;
9644 LastIteration
= SemaRef
.BuildBinOp(
9645 CurScope
, LastIteration
.get()->getExprLoc(), BO_Sub
,
9646 LastIteration
.get(),
9647 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get());
9648 if (!LastIteration
.isUsable())
9652 // Calculate the last iteration number beforehand instead of doing this on
9653 // each iteration. Do not do this if the number of iterations may be kfold-ed.
9654 bool IsConstant
= LastIteration
.get()->isIntegerConstantExpr(SemaRef
.Context
);
9655 ExprResult CalcLastIteration
;
9657 ExprResult SaveRef
=
9658 tryBuildCapture(SemaRef
, LastIteration
.get(), Captures
);
9659 LastIteration
= SaveRef
;
9661 // Prepare SaveRef + 1.
9662 NumIterations
= SemaRef
.BuildBinOp(
9663 CurScope
, SaveRef
.get()->getExprLoc(), BO_Add
, SaveRef
.get(),
9664 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get());
9665 if (!NumIterations
.isUsable())
9669 SourceLocation InitLoc
= IterSpaces
[0].InitSrcRange
.getBegin();
9671 // Build variables passed into runtime, necessary for worksharing directives.
9672 ExprResult LB
, UB
, IL
, ST
, EUB
, CombLB
, CombUB
, PrevLB
, PrevUB
, CombEUB
;
9673 if (isOpenMPWorksharingDirective(DKind
) || isOpenMPTaskLoopDirective(DKind
) ||
9674 isOpenMPDistributeDirective(DKind
) ||
9675 isOpenMPGenericLoopDirective(DKind
) ||
9676 isOpenMPLoopTransformationDirective(DKind
)) {
9677 // Lower bound variable, initialized with zero.
9678 VarDecl
*LBDecl
= buildVarDecl(SemaRef
, InitLoc
, VType
, ".omp.lb");
9679 LB
= buildDeclRefExpr(SemaRef
, LBDecl
, VType
, InitLoc
);
9680 SemaRef
.AddInitializerToDecl(LBDecl
,
9681 SemaRef
.ActOnIntegerConstant(InitLoc
, 0).get(),
9682 /*DirectInit*/ false);
9684 // Upper bound variable, initialized with last iteration number.
9685 VarDecl
*UBDecl
= buildVarDecl(SemaRef
, InitLoc
, VType
, ".omp.ub");
9686 UB
= buildDeclRefExpr(SemaRef
, UBDecl
, VType
, InitLoc
);
9687 SemaRef
.AddInitializerToDecl(UBDecl
, LastIteration
.get(),
9688 /*DirectInit*/ false);
9690 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9691 // This will be used to implement clause 'lastprivate'.
9692 QualType Int32Ty
= SemaRef
.Context
.getIntTypeForBitwidth(32, true);
9693 VarDecl
*ILDecl
= buildVarDecl(SemaRef
, InitLoc
, Int32Ty
, ".omp.is_last");
9694 IL
= buildDeclRefExpr(SemaRef
, ILDecl
, Int32Ty
, InitLoc
);
9695 SemaRef
.AddInitializerToDecl(ILDecl
,
9696 SemaRef
.ActOnIntegerConstant(InitLoc
, 0).get(),
9697 /*DirectInit*/ false);
9699 // Stride variable returned by runtime (we initialize it to 1 by default).
9701 buildVarDecl(SemaRef
, InitLoc
, StrideVType
, ".omp.stride");
9702 ST
= buildDeclRefExpr(SemaRef
, STDecl
, StrideVType
, InitLoc
);
9703 SemaRef
.AddInitializerToDecl(STDecl
,
9704 SemaRef
.ActOnIntegerConstant(InitLoc
, 1).get(),
9705 /*DirectInit*/ false);
9707 // Build expression: UB = min(UB, LastIteration)
9708 // It is necessary for CodeGen of directives with static scheduling.
9709 ExprResult IsUBGreater
= SemaRef
.BuildBinOp(CurScope
, InitLoc
, BO_GT
,
9710 UB
.get(), LastIteration
.get());
9711 ExprResult CondOp
= SemaRef
.ActOnConditionalOp(
9712 LastIteration
.get()->getExprLoc(), InitLoc
, IsUBGreater
.get(),
9713 LastIteration
.get(), UB
.get());
9714 EUB
= SemaRef
.BuildBinOp(CurScope
, InitLoc
, BO_Assign
, UB
.get(),
9716 EUB
= SemaRef
.ActOnFinishFullExpr(EUB
.get(), /*DiscardedValue*/ false);
9718 // If we have a combined directive that combines 'distribute', 'for' or
9719 // 'simd' we need to be able to access the bounds of the schedule of the
9720 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9721 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9722 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9723 // Lower bound variable, initialized with zero.
9724 VarDecl
*CombLBDecl
=
9725 buildVarDecl(SemaRef
, InitLoc
, VType
, ".omp.comb.lb");
9726 CombLB
= buildDeclRefExpr(SemaRef
, CombLBDecl
, VType
, InitLoc
);
9727 SemaRef
.AddInitializerToDecl(
9728 CombLBDecl
, SemaRef
.ActOnIntegerConstant(InitLoc
, 0).get(),
9729 /*DirectInit*/ false);
9731 // Upper bound variable, initialized with last iteration number.
9732 VarDecl
*CombUBDecl
=
9733 buildVarDecl(SemaRef
, InitLoc
, VType
, ".omp.comb.ub");
9734 CombUB
= buildDeclRefExpr(SemaRef
, CombUBDecl
, VType
, InitLoc
);
9735 SemaRef
.AddInitializerToDecl(CombUBDecl
, LastIteration
.get(),
9736 /*DirectInit*/ false);
9738 ExprResult CombIsUBGreater
= SemaRef
.BuildBinOp(
9739 CurScope
, InitLoc
, BO_GT
, CombUB
.get(), LastIteration
.get());
9740 ExprResult CombCondOp
=
9741 SemaRef
.ActOnConditionalOp(InitLoc
, InitLoc
, CombIsUBGreater
.get(),
9742 LastIteration
.get(), CombUB
.get());
9743 CombEUB
= SemaRef
.BuildBinOp(CurScope
, InitLoc
, BO_Assign
, CombUB
.get(),
9746 SemaRef
.ActOnFinishFullExpr(CombEUB
.get(), /*DiscardedValue*/ false);
9748 const CapturedDecl
*CD
= cast
<CapturedStmt
>(AStmt
)->getCapturedDecl();
9749 // We expect to have at least 2 more parameters than the 'parallel'
9750 // directive does - the lower and upper bounds of the previous schedule.
9751 assert(CD
->getNumParams() >= 4 &&
9752 "Unexpected number of parameters in loop combined directive");
9754 // Set the proper type for the bounds given what we learned from the
9756 ImplicitParamDecl
*PrevLBDecl
= CD
->getParam(/*PrevLB=*/2);
9757 ImplicitParamDecl
*PrevUBDecl
= CD
->getParam(/*PrevUB=*/3);
9759 // Previous lower and upper bounds are obtained from the region
9762 buildDeclRefExpr(SemaRef
, PrevLBDecl
, PrevLBDecl
->getType(), InitLoc
);
9764 buildDeclRefExpr(SemaRef
, PrevUBDecl
, PrevUBDecl
->getType(), InitLoc
);
9768 // Build the iteration variable and its initialization before loop.
9770 ExprResult Init
, CombInit
;
9772 VarDecl
*IVDecl
= buildVarDecl(SemaRef
, InitLoc
, RealVType
, ".omp.iv");
9773 IV
= buildDeclRefExpr(SemaRef
, IVDecl
, RealVType
, InitLoc
);
9774 Expr
*RHS
= (isOpenMPWorksharingDirective(DKind
) ||
9775 isOpenMPGenericLoopDirective(DKind
) ||
9776 isOpenMPTaskLoopDirective(DKind
) ||
9777 isOpenMPDistributeDirective(DKind
) ||
9778 isOpenMPLoopTransformationDirective(DKind
))
9780 : SemaRef
.ActOnIntegerConstant(SourceLocation(), 0).get();
9781 Init
= SemaRef
.BuildBinOp(CurScope
, InitLoc
, BO_Assign
, IV
.get(), RHS
);
9782 Init
= SemaRef
.ActOnFinishFullExpr(Init
.get(), /*DiscardedValue*/ false);
9784 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9786 (isOpenMPWorksharingDirective(DKind
) ||
9787 isOpenMPGenericLoopDirective(DKind
) ||
9788 isOpenMPTaskLoopDirective(DKind
) ||
9789 isOpenMPDistributeDirective(DKind
))
9791 : SemaRef
.ActOnIntegerConstant(SourceLocation(), 0).get();
9793 SemaRef
.BuildBinOp(CurScope
, InitLoc
, BO_Assign
, IV
.get(), CombRHS
);
9795 SemaRef
.ActOnFinishFullExpr(CombInit
.get(), /*DiscardedValue*/ false);
9799 bool UseStrictCompare
=
9800 RealVType
->hasUnsignedIntegerRepresentation() &&
9801 llvm::all_of(IterSpaces
, [](const LoopIterationSpace
&LIS
) {
9802 return LIS
.IsStrictCompare
;
9804 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9805 // unsigned IV)) for worksharing loops.
9806 SourceLocation CondLoc
= AStmt
->getBeginLoc();
9807 Expr
*BoundUB
= UB
.get();
9808 if (UseStrictCompare
) {
9811 .BuildBinOp(CurScope
, CondLoc
, BO_Add
, BoundUB
,
9812 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get())
9815 SemaRef
.ActOnFinishFullExpr(BoundUB
, /*DiscardedValue*/ false).get();
9818 (isOpenMPWorksharingDirective(DKind
) ||
9819 isOpenMPGenericLoopDirective(DKind
) ||
9820 isOpenMPTaskLoopDirective(DKind
) || isOpenMPDistributeDirective(DKind
) ||
9821 isOpenMPLoopTransformationDirective(DKind
))
9822 ? SemaRef
.BuildBinOp(CurScope
, CondLoc
,
9823 UseStrictCompare
? BO_LT
: BO_LE
, IV
.get(),
9825 : SemaRef
.BuildBinOp(CurScope
, CondLoc
, BO_LT
, IV
.get(),
9826 NumIterations
.get());
9827 ExprResult CombDistCond
;
9828 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9829 CombDistCond
= SemaRef
.BuildBinOp(CurScope
, CondLoc
, BO_LT
, IV
.get(),
9830 NumIterations
.get());
9833 ExprResult CombCond
;
9834 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9835 Expr
*BoundCombUB
= CombUB
.get();
9836 if (UseStrictCompare
) {
9840 CurScope
, CondLoc
, BO_Add
, BoundCombUB
,
9841 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get())
9844 SemaRef
.ActOnFinishFullExpr(BoundCombUB
, /*DiscardedValue*/ false)
9848 SemaRef
.BuildBinOp(CurScope
, CondLoc
, UseStrictCompare
? BO_LT
: BO_LE
,
9849 IV
.get(), BoundCombUB
);
9851 // Loop increment (IV = IV + 1)
9852 SourceLocation IncLoc
= AStmt
->getBeginLoc();
9854 SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Add
, IV
.get(),
9855 SemaRef
.ActOnIntegerConstant(IncLoc
, 1).get());
9856 if (!Inc
.isUsable())
9858 Inc
= SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Assign
, IV
.get(), Inc
.get());
9859 Inc
= SemaRef
.ActOnFinishFullExpr(Inc
.get(), /*DiscardedValue*/ false);
9860 if (!Inc
.isUsable())
9863 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9864 // Used for directives with static scheduling.
9865 // In combined construct, add combined version that use CombLB and CombUB
9866 // base variables for the update
9867 ExprResult NextLB
, NextUB
, CombNextLB
, CombNextUB
;
9868 if (isOpenMPWorksharingDirective(DKind
) || isOpenMPTaskLoopDirective(DKind
) ||
9869 isOpenMPGenericLoopDirective(DKind
) ||
9870 isOpenMPDistributeDirective(DKind
) ||
9871 isOpenMPLoopTransformationDirective(DKind
)) {
9873 NextLB
= SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Add
, LB
.get(), ST
.get());
9874 if (!NextLB
.isUsable())
9878 SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Assign
, LB
.get(), NextLB
.get());
9880 SemaRef
.ActOnFinishFullExpr(NextLB
.get(), /*DiscardedValue*/ false);
9881 if (!NextLB
.isUsable())
9884 NextUB
= SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Add
, UB
.get(), ST
.get());
9885 if (!NextUB
.isUsable())
9889 SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Assign
, UB
.get(), NextUB
.get());
9891 SemaRef
.ActOnFinishFullExpr(NextUB
.get(), /*DiscardedValue*/ false);
9892 if (!NextUB
.isUsable())
9894 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9896 SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Add
, CombLB
.get(), ST
.get());
9897 if (!NextLB
.isUsable())
9900 CombNextLB
= SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Assign
, CombLB
.get(),
9902 CombNextLB
= SemaRef
.ActOnFinishFullExpr(CombNextLB
.get(),
9903 /*DiscardedValue*/ false);
9904 if (!CombNextLB
.isUsable())
9908 SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Add
, CombUB
.get(), ST
.get());
9909 if (!CombNextUB
.isUsable())
9912 CombNextUB
= SemaRef
.BuildBinOp(CurScope
, IncLoc
, BO_Assign
, CombUB
.get(),
9914 CombNextUB
= SemaRef
.ActOnFinishFullExpr(CombNextUB
.get(),
9915 /*DiscardedValue*/ false);
9916 if (!CombNextUB
.isUsable())
9921 // Create increment expression for distribute loop when combined in a same
9922 // directive with for as IV = IV + ST; ensure upper bound expression based
9923 // on PrevUB instead of NumIterations - used to implement 'for' when found
9924 // in combination with 'distribute', like in 'distribute parallel for'
9925 SourceLocation DistIncLoc
= AStmt
->getBeginLoc();
9926 ExprResult DistCond
, DistInc
, PrevEUB
, ParForInDistCond
;
9927 if (isOpenMPLoopBoundSharingDirective(DKind
)) {
9928 DistCond
= SemaRef
.BuildBinOp(
9929 CurScope
, CondLoc
, UseStrictCompare
? BO_LT
: BO_LE
, IV
.get(), BoundUB
);
9930 assert(DistCond
.isUsable() && "distribute cond expr was not built");
9933 SemaRef
.BuildBinOp(CurScope
, DistIncLoc
, BO_Add
, IV
.get(), ST
.get());
9934 assert(DistInc
.isUsable() && "distribute inc expr was not built");
9935 DistInc
= SemaRef
.BuildBinOp(CurScope
, DistIncLoc
, BO_Assign
, IV
.get(),
9938 SemaRef
.ActOnFinishFullExpr(DistInc
.get(), /*DiscardedValue*/ false);
9939 assert(DistInc
.isUsable() && "distribute inc expr was not built");
9941 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9943 ExprResult NewPrevUB
= PrevUB
;
9944 SourceLocation DistEUBLoc
= AStmt
->getBeginLoc();
9945 if (!SemaRef
.Context
.hasSameType(UB
.get()->getType(),
9946 PrevUB
.get()->getType())) {
9947 NewPrevUB
= SemaRef
.BuildCStyleCastExpr(
9949 SemaRef
.Context
.getTrivialTypeSourceInfo(UB
.get()->getType()),
9950 DistEUBLoc
, NewPrevUB
.get());
9951 if (!NewPrevUB
.isUsable())
9954 ExprResult IsUBGreater
= SemaRef
.BuildBinOp(CurScope
, DistEUBLoc
, BO_GT
,
9955 UB
.get(), NewPrevUB
.get());
9956 ExprResult CondOp
= SemaRef
.ActOnConditionalOp(
9957 DistEUBLoc
, DistEUBLoc
, IsUBGreater
.get(), NewPrevUB
.get(), UB
.get());
9958 PrevEUB
= SemaRef
.BuildBinOp(CurScope
, DistIncLoc
, BO_Assign
, UB
.get(),
9961 SemaRef
.ActOnFinishFullExpr(PrevEUB
.get(), /*DiscardedValue*/ false);
9963 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9964 // parallel for is in combination with a distribute directive with
9965 // schedule(static, 1)
9966 Expr
*BoundPrevUB
= PrevUB
.get();
9967 if (UseStrictCompare
) {
9971 CurScope
, CondLoc
, BO_Add
, BoundPrevUB
,
9972 SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get())
9975 SemaRef
.ActOnFinishFullExpr(BoundPrevUB
, /*DiscardedValue*/ false)
9979 SemaRef
.BuildBinOp(CurScope
, CondLoc
, UseStrictCompare
? BO_LT
: BO_LE
,
9980 IV
.get(), BoundPrevUB
);
9983 // Build updates and final values of the loop counters.
9984 bool HasErrors
= false;
9985 Built
.Counters
.resize(NestedLoopCount
);
9986 Built
.Inits
.resize(NestedLoopCount
);
9987 Built
.Updates
.resize(NestedLoopCount
);
9988 Built
.Finals
.resize(NestedLoopCount
);
9989 Built
.DependentCounters
.resize(NestedLoopCount
);
9990 Built
.DependentInits
.resize(NestedLoopCount
);
9991 Built
.FinalsConditions
.resize(NestedLoopCount
);
9993 // We implement the following algorithm for obtaining the
9994 // original loop iteration variable values based on the
9995 // value of the collapsed loop iteration variable IV.
9997 // Let n+1 be the number of collapsed loops in the nest.
9998 // Iteration variables (I0, I1, .... In)
9999 // Iteration counts (N0, N1, ... Nn)
10003 // To compute Ik for loop k, 0 <= k <= n, generate:
10004 // Prod = N(k+1) * N(k+2) * ... * Nn;
10005 // Ik = Acc / Prod;
10006 // Acc -= Ik * Prod;
10008 ExprResult Acc
= IV
;
10009 for (unsigned int Cnt
= 0; Cnt
< NestedLoopCount
; ++Cnt
) {
10010 LoopIterationSpace
&IS
= IterSpaces
[Cnt
];
10011 SourceLocation UpdLoc
= IS
.IncSrcRange
.getBegin();
10015 ExprResult Prod
= SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get();
10016 for (unsigned int K
= Cnt
+ 1; K
< NestedLoopCount
; ++K
)
10017 Prod
= SemaRef
.BuildBinOp(CurScope
, UpdLoc
, BO_Mul
, Prod
.get(),
10018 IterSpaces
[K
].NumIterations
);
10020 // Iter = Acc / Prod
10021 // If there is at least one more inner loop to avoid
10022 // multiplication by 1.
10023 if (Cnt
+ 1 < NestedLoopCount
)
10025 SemaRef
.BuildBinOp(CurScope
, UpdLoc
, BO_Div
, Acc
.get(), Prod
.get());
10028 if (!Iter
.isUsable()) {
10034 // Acc -= Iter * Prod
10035 // Check if there is at least one more inner loop to avoid
10036 // multiplication by 1.
10037 if (Cnt
+ 1 < NestedLoopCount
)
10038 Prod
= SemaRef
.BuildBinOp(CurScope
, UpdLoc
, BO_Mul
, Iter
.get(),
10042 Acc
= SemaRef
.BuildBinOp(CurScope
, UpdLoc
, BO_Sub
, Acc
.get(), Prod
.get());
10044 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10045 auto *VD
= cast
<VarDecl
>(cast
<DeclRefExpr
>(IS
.CounterVar
)->getDecl());
10046 DeclRefExpr
*CounterVar
= buildDeclRefExpr(
10047 SemaRef
, VD
, IS
.CounterVar
->getType(), IS
.CounterVar
->getExprLoc(),
10048 /*RefersToCapture=*/true);
10050 buildCounterInit(SemaRef
, CurScope
, UpdLoc
, CounterVar
,
10051 IS
.CounterInit
, IS
.IsNonRectangularLB
, Captures
);
10052 if (!Init
.isUsable()) {
10056 ExprResult Update
= buildCounterUpdate(
10057 SemaRef
, CurScope
, UpdLoc
, CounterVar
, IS
.CounterInit
, Iter
,
10058 IS
.CounterStep
, IS
.Subtract
, IS
.IsNonRectangularLB
, &Captures
);
10059 if (!Update
.isUsable()) {
10064 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10066 buildCounterUpdate(SemaRef
, CurScope
, UpdLoc
, CounterVar
,
10067 IS
.CounterInit
, IS
.NumIterations
, IS
.CounterStep
,
10068 IS
.Subtract
, IS
.IsNonRectangularLB
, &Captures
);
10069 if (!Final
.isUsable()) {
10074 if (!Update
.isUsable() || !Final
.isUsable()) {
10079 Built
.Counters
[Cnt
] = IS
.CounterVar
;
10080 Built
.PrivateCounters
[Cnt
] = IS
.PrivateCounterVar
;
10081 Built
.Inits
[Cnt
] = Init
.get();
10082 Built
.Updates
[Cnt
] = Update
.get();
10083 Built
.Finals
[Cnt
] = Final
.get();
10084 Built
.DependentCounters
[Cnt
] = nullptr;
10085 Built
.DependentInits
[Cnt
] = nullptr;
10086 Built
.FinalsConditions
[Cnt
] = nullptr;
10087 if (IS
.IsNonRectangularLB
|| IS
.IsNonRectangularUB
) {
10088 Built
.DependentCounters
[Cnt
] =
10089 Built
.Counters
[NestedLoopCount
- 1 - IS
.LoopDependentIdx
];
10090 Built
.DependentInits
[Cnt
] =
10091 Built
.Inits
[NestedLoopCount
- 1 - IS
.LoopDependentIdx
];
10092 Built
.FinalsConditions
[Cnt
] = IS
.FinalCondition
;
10101 Built
.IterationVarRef
= IV
.get();
10102 Built
.LastIteration
= LastIteration
.get();
10103 Built
.NumIterations
= NumIterations
.get();
10104 Built
.CalcLastIteration
= SemaRef
10105 .ActOnFinishFullExpr(CalcLastIteration
.get(),
10106 /*DiscardedValue=*/false)
10108 Built
.PreCond
= PreCond
.get();
10109 Built
.PreInits
= buildPreInits(C
, Captures
);
10110 Built
.Cond
= Cond
.get();
10111 Built
.Init
= Init
.get();
10112 Built
.Inc
= Inc
.get();
10113 Built
.LB
= LB
.get();
10114 Built
.UB
= UB
.get();
10115 Built
.IL
= IL
.get();
10116 Built
.ST
= ST
.get();
10117 Built
.EUB
= EUB
.get();
10118 Built
.NLB
= NextLB
.get();
10119 Built
.NUB
= NextUB
.get();
10120 Built
.PrevLB
= PrevLB
.get();
10121 Built
.PrevUB
= PrevUB
.get();
10122 Built
.DistInc
= DistInc
.get();
10123 Built
.PrevEUB
= PrevEUB
.get();
10124 Built
.DistCombinedFields
.LB
= CombLB
.get();
10125 Built
.DistCombinedFields
.UB
= CombUB
.get();
10126 Built
.DistCombinedFields
.EUB
= CombEUB
.get();
10127 Built
.DistCombinedFields
.Init
= CombInit
.get();
10128 Built
.DistCombinedFields
.Cond
= CombCond
.get();
10129 Built
.DistCombinedFields
.NLB
= CombNextLB
.get();
10130 Built
.DistCombinedFields
.NUB
= CombNextUB
.get();
10131 Built
.DistCombinedFields
.DistCond
= CombDistCond
.get();
10132 Built
.DistCombinedFields
.ParForInDistCond
= ParForInDistCond
.get();
10134 return NestedLoopCount
;
10137 static Expr
*getCollapseNumberExpr(ArrayRef
<OMPClause
*> Clauses
) {
10138 auto CollapseClauses
=
10139 OMPExecutableDirective::getClausesOfKind
<OMPCollapseClause
>(Clauses
);
10140 if (CollapseClauses
.begin() != CollapseClauses
.end())
10141 return (*CollapseClauses
.begin())->getNumForLoops();
10145 static Expr
*getOrderedNumberExpr(ArrayRef
<OMPClause
*> Clauses
) {
10146 auto OrderedClauses
=
10147 OMPExecutableDirective::getClausesOfKind
<OMPOrderedClause
>(Clauses
);
10148 if (OrderedClauses
.begin() != OrderedClauses
.end())
10149 return (*OrderedClauses
.begin())->getNumForLoops();
10153 static bool checkSimdlenSafelenSpecified(Sema
&S
,
10154 const ArrayRef
<OMPClause
*> Clauses
) {
10155 const OMPSafelenClause
*Safelen
= nullptr;
10156 const OMPSimdlenClause
*Simdlen
= nullptr;
10158 for (const OMPClause
*Clause
: Clauses
) {
10159 if (Clause
->getClauseKind() == OMPC_safelen
)
10160 Safelen
= cast
<OMPSafelenClause
>(Clause
);
10161 else if (Clause
->getClauseKind() == OMPC_simdlen
)
10162 Simdlen
= cast
<OMPSimdlenClause
>(Clause
);
10163 if (Safelen
&& Simdlen
)
10167 if (Simdlen
&& Safelen
) {
10168 const Expr
*SimdlenLength
= Simdlen
->getSimdlen();
10169 const Expr
*SafelenLength
= Safelen
->getSafelen();
10170 if (SimdlenLength
->isValueDependent() || SimdlenLength
->isTypeDependent() ||
10171 SimdlenLength
->isInstantiationDependent() ||
10172 SimdlenLength
->containsUnexpandedParameterPack())
10174 if (SafelenLength
->isValueDependent() || SafelenLength
->isTypeDependent() ||
10175 SafelenLength
->isInstantiationDependent() ||
10176 SafelenLength
->containsUnexpandedParameterPack())
10178 Expr::EvalResult SimdlenResult
, SafelenResult
;
10179 SimdlenLength
->EvaluateAsInt(SimdlenResult
, S
.Context
);
10180 SafelenLength
->EvaluateAsInt(SafelenResult
, S
.Context
);
10181 llvm::APSInt SimdlenRes
= SimdlenResult
.Val
.getInt();
10182 llvm::APSInt SafelenRes
= SafelenResult
.Val
.getInt();
10183 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10184 // If both simdlen and safelen clauses are specified, the value of the
10185 // simdlen parameter must be less than or equal to the value of the safelen
10187 if (SimdlenRes
> SafelenRes
) {
10188 S
.Diag(SimdlenLength
->getExprLoc(),
10189 diag::err_omp_wrong_simdlen_safelen_values
)
10190 << SimdlenLength
->getSourceRange() << SafelenLength
->getSourceRange();
10198 Sema::ActOnOpenMPSimdDirective(ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
,
10199 SourceLocation StartLoc
, SourceLocation EndLoc
,
10200 VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10202 return StmtError();
10204 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10205 OMPLoopBasedDirective::HelperExprs B
;
10206 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10207 // define the nested loops number.
10208 unsigned NestedLoopCount
= checkOpenMPLoop(
10209 OMPD_simd
, getCollapseNumberExpr(Clauses
), getOrderedNumberExpr(Clauses
),
10210 AStmt
, *this, *DSAStack
, VarsWithImplicitDSA
, B
);
10211 if (NestedLoopCount
== 0)
10212 return StmtError();
10214 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10215 "omp simd loop exprs were not built");
10217 if (!CurContext
->isDependentContext()) {
10218 // Finalize the clauses that need pre-built expressions for CodeGen.
10219 for (OMPClause
*C
: Clauses
) {
10220 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
10221 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
10222 B
.NumIterations
, *this, CurScope
,
10224 return StmtError();
10228 if (checkSimdlenSafelenSpecified(*this, Clauses
))
10229 return StmtError();
10231 setFunctionHasBranchProtectedScope();
10232 return OMPSimdDirective::Create(Context
, StartLoc
, EndLoc
, NestedLoopCount
,
10233 Clauses
, AStmt
, B
);
10237 Sema::ActOnOpenMPForDirective(ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
,
10238 SourceLocation StartLoc
, SourceLocation EndLoc
,
10239 VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10241 return StmtError();
10243 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10244 OMPLoopBasedDirective::HelperExprs B
;
10245 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10246 // define the nested loops number.
10247 unsigned NestedLoopCount
= checkOpenMPLoop(
10248 OMPD_for
, getCollapseNumberExpr(Clauses
), getOrderedNumberExpr(Clauses
),
10249 AStmt
, *this, *DSAStack
, VarsWithImplicitDSA
, B
);
10250 if (NestedLoopCount
== 0)
10251 return StmtError();
10253 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10254 "omp for loop exprs were not built");
10256 if (!CurContext
->isDependentContext()) {
10257 // Finalize the clauses that need pre-built expressions for CodeGen.
10258 for (OMPClause
*C
: Clauses
) {
10259 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
10260 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
10261 B
.NumIterations
, *this, CurScope
,
10263 return StmtError();
10267 setFunctionHasBranchProtectedScope();
10268 return OMPForDirective::Create(
10269 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
10270 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
10273 StmtResult
Sema::ActOnOpenMPForSimdDirective(
10274 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10275 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10277 return StmtError();
10279 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10280 OMPLoopBasedDirective::HelperExprs B
;
10281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10282 // define the nested loops number.
10283 unsigned NestedLoopCount
=
10284 checkOpenMPLoop(OMPD_for_simd
, getCollapseNumberExpr(Clauses
),
10285 getOrderedNumberExpr(Clauses
), AStmt
, *this, *DSAStack
,
10286 VarsWithImplicitDSA
, B
);
10287 if (NestedLoopCount
== 0)
10288 return StmtError();
10290 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10291 "omp for simd loop exprs were not built");
10293 if (!CurContext
->isDependentContext()) {
10294 // Finalize the clauses that need pre-built expressions for CodeGen.
10295 for (OMPClause
*C
: Clauses
) {
10296 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
10297 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
10298 B
.NumIterations
, *this, CurScope
,
10300 return StmtError();
10304 if (checkSimdlenSafelenSpecified(*this, Clauses
))
10305 return StmtError();
10307 setFunctionHasBranchProtectedScope();
10308 return OMPForSimdDirective::Create(Context
, StartLoc
, EndLoc
, NestedLoopCount
,
10309 Clauses
, AStmt
, B
);
10312 StmtResult
Sema::ActOnOpenMPSectionsDirective(ArrayRef
<OMPClause
*> Clauses
,
10314 SourceLocation StartLoc
,
10315 SourceLocation EndLoc
) {
10317 return StmtError();
10319 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10320 auto BaseStmt
= AStmt
;
10321 while (auto *CS
= dyn_cast_or_null
<CapturedStmt
>(BaseStmt
))
10322 BaseStmt
= CS
->getCapturedStmt();
10323 if (auto *C
= dyn_cast_or_null
<CompoundStmt
>(BaseStmt
)) {
10324 auto S
= C
->children();
10325 if (S
.begin() == S
.end())
10326 return StmtError();
10327 // All associated statements must be '#pragma omp section' except for
10329 for (Stmt
*SectionStmt
: llvm::drop_begin(S
)) {
10330 if (!SectionStmt
|| !isa
<OMPSectionDirective
>(SectionStmt
)) {
10332 Diag(SectionStmt
->getBeginLoc(),
10333 diag::err_omp_sections_substmt_not_section
);
10334 return StmtError();
10336 cast
<OMPSectionDirective
>(SectionStmt
)
10337 ->setHasCancel(DSAStack
->isCancelRegion());
10340 Diag(AStmt
->getBeginLoc(), diag::err_omp_sections_not_compound_stmt
);
10341 return StmtError();
10344 setFunctionHasBranchProtectedScope();
10346 return OMPSectionsDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
10347 DSAStack
->getTaskgroupReductionRef(),
10348 DSAStack
->isCancelRegion());
10351 StmtResult
Sema::ActOnOpenMPSectionDirective(Stmt
*AStmt
,
10352 SourceLocation StartLoc
,
10353 SourceLocation EndLoc
) {
10355 return StmtError();
10357 setFunctionHasBranchProtectedScope();
10358 DSAStack
->setParentCancelRegion(DSAStack
->isCancelRegion());
10360 return OMPSectionDirective::Create(Context
, StartLoc
, EndLoc
, AStmt
,
10361 DSAStack
->isCancelRegion());
10364 static Expr
*getDirectCallExpr(Expr
*E
) {
10365 E
= E
->IgnoreParenCasts()->IgnoreImplicit();
10366 if (auto *CE
= dyn_cast
<CallExpr
>(E
))
10367 if (CE
->getDirectCallee())
10372 StmtResult
Sema::ActOnOpenMPDispatchDirective(ArrayRef
<OMPClause
*> Clauses
,
10374 SourceLocation StartLoc
,
10375 SourceLocation EndLoc
) {
10377 return StmtError();
10379 Stmt
*S
= cast
<CapturedStmt
>(AStmt
)->getCapturedStmt();
10382 // expression-stmt : an expression statement with one of the following forms:
10383 // expression = target-call ( [expression-list] );
10384 // target-call ( [expression-list] );
10386 SourceLocation TargetCallLoc
;
10388 if (!CurContext
->isDependentContext()) {
10389 Expr
*TargetCall
= nullptr;
10391 auto *E
= dyn_cast
<Expr
>(S
);
10393 Diag(S
->getBeginLoc(), diag::err_omp_dispatch_statement_call
);
10394 return StmtError();
10397 E
= E
->IgnoreParenCasts()->IgnoreImplicit();
10399 if (auto *BO
= dyn_cast
<BinaryOperator
>(E
)) {
10400 if (BO
->getOpcode() == BO_Assign
)
10401 TargetCall
= getDirectCallExpr(BO
->getRHS());
10403 if (auto *COCE
= dyn_cast
<CXXOperatorCallExpr
>(E
))
10404 if (COCE
->getOperator() == OO_Equal
)
10405 TargetCall
= getDirectCallExpr(COCE
->getArg(1));
10407 TargetCall
= getDirectCallExpr(E
);
10410 Diag(E
->getBeginLoc(), diag::err_omp_dispatch_statement_call
);
10411 return StmtError();
10413 TargetCallLoc
= TargetCall
->getExprLoc();
10416 setFunctionHasBranchProtectedScope();
10418 return OMPDispatchDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
10422 static bool checkGenericLoopLastprivate(Sema
&S
, ArrayRef
<OMPClause
*> Clauses
,
10423 OpenMPDirectiveKind K
,
10424 DSAStackTy
*Stack
) {
10425 bool ErrorFound
= false;
10426 for (OMPClause
*C
: Clauses
) {
10427 if (auto *LPC
= dyn_cast
<OMPLastprivateClause
>(C
)) {
10428 for (Expr
*RefExpr
: LPC
->varlists()) {
10429 SourceLocation ELoc
;
10430 SourceRange ERange
;
10431 Expr
*SimpleRefExpr
= RefExpr
;
10432 auto Res
= getPrivateItem(S
, SimpleRefExpr
, ELoc
, ERange
);
10433 if (ValueDecl
*D
= Res
.first
) {
10434 auto &&Info
= Stack
->isLoopControlVariable(D
);
10436 S
.Diag(ELoc
, diag::err_omp_lastprivate_loop_var_non_loop_iteration
)
10437 << getOpenMPDirectiveName(K
);
10447 StmtResult
Sema::ActOnOpenMPGenericLoopDirective(
10448 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10449 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10451 return StmtError();
10453 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10454 // A list item may not appear in a lastprivate clause unless it is the
10455 // loop iteration variable of a loop that is associated with the construct.
10456 if (checkGenericLoopLastprivate(*this, Clauses
, OMPD_loop
, DSAStack
))
10457 return StmtError();
10459 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10460 // 1.2.2 OpenMP Language Terminology
10461 // Structured block - An executable statement with a single entry at the
10462 // top and a single exit at the bottom.
10463 // The point of exit cannot be a branch out of the structured block.
10464 // longjmp() and throw() must not violate the entry/exit criteria.
10465 CS
->getCapturedDecl()->setNothrow();
10467 OMPLoopDirective::HelperExprs B
;
10468 // In presence of clause 'collapse', it will define the nested loops number.
10469 unsigned NestedLoopCount
= checkOpenMPLoop(
10470 OMPD_loop
, getCollapseNumberExpr(Clauses
), getOrderedNumberExpr(Clauses
),
10471 AStmt
, *this, *DSAStack
, VarsWithImplicitDSA
, B
);
10472 if (NestedLoopCount
== 0)
10473 return StmtError();
10475 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10476 "omp loop exprs were not built");
10478 setFunctionHasBranchProtectedScope();
10479 return OMPGenericLoopDirective::Create(Context
, StartLoc
, EndLoc
,
10480 NestedLoopCount
, Clauses
, AStmt
, B
);
10483 StmtResult
Sema::ActOnOpenMPTeamsGenericLoopDirective(
10484 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10485 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10487 return StmtError();
10489 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10490 // A list item may not appear in a lastprivate clause unless it is the
10491 // loop iteration variable of a loop that is associated with the construct.
10492 if (checkGenericLoopLastprivate(*this, Clauses
, OMPD_teams_loop
, DSAStack
))
10493 return StmtError();
10495 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10496 // 1.2.2 OpenMP Language Terminology
10497 // Structured block - An executable statement with a single entry at the
10498 // top and a single exit at the bottom.
10499 // The point of exit cannot be a branch out of the structured block.
10500 // longjmp() and throw() must not violate the entry/exit criteria.
10501 CS
->getCapturedDecl()->setNothrow();
10502 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_teams_loop
);
10503 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
10504 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
10505 // 1.2.2 OpenMP Language Terminology
10506 // Structured block - An executable statement with a single entry at the
10507 // top and a single exit at the bottom.
10508 // The point of exit cannot be a branch out of the structured block.
10509 // longjmp() and throw() must not violate the entry/exit criteria.
10510 CS
->getCapturedDecl()->setNothrow();
10513 OMPLoopDirective::HelperExprs B
;
10514 // In presence of clause 'collapse', it will define the nested loops number.
10515 unsigned NestedLoopCount
=
10516 checkOpenMPLoop(OMPD_teams_loop
, getCollapseNumberExpr(Clauses
),
10517 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
10518 VarsWithImplicitDSA
, B
);
10519 if (NestedLoopCount
== 0)
10520 return StmtError();
10522 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10523 "omp loop exprs were not built");
10525 setFunctionHasBranchProtectedScope();
10526 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
10528 return OMPTeamsGenericLoopDirective::Create(
10529 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
10532 StmtResult
Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10533 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10534 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10536 return StmtError();
10538 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10539 // A list item may not appear in a lastprivate clause unless it is the
10540 // loop iteration variable of a loop that is associated with the construct.
10541 if (checkGenericLoopLastprivate(*this, Clauses
, OMPD_target_teams_loop
,
10543 return StmtError();
10545 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10546 // 1.2.2 OpenMP Language Terminology
10547 // Structured block - An executable statement with a single entry at the
10548 // top and a single exit at the bottom.
10549 // The point of exit cannot be a branch out of the structured block.
10550 // longjmp() and throw() must not violate the entry/exit criteria.
10551 CS
->getCapturedDecl()->setNothrow();
10552 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_teams_loop
);
10553 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
10554 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
10555 // 1.2.2 OpenMP Language Terminology
10556 // Structured block - An executable statement with a single entry at the
10557 // top and a single exit at the bottom.
10558 // The point of exit cannot be a branch out of the structured block.
10559 // longjmp() and throw() must not violate the entry/exit criteria.
10560 CS
->getCapturedDecl()->setNothrow();
10563 OMPLoopDirective::HelperExprs B
;
10564 // In presence of clause 'collapse', it will define the nested loops number.
10565 unsigned NestedLoopCount
=
10566 checkOpenMPLoop(OMPD_target_teams_loop
, getCollapseNumberExpr(Clauses
),
10567 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
10568 VarsWithImplicitDSA
, B
);
10569 if (NestedLoopCount
== 0)
10570 return StmtError();
10572 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10573 "omp loop exprs were not built");
10575 setFunctionHasBranchProtectedScope();
10577 return OMPTargetTeamsGenericLoopDirective::Create(
10578 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
10581 StmtResult
Sema::ActOnOpenMPParallelGenericLoopDirective(
10582 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10583 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10585 return StmtError();
10587 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10588 // A list item may not appear in a lastprivate clause unless it is the
10589 // loop iteration variable of a loop that is associated with the construct.
10590 if (checkGenericLoopLastprivate(*this, Clauses
, OMPD_parallel_loop
, DSAStack
))
10591 return StmtError();
10593 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10594 // 1.2.2 OpenMP Language Terminology
10595 // Structured block - An executable statement with a single entry at the
10596 // top and a single exit at the bottom.
10597 // The point of exit cannot be a branch out of the structured block.
10598 // longjmp() and throw() must not violate the entry/exit criteria.
10599 CS
->getCapturedDecl()->setNothrow();
10600 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_parallel_loop
);
10601 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
10602 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
10603 // 1.2.2 OpenMP Language Terminology
10604 // Structured block - An executable statement with a single entry at the
10605 // top and a single exit at the bottom.
10606 // The point of exit cannot be a branch out of the structured block.
10607 // longjmp() and throw() must not violate the entry/exit criteria.
10608 CS
->getCapturedDecl()->setNothrow();
10611 OMPLoopDirective::HelperExprs B
;
10612 // In presence of clause 'collapse', it will define the nested loops number.
10613 unsigned NestedLoopCount
=
10614 checkOpenMPLoop(OMPD_parallel_loop
, getCollapseNumberExpr(Clauses
),
10615 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
10616 VarsWithImplicitDSA
, B
);
10617 if (NestedLoopCount
== 0)
10618 return StmtError();
10620 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10621 "omp loop exprs were not built");
10623 setFunctionHasBranchProtectedScope();
10625 return OMPParallelGenericLoopDirective::Create(
10626 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
10629 StmtResult
Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10630 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10631 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10633 return StmtError();
10635 // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10636 // A list item may not appear in a lastprivate clause unless it is the
10637 // loop iteration variable of a loop that is associated with the construct.
10638 if (checkGenericLoopLastprivate(*this, Clauses
, OMPD_target_parallel_loop
,
10640 return StmtError();
10642 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10643 // 1.2.2 OpenMP Language Terminology
10644 // Structured block - An executable statement with a single entry at the
10645 // top and a single exit at the bottom.
10646 // The point of exit cannot be a branch out of the structured block.
10647 // longjmp() and throw() must not violate the entry/exit criteria.
10648 CS
->getCapturedDecl()->setNothrow();
10649 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_parallel_loop
);
10650 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
10651 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
10652 // 1.2.2 OpenMP Language Terminology
10653 // Structured block - An executable statement with a single entry at the
10654 // top and a single exit at the bottom.
10655 // The point of exit cannot be a branch out of the structured block.
10656 // longjmp() and throw() must not violate the entry/exit criteria.
10657 CS
->getCapturedDecl()->setNothrow();
10660 OMPLoopDirective::HelperExprs B
;
10661 // In presence of clause 'collapse', it will define the nested loops number.
10662 unsigned NestedLoopCount
=
10663 checkOpenMPLoop(OMPD_target_parallel_loop
, getCollapseNumberExpr(Clauses
),
10664 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
10665 VarsWithImplicitDSA
, B
);
10666 if (NestedLoopCount
== 0)
10667 return StmtError();
10669 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10670 "omp loop exprs were not built");
10672 setFunctionHasBranchProtectedScope();
10674 return OMPTargetParallelGenericLoopDirective::Create(
10675 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
10678 StmtResult
Sema::ActOnOpenMPSingleDirective(ArrayRef
<OMPClause
*> Clauses
,
10680 SourceLocation StartLoc
,
10681 SourceLocation EndLoc
) {
10683 return StmtError();
10685 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10687 setFunctionHasBranchProtectedScope();
10689 // OpenMP [2.7.3, single Construct, Restrictions]
10690 // The copyprivate clause must not be used with the nowait clause.
10691 const OMPClause
*Nowait
= nullptr;
10692 const OMPClause
*Copyprivate
= nullptr;
10693 for (const OMPClause
*Clause
: Clauses
) {
10694 if (Clause
->getClauseKind() == OMPC_nowait
)
10696 else if (Clause
->getClauseKind() == OMPC_copyprivate
)
10697 Copyprivate
= Clause
;
10698 if (Copyprivate
&& Nowait
) {
10699 Diag(Copyprivate
->getBeginLoc(),
10700 diag::err_omp_single_copyprivate_with_nowait
);
10701 Diag(Nowait
->getBeginLoc(), diag::note_omp_nowait_clause_here
);
10702 return StmtError();
10706 return OMPSingleDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
);
10709 StmtResult
Sema::ActOnOpenMPMasterDirective(Stmt
*AStmt
,
10710 SourceLocation StartLoc
,
10711 SourceLocation EndLoc
) {
10713 return StmtError();
10715 setFunctionHasBranchProtectedScope();
10717 return OMPMasterDirective::Create(Context
, StartLoc
, EndLoc
, AStmt
);
10720 StmtResult
Sema::ActOnOpenMPMaskedDirective(ArrayRef
<OMPClause
*> Clauses
,
10722 SourceLocation StartLoc
,
10723 SourceLocation EndLoc
) {
10725 return StmtError();
10727 setFunctionHasBranchProtectedScope();
10729 return OMPMaskedDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
);
10732 StmtResult
Sema::ActOnOpenMPCriticalDirective(
10733 const DeclarationNameInfo
&DirName
, ArrayRef
<OMPClause
*> Clauses
,
10734 Stmt
*AStmt
, SourceLocation StartLoc
, SourceLocation EndLoc
) {
10736 return StmtError();
10738 bool ErrorFound
= false;
10740 SourceLocation HintLoc
;
10741 bool DependentHint
= false;
10742 for (const OMPClause
*C
: Clauses
) {
10743 if (C
->getClauseKind() == OMPC_hint
) {
10744 if (!DirName
.getName()) {
10745 Diag(C
->getBeginLoc(), diag::err_omp_hint_clause_no_name
);
10748 Expr
*E
= cast
<OMPHintClause
>(C
)->getHint();
10749 if (E
->isTypeDependent() || E
->isValueDependent() ||
10750 E
->isInstantiationDependent()) {
10751 DependentHint
= true;
10753 Hint
= E
->EvaluateKnownConstInt(Context
);
10754 HintLoc
= C
->getBeginLoc();
10759 return StmtError();
10760 const auto Pair
= DSAStack
->getCriticalWithHint(DirName
);
10761 if (Pair
.first
&& DirName
.getName() && !DependentHint
) {
10762 if (llvm::APSInt::compareValues(Hint
, Pair
.second
) != 0) {
10763 Diag(StartLoc
, diag::err_omp_critical_with_hint
);
10764 if (HintLoc
.isValid())
10765 Diag(HintLoc
, diag::note_omp_critical_hint_here
)
10766 << 0 << toString(Hint
, /*Radix=*/10, /*Signed=*/false);
10768 Diag(StartLoc
, diag::note_omp_critical_no_hint
) << 0;
10769 if (const auto *C
= Pair
.first
->getSingleClause
<OMPHintClause
>()) {
10770 Diag(C
->getBeginLoc(), diag::note_omp_critical_hint_here
)
10772 << toString(C
->getHint()->EvaluateKnownConstInt(Context
),
10773 /*Radix=*/10, /*Signed=*/false);
10775 Diag(Pair
.first
->getBeginLoc(), diag::note_omp_critical_no_hint
) << 1;
10780 setFunctionHasBranchProtectedScope();
10782 auto *Dir
= OMPCriticalDirective::Create(Context
, DirName
, StartLoc
, EndLoc
,
10784 if (!Pair
.first
&& DirName
.getName() && !DependentHint
)
10785 DSAStack
->addCriticalWithHint(Dir
, Hint
);
10789 StmtResult
Sema::ActOnOpenMPParallelForDirective(
10790 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10791 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10793 return StmtError();
10795 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10796 // 1.2.2 OpenMP Language Terminology
10797 // Structured block - An executable statement with a single entry at the
10798 // top and a single exit at the bottom.
10799 // The point of exit cannot be a branch out of the structured block.
10800 // longjmp() and throw() must not violate the entry/exit criteria.
10801 CS
->getCapturedDecl()->setNothrow();
10803 OMPLoopBasedDirective::HelperExprs B
;
10804 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10805 // define the nested loops number.
10806 unsigned NestedLoopCount
=
10807 checkOpenMPLoop(OMPD_parallel_for
, getCollapseNumberExpr(Clauses
),
10808 getOrderedNumberExpr(Clauses
), AStmt
, *this, *DSAStack
,
10809 VarsWithImplicitDSA
, B
);
10810 if (NestedLoopCount
== 0)
10811 return StmtError();
10813 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
10814 "omp parallel for loop exprs were not built");
10816 if (!CurContext
->isDependentContext()) {
10817 // Finalize the clauses that need pre-built expressions for CodeGen.
10818 for (OMPClause
*C
: Clauses
) {
10819 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
10820 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
10821 B
.NumIterations
, *this, CurScope
,
10823 return StmtError();
10827 setFunctionHasBranchProtectedScope();
10828 return OMPParallelForDirective::Create(
10829 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
10830 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
10833 StmtResult
Sema::ActOnOpenMPParallelForSimdDirective(
10834 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
10835 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
10837 return StmtError();
10839 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10840 // 1.2.2 OpenMP Language Terminology
10841 // Structured block - An executable statement with a single entry at the
10842 // top and a single exit at the bottom.
10843 // The point of exit cannot be a branch out of the structured block.
10844 // longjmp() and throw() must not violate the entry/exit criteria.
10845 CS
->getCapturedDecl()->setNothrow();
10847 OMPLoopBasedDirective::HelperExprs B
;
10848 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10849 // define the nested loops number.
10850 unsigned NestedLoopCount
=
10851 checkOpenMPLoop(OMPD_parallel_for_simd
, getCollapseNumberExpr(Clauses
),
10852 getOrderedNumberExpr(Clauses
), AStmt
, *this, *DSAStack
,
10853 VarsWithImplicitDSA
, B
);
10854 if (NestedLoopCount
== 0)
10855 return StmtError();
10857 if (!CurContext
->isDependentContext()) {
10858 // Finalize the clauses that need pre-built expressions for CodeGen.
10859 for (OMPClause
*C
: Clauses
) {
10860 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
10861 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
10862 B
.NumIterations
, *this, CurScope
,
10864 return StmtError();
10868 if (checkSimdlenSafelenSpecified(*this, Clauses
))
10869 return StmtError();
10871 setFunctionHasBranchProtectedScope();
10872 return OMPParallelForSimdDirective::Create(
10873 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
10877 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef
<OMPClause
*> Clauses
,
10878 Stmt
*AStmt
, SourceLocation StartLoc
,
10879 SourceLocation EndLoc
) {
10881 return StmtError();
10883 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10884 auto *CS
= cast
<CapturedStmt
>(AStmt
);
10885 // 1.2.2 OpenMP Language Terminology
10886 // Structured block - An executable statement with a single entry at the
10887 // top and a single exit at the bottom.
10888 // The point of exit cannot be a branch out of the structured block.
10889 // longjmp() and throw() must not violate the entry/exit criteria.
10890 CS
->getCapturedDecl()->setNothrow();
10892 setFunctionHasBranchProtectedScope();
10894 return OMPParallelMasterDirective::Create(
10895 Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
10896 DSAStack
->getTaskgroupReductionRef());
10900 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef
<OMPClause
*> Clauses
,
10901 Stmt
*AStmt
, SourceLocation StartLoc
,
10902 SourceLocation EndLoc
) {
10904 return StmtError();
10906 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10907 auto *CS
= cast
<CapturedStmt
>(AStmt
);
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();
10915 setFunctionHasBranchProtectedScope();
10917 return OMPParallelMaskedDirective::Create(
10918 Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
10919 DSAStack
->getTaskgroupReductionRef());
10923 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef
<OMPClause
*> Clauses
,
10924 Stmt
*AStmt
, SourceLocation StartLoc
,
10925 SourceLocation EndLoc
) {
10927 return StmtError();
10929 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
10930 auto BaseStmt
= AStmt
;
10931 while (auto *CS
= dyn_cast_or_null
<CapturedStmt
>(BaseStmt
))
10932 BaseStmt
= CS
->getCapturedStmt();
10933 if (auto *C
= dyn_cast_or_null
<CompoundStmt
>(BaseStmt
)) {
10934 auto S
= C
->children();
10935 if (S
.begin() == S
.end())
10936 return StmtError();
10937 // All associated statements must be '#pragma omp section' except for
10939 for (Stmt
*SectionStmt
: llvm::drop_begin(S
)) {
10940 if (!SectionStmt
|| !isa
<OMPSectionDirective
>(SectionStmt
)) {
10942 Diag(SectionStmt
->getBeginLoc(),
10943 diag::err_omp_parallel_sections_substmt_not_section
);
10944 return StmtError();
10946 cast
<OMPSectionDirective
>(SectionStmt
)
10947 ->setHasCancel(DSAStack
->isCancelRegion());
10950 Diag(AStmt
->getBeginLoc(),
10951 diag::err_omp_parallel_sections_not_compound_stmt
);
10952 return StmtError();
10955 setFunctionHasBranchProtectedScope();
10957 return OMPParallelSectionsDirective::Create(
10958 Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
10959 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
10962 /// Find and diagnose mutually exclusive clause kinds.
10963 static bool checkMutuallyExclusiveClauses(
10964 Sema
&S
, ArrayRef
<OMPClause
*> Clauses
,
10965 ArrayRef
<OpenMPClauseKind
> MutuallyExclusiveClauses
) {
10966 const OMPClause
*PrevClause
= nullptr;
10967 bool ErrorFound
= false;
10968 for (const OMPClause
*C
: Clauses
) {
10969 if (llvm::is_contained(MutuallyExclusiveClauses
, C
->getClauseKind())) {
10972 } else if (PrevClause
->getClauseKind() != C
->getClauseKind()) {
10973 S
.Diag(C
->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive
)
10974 << getOpenMPClauseName(C
->getClauseKind())
10975 << getOpenMPClauseName(PrevClause
->getClauseKind());
10976 S
.Diag(PrevClause
->getBeginLoc(), diag::note_omp_previous_clause
)
10977 << getOpenMPClauseName(PrevClause
->getClauseKind());
10985 StmtResult
Sema::ActOnOpenMPTaskDirective(ArrayRef
<OMPClause
*> Clauses
,
10986 Stmt
*AStmt
, SourceLocation StartLoc
,
10987 SourceLocation EndLoc
) {
10989 return StmtError();
10991 // OpenMP 5.0, 2.10.1 task Construct
10992 // If a detach clause appears on the directive, then a mergeable clause cannot
10993 // appear on the same directive.
10994 if (checkMutuallyExclusiveClauses(*this, Clauses
,
10995 {OMPC_detach
, OMPC_mergeable
}))
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();
11006 setFunctionHasBranchProtectedScope();
11008 return OMPTaskDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
11009 DSAStack
->isCancelRegion());
11012 StmtResult
Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc
,
11013 SourceLocation EndLoc
) {
11014 return OMPTaskyieldDirective::Create(Context
, StartLoc
, EndLoc
);
11017 StmtResult
Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc
,
11018 SourceLocation EndLoc
) {
11019 return OMPBarrierDirective::Create(Context
, StartLoc
, EndLoc
);
11022 StmtResult
Sema::ActOnOpenMPTaskwaitDirective(ArrayRef
<OMPClause
*> Clauses
,
11023 SourceLocation StartLoc
,
11024 SourceLocation EndLoc
) {
11025 return OMPTaskwaitDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
);
11028 StmtResult
Sema::ActOnOpenMPTaskgroupDirective(ArrayRef
<OMPClause
*> Clauses
,
11030 SourceLocation StartLoc
,
11031 SourceLocation EndLoc
) {
11033 return StmtError();
11035 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
11037 setFunctionHasBranchProtectedScope();
11039 return OMPTaskgroupDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
11041 DSAStack
->getTaskgroupReductionRef());
11044 StmtResult
Sema::ActOnOpenMPFlushDirective(ArrayRef
<OMPClause
*> Clauses
,
11045 SourceLocation StartLoc
,
11046 SourceLocation EndLoc
) {
11047 OMPFlushClause
*FC
= nullptr;
11048 OMPClause
*OrderClause
= nullptr;
11049 for (OMPClause
*C
: Clauses
) {
11050 if (C
->getClauseKind() == OMPC_flush
)
11051 FC
= cast
<OMPFlushClause
>(C
);
11055 OpenMPClauseKind MemOrderKind
= OMPC_unknown
;
11056 SourceLocation MemOrderLoc
;
11057 for (const OMPClause
*C
: Clauses
) {
11058 if (C
->getClauseKind() == OMPC_acq_rel
||
11059 C
->getClauseKind() == OMPC_acquire
||
11060 C
->getClauseKind() == OMPC_release
) {
11061 if (MemOrderKind
!= OMPC_unknown
) {
11062 Diag(C
->getBeginLoc(), diag::err_omp_several_mem_order_clauses
)
11063 << getOpenMPDirectiveName(OMPD_flush
) << 1
11064 << SourceRange(C
->getBeginLoc(), C
->getEndLoc());
11065 Diag(MemOrderLoc
, diag::note_omp_previous_mem_order_clause
)
11066 << getOpenMPClauseName(MemOrderKind
);
11068 MemOrderKind
= C
->getClauseKind();
11069 MemOrderLoc
= C
->getBeginLoc();
11073 if (FC
&& OrderClause
) {
11074 Diag(FC
->getLParenLoc(), diag::err_omp_flush_order_clause_and_list
)
11075 << getOpenMPClauseName(OrderClause
->getClauseKind());
11076 Diag(OrderClause
->getBeginLoc(), diag::note_omp_flush_order_clause_here
)
11077 << getOpenMPClauseName(OrderClause
->getClauseKind());
11078 return StmtError();
11080 return OMPFlushDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
);
11083 StmtResult
Sema::ActOnOpenMPDepobjDirective(ArrayRef
<OMPClause
*> Clauses
,
11084 SourceLocation StartLoc
,
11085 SourceLocation EndLoc
) {
11086 if (Clauses
.empty()) {
11087 Diag(StartLoc
, diag::err_omp_depobj_expected
);
11088 return StmtError();
11089 } else if (Clauses
[0]->getClauseKind() != OMPC_depobj
) {
11090 Diag(Clauses
[0]->getBeginLoc(), diag::err_omp_depobj_expected
);
11091 return StmtError();
11093 // Only depobj expression and another single clause is allowed.
11094 if (Clauses
.size() > 2) {
11095 Diag(Clauses
[2]->getBeginLoc(),
11096 diag::err_omp_depobj_single_clause_expected
);
11097 return StmtError();
11098 } else if (Clauses
.size() < 1) {
11099 Diag(Clauses
[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected
);
11100 return StmtError();
11102 return OMPDepobjDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
);
11105 StmtResult
Sema::ActOnOpenMPScanDirective(ArrayRef
<OMPClause
*> Clauses
,
11106 SourceLocation StartLoc
,
11107 SourceLocation EndLoc
) {
11108 // Check that exactly one clause is specified.
11109 if (Clauses
.size() != 1) {
11110 Diag(Clauses
.empty() ? EndLoc
: Clauses
[1]->getBeginLoc(),
11111 diag::err_omp_scan_single_clause_expected
);
11112 return StmtError();
11114 // Check that scan directive is used in the scopeof the OpenMP loop body.
11115 if (Scope
*S
= DSAStack
->getCurScope()) {
11116 Scope
*ParentS
= S
->getParent();
11117 if (!ParentS
|| ParentS
->getParent() != ParentS
->getBreakParent() ||
11118 !ParentS
->getBreakParent()->isOpenMPLoopScope())
11119 return StmtError(Diag(StartLoc
, diag::err_omp_orphaned_device_directive
)
11120 << getOpenMPDirectiveName(OMPD_scan
) << 5);
11122 // Check that only one instance of scan directives is used in the same outer
11124 if (DSAStack
->doesParentHasScanDirective()) {
11125 Diag(StartLoc
, diag::err_omp_several_directives_in_region
) << "scan";
11126 Diag(DSAStack
->getParentScanDirectiveLoc(),
11127 diag::note_omp_previous_directive
)
11129 return StmtError();
11131 DSAStack
->setParentHasScanDirective(StartLoc
);
11132 return OMPScanDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
);
11135 StmtResult
Sema::ActOnOpenMPOrderedDirective(ArrayRef
<OMPClause
*> Clauses
,
11137 SourceLocation StartLoc
,
11138 SourceLocation EndLoc
) {
11139 const OMPClause
*DependFound
= nullptr;
11140 const OMPClause
*DependSourceClause
= nullptr;
11141 const OMPClause
*DependSinkClause
= nullptr;
11142 bool ErrorFound
= false;
11143 const OMPThreadsClause
*TC
= nullptr;
11144 const OMPSIMDClause
*SC
= nullptr;
11145 for (const OMPClause
*C
: Clauses
) {
11146 if (auto *DC
= dyn_cast
<OMPDependClause
>(C
)) {
11148 if (DC
->getDependencyKind() == OMPC_DEPEND_source
) {
11149 if (DependSourceClause
) {
11150 Diag(C
->getBeginLoc(), diag::err_omp_more_one_clause
)
11151 << getOpenMPDirectiveName(OMPD_ordered
)
11152 << getOpenMPClauseName(OMPC_depend
) << 2;
11155 DependSourceClause
= C
;
11157 if (DependSinkClause
) {
11158 Diag(C
->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed
)
11162 } else if (DC
->getDependencyKind() == OMPC_DEPEND_sink
) {
11163 if (DependSourceClause
) {
11164 Diag(C
->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed
)
11168 DependSinkClause
= C
;
11170 } else if (C
->getClauseKind() == OMPC_threads
) {
11171 TC
= cast
<OMPThreadsClause
>(C
);
11172 } else if (C
->getClauseKind() == OMPC_simd
) {
11173 SC
= cast
<OMPSIMDClause
>(C
);
11176 if (!ErrorFound
&& !SC
&&
11177 isOpenMPSimdDirective(DSAStack
->getParentDirective())) {
11178 // OpenMP [2.8.1,simd Construct, Restrictions]
11179 // An ordered construct with the simd clause is the only OpenMP construct
11180 // that can appear in the simd region.
11181 Diag(StartLoc
, diag::err_omp_prohibited_region_simd
)
11182 << (LangOpts
.OpenMP
>= 50 ? 1 : 0);
11184 } else if (DependFound
&& (TC
|| SC
)) {
11185 Diag(DependFound
->getBeginLoc(), diag::err_omp_depend_clause_thread_simd
)
11186 << getOpenMPClauseName(TC
? TC
->getClauseKind() : SC
->getClauseKind());
11188 } else if (DependFound
&& !DSAStack
->getParentOrderedRegionParam().first
) {
11189 Diag(DependFound
->getBeginLoc(),
11190 diag::err_omp_ordered_directive_without_param
);
11192 } else if (TC
|| Clauses
.empty()) {
11193 if (const Expr
*Param
= DSAStack
->getParentOrderedRegionParam().first
) {
11194 SourceLocation ErrLoc
= TC
? TC
->getBeginLoc() : StartLoc
;
11195 Diag(ErrLoc
, diag::err_omp_ordered_directive_with_param
)
11196 << (TC
!= nullptr);
11197 Diag(Param
->getBeginLoc(), diag::note_omp_ordered_param
) << 1;
11201 if ((!AStmt
&& !DependFound
) || ErrorFound
)
11202 return StmtError();
11204 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11205 // During execution of an iteration of a worksharing-loop or a loop nest
11206 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11207 // must not execute more than one ordered region corresponding to an ordered
11208 // construct without a depend clause.
11209 if (!DependFound
) {
11210 if (DSAStack
->doesParentHasOrderedDirective()) {
11211 Diag(StartLoc
, diag::err_omp_several_directives_in_region
) << "ordered";
11212 Diag(DSAStack
->getParentOrderedDirectiveLoc(),
11213 diag::note_omp_previous_directive
)
11215 return StmtError();
11217 DSAStack
->setParentHasOrderedDirective(StartLoc
);
11221 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
11223 setFunctionHasBranchProtectedScope();
11226 return OMPOrderedDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
);
11230 /// Helper class for checking expression in 'omp atomic [update]'
11232 class OpenMPAtomicUpdateChecker
{
11233 /// Error results for atomic update expressions.
11234 enum ExprAnalysisErrorCode
{
11235 /// A statement is not an expression statement.
11237 /// Expression is not builtin binary or unary operation.
11238 NotABinaryOrUnaryExpression
,
11239 /// Unary operation is not post-/pre- increment/decrement operation.
11240 NotAnUnaryIncDecExpression
,
11241 /// An expression is not of scalar type.
11243 /// A binary operation is not an assignment operation.
11245 /// RHS part of the binary operation is not a binary expression.
11246 NotABinaryExpression
,
11247 /// RHS part is not additive/multiplicative/shift/biwise binary
11249 NotABinaryOperator
,
11250 /// RHS binary operation does not have reference to the updated LHS
11252 NotAnUpdateExpression
,
11253 /// No errors is found.
11256 /// Reference to Sema.
11258 /// A location for note diagnostics (when error is found).
11259 SourceLocation NoteLoc
;
11260 /// 'x' lvalue part of the source atomic expression.
11262 /// 'expr' rvalue part of the source atomic expression.
11264 /// Helper expression of the form
11265 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11266 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11268 /// Is 'x' a LHS in a RHS part of full update expression. It is
11269 /// important for non-associative operations.
11270 bool IsXLHSInRHSPart
;
11271 BinaryOperatorKind Op
;
11272 SourceLocation OpLoc
;
11273 /// true if the source expression is a postfix unary operation, false
11274 /// if it is a prefix unary operation.
11275 bool IsPostfixUpdate
;
11278 OpenMPAtomicUpdateChecker(Sema
&SemaRef
)
11279 : SemaRef(SemaRef
), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11280 IsXLHSInRHSPart(false), Op(BO_PtrMemD
), IsPostfixUpdate(false) {}
11281 /// Check specified statement that it is suitable for 'atomic update'
11282 /// constructs and extract 'x', 'expr' and Operation from the original
11283 /// expression. If DiagId and NoteId == 0, then only check is performed
11284 /// without error notification.
11285 /// \param DiagId Diagnostic which should be emitted if error is found.
11286 /// \param NoteId Diagnostic note for the main error message.
11287 /// \return true if statement is not an update expression, false otherwise.
11288 bool checkStatement(Stmt
*S
, unsigned DiagId
= 0, unsigned NoteId
= 0);
11289 /// Return the 'x' lvalue part of the source atomic expression.
11290 Expr
*getX() const { return X
; }
11291 /// Return the 'expr' rvalue part of the source atomic expression.
11292 Expr
*getExpr() const { return E
; }
11293 /// Return the update expression used in calculation of the updated
11294 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11295 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11296 Expr
*getUpdateExpr() const { return UpdateExpr
; }
11297 /// Return true if 'x' is LHS in RHS part of full update expression,
11298 /// false otherwise.
11299 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart
; }
11301 /// true if the source expression is a postfix unary operation, false
11302 /// if it is a prefix unary operation.
11303 bool isPostfixUpdate() const { return IsPostfixUpdate
; }
11306 bool checkBinaryOperation(BinaryOperator
*AtomicBinOp
, unsigned DiagId
= 0,
11307 unsigned NoteId
= 0);
11310 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11311 BinaryOperator
*AtomicBinOp
, unsigned DiagId
, unsigned NoteId
) {
11312 ExprAnalysisErrorCode ErrorFound
= NoError
;
11313 SourceLocation ErrorLoc
, NoteLoc
;
11314 SourceRange ErrorRange
, NoteRange
;
11315 // Allowed constructs are:
11316 // x = x binop expr;
11317 // x = expr binop x;
11318 if (AtomicBinOp
->getOpcode() == BO_Assign
) {
11319 X
= AtomicBinOp
->getLHS();
11320 if (const auto *AtomicInnerBinOp
= dyn_cast
<BinaryOperator
>(
11321 AtomicBinOp
->getRHS()->IgnoreParenImpCasts())) {
11322 if (AtomicInnerBinOp
->isMultiplicativeOp() ||
11323 AtomicInnerBinOp
->isAdditiveOp() || AtomicInnerBinOp
->isShiftOp() ||
11324 AtomicInnerBinOp
->isBitwiseOp()) {
11325 Op
= AtomicInnerBinOp
->getOpcode();
11326 OpLoc
= AtomicInnerBinOp
->getOperatorLoc();
11327 Expr
*LHS
= AtomicInnerBinOp
->getLHS();
11328 Expr
*RHS
= AtomicInnerBinOp
->getRHS();
11329 llvm::FoldingSetNodeID XId
, LHSId
, RHSId
;
11330 X
->IgnoreParenImpCasts()->Profile(XId
, SemaRef
.getASTContext(),
11331 /*Canonical=*/true);
11332 LHS
->IgnoreParenImpCasts()->Profile(LHSId
, SemaRef
.getASTContext(),
11333 /*Canonical=*/true);
11334 RHS
->IgnoreParenImpCasts()->Profile(RHSId
, SemaRef
.getASTContext(),
11335 /*Canonical=*/true);
11336 if (XId
== LHSId
) {
11338 IsXLHSInRHSPart
= true;
11339 } else if (XId
== RHSId
) {
11341 IsXLHSInRHSPart
= false;
11343 ErrorLoc
= AtomicInnerBinOp
->getExprLoc();
11344 ErrorRange
= AtomicInnerBinOp
->getSourceRange();
11345 NoteLoc
= X
->getExprLoc();
11346 NoteRange
= X
->getSourceRange();
11347 ErrorFound
= NotAnUpdateExpression
;
11350 ErrorLoc
= AtomicInnerBinOp
->getExprLoc();
11351 ErrorRange
= AtomicInnerBinOp
->getSourceRange();
11352 NoteLoc
= AtomicInnerBinOp
->getOperatorLoc();
11353 NoteRange
= SourceRange(NoteLoc
, NoteLoc
);
11354 ErrorFound
= NotABinaryOperator
;
11357 NoteLoc
= ErrorLoc
= AtomicBinOp
->getRHS()->getExprLoc();
11358 NoteRange
= ErrorRange
= AtomicBinOp
->getRHS()->getSourceRange();
11359 ErrorFound
= NotABinaryExpression
;
11362 ErrorLoc
= AtomicBinOp
->getExprLoc();
11363 ErrorRange
= AtomicBinOp
->getSourceRange();
11364 NoteLoc
= AtomicBinOp
->getOperatorLoc();
11365 NoteRange
= SourceRange(NoteLoc
, NoteLoc
);
11366 ErrorFound
= NotAnAssignmentOp
;
11368 if (ErrorFound
!= NoError
&& DiagId
!= 0 && NoteId
!= 0) {
11369 SemaRef
.Diag(ErrorLoc
, DiagId
) << ErrorRange
;
11370 SemaRef
.Diag(NoteLoc
, NoteId
) << ErrorFound
<< NoteRange
;
11373 if (SemaRef
.CurContext
->isDependentContext())
11374 E
= X
= UpdateExpr
= nullptr;
11375 return ErrorFound
!= NoError
;
11378 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt
*S
, unsigned DiagId
,
11380 ExprAnalysisErrorCode ErrorFound
= NoError
;
11381 SourceLocation ErrorLoc
, NoteLoc
;
11382 SourceRange ErrorRange
, NoteRange
;
11383 // Allowed constructs are:
11389 // x = x binop expr;
11390 // x = expr binop x;
11391 if (auto *AtomicBody
= dyn_cast
<Expr
>(S
)) {
11392 AtomicBody
= AtomicBody
->IgnoreParenImpCasts();
11393 if (AtomicBody
->getType()->isScalarType() ||
11394 AtomicBody
->isInstantiationDependent()) {
11395 if (const auto *AtomicCompAssignOp
= dyn_cast
<CompoundAssignOperator
>(
11396 AtomicBody
->IgnoreParenImpCasts())) {
11397 // Check for Compound Assignment Operation
11398 Op
= BinaryOperator::getOpForCompoundAssignment(
11399 AtomicCompAssignOp
->getOpcode());
11400 OpLoc
= AtomicCompAssignOp
->getOperatorLoc();
11401 E
= AtomicCompAssignOp
->getRHS();
11402 X
= AtomicCompAssignOp
->getLHS()->IgnoreParens();
11403 IsXLHSInRHSPart
= true;
11404 } else if (auto *AtomicBinOp
= dyn_cast
<BinaryOperator
>(
11405 AtomicBody
->IgnoreParenImpCasts())) {
11406 // Check for Binary Operation
11407 if (checkBinaryOperation(AtomicBinOp
, DiagId
, NoteId
))
11409 } else if (const auto *AtomicUnaryOp
= dyn_cast
<UnaryOperator
>(
11410 AtomicBody
->IgnoreParenImpCasts())) {
11411 // Check for Unary Operation
11412 if (AtomicUnaryOp
->isIncrementDecrementOp()) {
11413 IsPostfixUpdate
= AtomicUnaryOp
->isPostfix();
11414 Op
= AtomicUnaryOp
->isIncrementOp() ? BO_Add
: BO_Sub
;
11415 OpLoc
= AtomicUnaryOp
->getOperatorLoc();
11416 X
= AtomicUnaryOp
->getSubExpr()->IgnoreParens();
11417 E
= SemaRef
.ActOnIntegerConstant(OpLoc
, /*uint64_t Val=*/1).get();
11418 IsXLHSInRHSPart
= true;
11420 ErrorFound
= NotAnUnaryIncDecExpression
;
11421 ErrorLoc
= AtomicUnaryOp
->getExprLoc();
11422 ErrorRange
= AtomicUnaryOp
->getSourceRange();
11423 NoteLoc
= AtomicUnaryOp
->getOperatorLoc();
11424 NoteRange
= SourceRange(NoteLoc
, NoteLoc
);
11426 } else if (!AtomicBody
->isInstantiationDependent()) {
11427 ErrorFound
= NotABinaryOrUnaryExpression
;
11428 NoteLoc
= ErrorLoc
= AtomicBody
->getExprLoc();
11429 NoteRange
= ErrorRange
= AtomicBody
->getSourceRange();
11432 ErrorFound
= NotAScalarType
;
11433 NoteLoc
= ErrorLoc
= AtomicBody
->getBeginLoc();
11434 NoteRange
= ErrorRange
= SourceRange(NoteLoc
, NoteLoc
);
11437 ErrorFound
= NotAnExpression
;
11438 NoteLoc
= ErrorLoc
= S
->getBeginLoc();
11439 NoteRange
= ErrorRange
= SourceRange(NoteLoc
, NoteLoc
);
11441 if (ErrorFound
!= NoError
&& DiagId
!= 0 && NoteId
!= 0) {
11442 SemaRef
.Diag(ErrorLoc
, DiagId
) << ErrorRange
;
11443 SemaRef
.Diag(NoteLoc
, NoteId
) << ErrorFound
<< NoteRange
;
11446 if (SemaRef
.CurContext
->isDependentContext())
11447 E
= X
= UpdateExpr
= nullptr;
11448 if (ErrorFound
== NoError
&& E
&& X
) {
11449 // Build an update expression of form 'OpaqueValueExpr(x) binop
11450 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11451 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11452 auto *OVEX
= new (SemaRef
.getASTContext())
11453 OpaqueValueExpr(X
->getExprLoc(), X
->getType(), VK_PRValue
);
11454 auto *OVEExpr
= new (SemaRef
.getASTContext())
11455 OpaqueValueExpr(E
->getExprLoc(), E
->getType(), VK_PRValue
);
11456 ExprResult Update
=
11457 SemaRef
.CreateBuiltinBinOp(OpLoc
, Op
, IsXLHSInRHSPart
? OVEX
: OVEExpr
,
11458 IsXLHSInRHSPart
? OVEExpr
: OVEX
);
11459 if (Update
.isInvalid())
11461 Update
= SemaRef
.PerformImplicitConversion(Update
.get(), X
->getType(),
11463 if (Update
.isInvalid())
11465 UpdateExpr
= Update
.get();
11467 return ErrorFound
!= NoError
;
11470 /// Get the node id of the fixed point of an expression \a S.
11471 llvm::FoldingSetNodeID
getNodeId(ASTContext
&Context
, const Expr
*S
) {
11472 llvm::FoldingSetNodeID Id
;
11473 S
->IgnoreParenImpCasts()->Profile(Id
, Context
, true);
11477 /// Check if two expressions are same.
11478 bool checkIfTwoExprsAreSame(ASTContext
&Context
, const Expr
*LHS
,
11480 return getNodeId(Context
, LHS
) == getNodeId(Context
, RHS
);
11483 class OpenMPAtomicCompareChecker
{
11485 /// All kinds of errors that can occur in `atomic compare`
11487 /// Empty compound statement.
11489 /// More than one statement in a compound statement.
11491 /// Not an assignment binary operator.
11493 /// Not a conditional operator.
11495 /// Wrong false expr. According to the spec, 'x' should be at the false
11496 /// expression of a conditional expression.
11498 /// The condition of a conditional expression is not a binary operator.
11500 /// Invalid binary operator (not <, >, or ==).
11502 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11504 /// X is not a lvalue.
11508 /// Not an integer.
11510 /// 'else' statement is not expected.
11512 /// Not an equality operator.
11514 /// Invalid assignment (not v == x).
11516 /// Not if statement
11518 /// More than two statements in a compund statement.
11520 /// Not a compound statement.
11522 /// No else statement.
11530 struct ErrorInfoTy
{
11532 SourceLocation ErrorLoc
;
11533 SourceRange ErrorRange
;
11534 SourceLocation NoteLoc
;
11535 SourceRange NoteRange
;
11538 OpenMPAtomicCompareChecker(Sema
&S
) : ContextRef(S
.getASTContext()) {}
11540 /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11541 bool checkStmt(Stmt
*S
, ErrorInfoTy
&ErrorInfo
);
11543 Expr
*getX() const { return X
; }
11544 Expr
*getE() const { return E
; }
11545 Expr
*getD() const { return D
; }
11546 Expr
*getCond() const { return C
; }
11547 bool isXBinopExpr() const { return IsXBinopExpr
; }
11550 /// Reference to ASTContext
11551 ASTContext
&ContextRef
;
11552 /// 'x' lvalue part of the source atomic expression.
11554 /// 'expr' or 'e' rvalue part of the source atomic expression.
11556 /// 'd' rvalue part of the source atomic expression.
11558 /// 'cond' part of the source atomic expression. It is in one of the following
11565 /// True if the cond expr is in the form of 'x ordop expr'.
11566 bool IsXBinopExpr
= true;
11568 /// Check if it is a valid conditional update statement (cond-update-stmt).
11569 bool checkCondUpdateStmt(IfStmt
*S
, ErrorInfoTy
&ErrorInfo
);
11571 /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11572 bool checkCondExprStmt(Stmt
*S
, ErrorInfoTy
&ErrorInfo
);
11574 /// Check if all captured values have right type.
11575 bool checkType(ErrorInfoTy
&ErrorInfo
) const;
11577 static bool CheckValue(const Expr
*E
, ErrorInfoTy
&ErrorInfo
,
11578 bool ShouldBeLValue
, bool ShouldBeInteger
= false) {
11579 if (ShouldBeLValue
&& !E
->isLValue()) {
11580 ErrorInfo
.Error
= ErrorTy::XNotLValue
;
11581 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= E
->getExprLoc();
11582 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= E
->getSourceRange();
11586 if (!E
->isInstantiationDependent()) {
11587 QualType QTy
= E
->getType();
11588 if (!QTy
->isScalarType()) {
11589 ErrorInfo
.Error
= ErrorTy::NotScalar
;
11590 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= E
->getExprLoc();
11591 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= E
->getSourceRange();
11594 if (ShouldBeInteger
&& !QTy
->isIntegerType()) {
11595 ErrorInfo
.Error
= ErrorTy::NotInteger
;
11596 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= E
->getExprLoc();
11597 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= E
->getSourceRange();
11606 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt
*S
,
11607 ErrorInfoTy
&ErrorInfo
) {
11608 auto *Then
= S
->getThen();
11609 if (auto *CS
= dyn_cast
<CompoundStmt
>(Then
)) {
11610 if (CS
->body_empty()) {
11611 ErrorInfo
.Error
= ErrorTy::NoStmt
;
11612 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11613 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11616 if (CS
->size() > 1) {
11617 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
11618 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11619 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getSourceRange();
11622 Then
= CS
->body_front();
11625 auto *BO
= dyn_cast
<BinaryOperator
>(Then
);
11627 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11628 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Then
->getBeginLoc();
11629 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Then
->getSourceRange();
11632 if (BO
->getOpcode() != BO_Assign
) {
11633 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11634 ErrorInfo
.ErrorLoc
= BO
->getExprLoc();
11635 ErrorInfo
.NoteLoc
= BO
->getOperatorLoc();
11636 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
11642 auto *Cond
= dyn_cast
<BinaryOperator
>(S
->getCond());
11644 ErrorInfo
.Error
= ErrorTy::NotABinaryOp
;
11645 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getCond()->getExprLoc();
11646 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getCond()->getSourceRange();
11650 switch (Cond
->getOpcode()) {
11654 if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getLHS())) {
11655 E
= Cond
->getRHS();
11656 } else if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getRHS())) {
11657 E
= Cond
->getLHS();
11659 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
11660 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11661 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11669 if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getLHS()) &&
11670 checkIfTwoExprsAreSame(ContextRef
, E
, Cond
->getRHS())) {
11672 } else if (checkIfTwoExprsAreSame(ContextRef
, E
, Cond
->getLHS()) &&
11673 checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getRHS())) {
11675 IsXBinopExpr
= false;
11677 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
11678 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11679 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11685 ErrorInfo
.Error
= ErrorTy::InvalidBinaryOp
;
11686 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11687 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11691 if (S
->getElse()) {
11692 ErrorInfo
.Error
= ErrorTy::UnexpectedElse
;
11693 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getElse()->getBeginLoc();
11694 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getElse()->getSourceRange();
11701 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt
*S
,
11702 ErrorInfoTy
&ErrorInfo
) {
11703 auto *BO
= dyn_cast
<BinaryOperator
>(S
);
11705 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11706 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getBeginLoc();
11707 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getSourceRange();
11710 if (BO
->getOpcode() != BO_Assign
) {
11711 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11712 ErrorInfo
.ErrorLoc
= BO
->getExprLoc();
11713 ErrorInfo
.NoteLoc
= BO
->getOperatorLoc();
11714 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
11720 auto *CO
= dyn_cast
<ConditionalOperator
>(BO
->getRHS()->IgnoreParenImpCasts());
11722 ErrorInfo
.Error
= ErrorTy::NotCondOp
;
11723 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= BO
->getRHS()->getExprLoc();
11724 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getRHS()->getSourceRange();
11728 if (!checkIfTwoExprsAreSame(ContextRef
, X
, CO
->getFalseExpr())) {
11729 ErrorInfo
.Error
= ErrorTy::WrongFalseExpr
;
11730 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CO
->getFalseExpr()->getExprLoc();
11731 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
=
11732 CO
->getFalseExpr()->getSourceRange();
11736 auto *Cond
= dyn_cast
<BinaryOperator
>(CO
->getCond());
11738 ErrorInfo
.Error
= ErrorTy::NotABinaryOp
;
11739 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CO
->getCond()->getExprLoc();
11740 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
=
11741 CO
->getCond()->getSourceRange();
11745 switch (Cond
->getOpcode()) {
11748 D
= CO
->getTrueExpr();
11749 if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getLHS())) {
11750 E
= Cond
->getRHS();
11751 } else if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getRHS())) {
11752 E
= Cond
->getLHS();
11754 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
11755 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11756 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11763 E
= CO
->getTrueExpr();
11764 if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getLHS()) &&
11765 checkIfTwoExprsAreSame(ContextRef
, E
, Cond
->getRHS())) {
11767 } else if (checkIfTwoExprsAreSame(ContextRef
, E
, Cond
->getLHS()) &&
11768 checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getRHS())) {
11770 IsXBinopExpr
= false;
11772 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
11773 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11774 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11780 ErrorInfo
.Error
= ErrorTy::InvalidBinaryOp
;
11781 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11782 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11789 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy
&ErrorInfo
) const {
11790 // 'x' and 'e' cannot be nullptr
11791 assert(X
&& E
&& "X and E cannot be nullptr");
11793 if (!CheckValue(X
, ErrorInfo
, true))
11796 if (!CheckValue(E
, ErrorInfo
, false))
11799 if (D
&& !CheckValue(D
, ErrorInfo
, false))
11805 bool OpenMPAtomicCompareChecker::checkStmt(
11806 Stmt
*S
, OpenMPAtomicCompareChecker::ErrorInfoTy
&ErrorInfo
) {
11807 auto *CS
= dyn_cast
<CompoundStmt
>(S
);
11809 if (CS
->body_empty()) {
11810 ErrorInfo
.Error
= ErrorTy::NoStmt
;
11811 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11812 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11816 if (CS
->size() != 1) {
11817 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
11818 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11819 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11822 S
= CS
->body_front();
11827 if (auto *IS
= dyn_cast
<IfStmt
>(S
)) {
11828 // Check if the statement is in one of the following forms
11829 // (cond-update-stmt):
11830 // if (expr ordop x) { x = expr; }
11831 // if (x ordop expr) { x = expr; }
11832 // if (x == e) { x = d; }
11833 Res
= checkCondUpdateStmt(IS
, ErrorInfo
);
11835 // Check if the statement is in one of the following forms (cond-expr-stmt):
11836 // x = expr ordop x ? expr : x;
11837 // x = x ordop expr ? expr : x;
11838 // x = x == e ? d : x;
11839 Res
= checkCondExprStmt(S
, ErrorInfo
);
11845 return checkType(ErrorInfo
);
11848 class OpenMPAtomicCompareCaptureChecker final
11849 : public OpenMPAtomicCompareChecker
{
11851 OpenMPAtomicCompareCaptureChecker(Sema
&S
) : OpenMPAtomicCompareChecker(S
) {}
11853 Expr
*getV() const { return V
; }
11854 Expr
*getR() const { return R
; }
11855 bool isFailOnly() const { return IsFailOnly
; }
11856 bool isPostfixUpdate() const { return IsPostfixUpdate
; }
11858 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11859 bool checkStmt(Stmt
*S
, ErrorInfoTy
&ErrorInfo
);
11862 bool checkType(ErrorInfoTy
&ErrorInfo
);
11864 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11865 // form of 'conditional-update-capture-atomic' structured block on the v5.2
11867 // (1) { v = x; cond-update-stmt }
11868 // (2) { cond-update-stmt v = x; }
11869 // (3) if(x == e) { x = d; } else { v = x; }
11870 // (4) { r = x == e; if(r) { x = d; } }
11871 // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11873 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11874 bool checkForm3(IfStmt
*S
, ErrorInfoTy
&ErrorInfo
);
11876 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11877 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11878 bool checkForm45(Stmt
*S
, ErrorInfoTy
&ErrorInfo
);
11880 /// 'v' lvalue part of the source atomic expression.
11882 /// 'r' lvalue part of the source atomic expression.
11884 /// If 'v' is only updated when the comparison fails.
11885 bool IsFailOnly
= false;
11886 /// If original value of 'x' must be stored in 'v', not an updated one.
11887 bool IsPostfixUpdate
= false;
11890 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy
&ErrorInfo
) {
11891 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo
))
11894 if (V
&& !CheckValue(V
, ErrorInfo
, true))
11897 if (R
&& !CheckValue(R
, ErrorInfo
, true, true))
11903 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt
*S
,
11904 ErrorInfoTy
&ErrorInfo
) {
11907 auto *Then
= S
->getThen();
11908 if (auto *CS
= dyn_cast
<CompoundStmt
>(Then
)) {
11909 if (CS
->body_empty()) {
11910 ErrorInfo
.Error
= ErrorTy::NoStmt
;
11911 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11912 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11915 if (CS
->size() > 1) {
11916 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
11917 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11918 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11921 Then
= CS
->body_front();
11924 auto *BO
= dyn_cast
<BinaryOperator
>(Then
);
11926 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11927 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Then
->getBeginLoc();
11928 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Then
->getSourceRange();
11931 if (BO
->getOpcode() != BO_Assign
) {
11932 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11933 ErrorInfo
.ErrorLoc
= BO
->getExprLoc();
11934 ErrorInfo
.NoteLoc
= BO
->getOperatorLoc();
11935 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
11942 auto *Cond
= dyn_cast
<BinaryOperator
>(S
->getCond());
11944 ErrorInfo
.Error
= ErrorTy::NotABinaryOp
;
11945 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getCond()->getExprLoc();
11946 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getCond()->getSourceRange();
11949 if (Cond
->getOpcode() != BO_EQ
) {
11950 ErrorInfo
.Error
= ErrorTy::NotEQ
;
11951 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11952 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11956 if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getLHS())) {
11957 E
= Cond
->getRHS();
11958 } else if (checkIfTwoExprsAreSame(ContextRef
, X
, Cond
->getRHS())) {
11959 E
= Cond
->getLHS();
11961 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
11962 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Cond
->getExprLoc();
11963 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Cond
->getSourceRange();
11969 if (!S
->getElse()) {
11970 ErrorInfo
.Error
= ErrorTy::NoElse
;
11971 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getBeginLoc();
11972 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getSourceRange();
11976 auto *Else
= S
->getElse();
11977 if (auto *CS
= dyn_cast
<CompoundStmt
>(Else
)) {
11978 if (CS
->body_empty()) {
11979 ErrorInfo
.Error
= ErrorTy::NoStmt
;
11980 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11981 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
11984 if (CS
->size() > 1) {
11985 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
11986 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
11987 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getSourceRange();
11990 Else
= CS
->body_front();
11993 auto *ElseBO
= dyn_cast
<BinaryOperator
>(Else
);
11995 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
11996 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Else
->getBeginLoc();
11997 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Else
->getSourceRange();
12000 if (ElseBO
->getOpcode() != BO_Assign
) {
12001 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12002 ErrorInfo
.ErrorLoc
= ElseBO
->getExprLoc();
12003 ErrorInfo
.NoteLoc
= ElseBO
->getOperatorLoc();
12004 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ElseBO
->getSourceRange();
12008 if (!checkIfTwoExprsAreSame(ContextRef
, X
, ElseBO
->getRHS())) {
12009 ErrorInfo
.Error
= ErrorTy::InvalidAssignment
;
12010 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= ElseBO
->getRHS()->getExprLoc();
12011 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
=
12012 ElseBO
->getRHS()->getSourceRange();
12016 V
= ElseBO
->getLHS();
12018 return checkType(ErrorInfo
);
12021 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt
*S
,
12022 ErrorInfoTy
&ErrorInfo
) {
12023 // We don't check here as they should be already done before call this
12025 auto *CS
= cast
<CompoundStmt
>(S
);
12026 assert(CS
->size() == 2 && "CompoundStmt size is not expected");
12027 auto *S1
= cast
<BinaryOperator
>(CS
->body_front());
12028 auto *S2
= cast
<IfStmt
>(CS
->body_back());
12029 assert(S1
->getOpcode() == BO_Assign
&& "unexpected binary operator");
12031 if (!checkIfTwoExprsAreSame(ContextRef
, S1
->getLHS(), S2
->getCond())) {
12032 ErrorInfo
.Error
= ErrorTy::InvalidCondition
;
12033 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S2
->getCond()->getExprLoc();
12034 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S1
->getLHS()->getSourceRange();
12040 auto *Then
= S2
->getThen();
12041 if (auto *ThenCS
= dyn_cast
<CompoundStmt
>(Then
)) {
12042 if (ThenCS
->body_empty()) {
12043 ErrorInfo
.Error
= ErrorTy::NoStmt
;
12044 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= ThenCS
->getBeginLoc();
12045 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ThenCS
->getSourceRange();
12048 if (ThenCS
->size() > 1) {
12049 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
12050 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= ThenCS
->getBeginLoc();
12051 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ThenCS
->getSourceRange();
12054 Then
= ThenCS
->body_front();
12057 auto *ThenBO
= dyn_cast
<BinaryOperator
>(Then
);
12059 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12060 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S2
->getBeginLoc();
12061 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S2
->getSourceRange();
12064 if (ThenBO
->getOpcode() != BO_Assign
) {
12065 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12066 ErrorInfo
.ErrorLoc
= ThenBO
->getExprLoc();
12067 ErrorInfo
.NoteLoc
= ThenBO
->getOperatorLoc();
12068 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ThenBO
->getSourceRange();
12072 X
= ThenBO
->getLHS();
12073 D
= ThenBO
->getRHS();
12075 auto *BO
= cast
<BinaryOperator
>(S1
->getRHS()->IgnoreImpCasts());
12076 if (BO
->getOpcode() != BO_EQ
) {
12077 ErrorInfo
.Error
= ErrorTy::NotEQ
;
12078 ErrorInfo
.ErrorLoc
= BO
->getExprLoc();
12079 ErrorInfo
.NoteLoc
= BO
->getOperatorLoc();
12080 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
12086 if (checkIfTwoExprsAreSame(ContextRef
, X
, BO
->getLHS())) {
12088 } else if (checkIfTwoExprsAreSame(ContextRef
, X
, BO
->getRHS())) {
12091 ErrorInfo
.Error
= ErrorTy::InvalidComparison
;
12092 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= BO
->getExprLoc();
12093 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
12097 if (S2
->getElse()) {
12100 auto *Else
= S2
->getElse();
12101 if (auto *ElseCS
= dyn_cast
<CompoundStmt
>(Else
)) {
12102 if (ElseCS
->body_empty()) {
12103 ErrorInfo
.Error
= ErrorTy::NoStmt
;
12104 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= ElseCS
->getBeginLoc();
12105 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ElseCS
->getSourceRange();
12108 if (ElseCS
->size() > 1) {
12109 ErrorInfo
.Error
= ErrorTy::MoreThanOneStmt
;
12110 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= ElseCS
->getBeginLoc();
12111 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ElseCS
->getSourceRange();
12114 Else
= ElseCS
->body_front();
12117 auto *ElseBO
= dyn_cast
<BinaryOperator
>(Else
);
12119 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12120 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= Else
->getBeginLoc();
12121 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= Else
->getSourceRange();
12124 if (ElseBO
->getOpcode() != BO_Assign
) {
12125 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12126 ErrorInfo
.ErrorLoc
= ElseBO
->getExprLoc();
12127 ErrorInfo
.NoteLoc
= ElseBO
->getOperatorLoc();
12128 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= ElseBO
->getSourceRange();
12131 if (!checkIfTwoExprsAreSame(ContextRef
, X
, ElseBO
->getRHS())) {
12132 ErrorInfo
.Error
= ErrorTy::InvalidAssignment
;
12133 ErrorInfo
.ErrorLoc
= ElseBO
->getRHS()->getExprLoc();
12134 ErrorInfo
.NoteLoc
= X
->getExprLoc();
12135 ErrorInfo
.ErrorRange
= ElseBO
->getRHS()->getSourceRange();
12136 ErrorInfo
.NoteRange
= X
->getSourceRange();
12140 V
= ElseBO
->getLHS();
12143 return checkType(ErrorInfo
);
12146 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt
*S
,
12147 ErrorInfoTy
&ErrorInfo
) {
12148 // if(x == e) { x = d; } else { v = x; }
12149 if (auto *IS
= dyn_cast
<IfStmt
>(S
))
12150 return checkForm3(IS
, ErrorInfo
);
12152 auto *CS
= dyn_cast
<CompoundStmt
>(S
);
12154 ErrorInfo
.Error
= ErrorTy::NotCompoundStmt
;
12155 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= S
->getBeginLoc();
12156 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= S
->getSourceRange();
12159 if (CS
->body_empty()) {
12160 ErrorInfo
.Error
= ErrorTy::NoStmt
;
12161 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
12162 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
12166 // { if(x == e) { x = d; } else { v = x; } }
12167 if (CS
->size() == 1) {
12168 auto *IS
= dyn_cast
<IfStmt
>(CS
->body_front());
12170 ErrorInfo
.Error
= ErrorTy::NotIfStmt
;
12171 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->body_front()->getBeginLoc();
12172 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
=
12173 CS
->body_front()->getSourceRange();
12177 return checkForm3(IS
, ErrorInfo
);
12178 } else if (CS
->size() == 2) {
12179 auto *S1
= CS
->body_front();
12180 auto *S2
= CS
->body_back();
12182 Stmt
*UpdateStmt
= nullptr;
12183 Stmt
*CondUpdateStmt
= nullptr;
12185 if (auto *BO
= dyn_cast
<BinaryOperator
>(S1
)) {
12186 // { v = x; cond-update-stmt } or form 45.
12188 CondUpdateStmt
= S2
;
12189 // Check if form 45.
12190 if (isa
<BinaryOperator
>(BO
->getRHS()->IgnoreImpCasts()) &&
12192 return checkForm45(CS
, ErrorInfo
);
12193 // It cannot be set before we the check for form45.
12194 IsPostfixUpdate
= true;
12196 // { cond-update-stmt v = x; }
12198 CondUpdateStmt
= S1
;
12201 auto CheckCondUpdateStmt
= [this, &ErrorInfo
](Stmt
*CUS
) {
12202 auto *IS
= dyn_cast
<IfStmt
>(CUS
);
12204 ErrorInfo
.Error
= ErrorTy::NotIfStmt
;
12205 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CUS
->getBeginLoc();
12206 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CUS
->getSourceRange();
12210 if (!checkCondUpdateStmt(IS
, ErrorInfo
))
12216 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12217 auto CheckUpdateStmt
= [this, &ErrorInfo
](Stmt
*US
) {
12218 auto *BO
= dyn_cast
<BinaryOperator
>(US
);
12220 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12221 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= US
->getBeginLoc();
12222 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= US
->getSourceRange();
12225 if (BO
->getOpcode() != BO_Assign
) {
12226 ErrorInfo
.Error
= ErrorTy::NotAnAssignment
;
12227 ErrorInfo
.ErrorLoc
= BO
->getExprLoc();
12228 ErrorInfo
.NoteLoc
= BO
->getOperatorLoc();
12229 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= BO
->getSourceRange();
12232 if (!checkIfTwoExprsAreSame(ContextRef
, this->X
, BO
->getRHS())) {
12233 ErrorInfo
.Error
= ErrorTy::InvalidAssignment
;
12234 ErrorInfo
.ErrorLoc
= BO
->getRHS()->getExprLoc();
12235 ErrorInfo
.NoteLoc
= this->X
->getExprLoc();
12236 ErrorInfo
.ErrorRange
= BO
->getRHS()->getSourceRange();
12237 ErrorInfo
.NoteRange
= this->X
->getSourceRange();
12241 this->V
= BO
->getLHS();
12246 if (!CheckCondUpdateStmt(CondUpdateStmt
))
12248 if (!CheckUpdateStmt(UpdateStmt
))
12251 ErrorInfo
.Error
= ErrorTy::MoreThanTwoStmts
;
12252 ErrorInfo
.ErrorLoc
= ErrorInfo
.NoteLoc
= CS
->getBeginLoc();
12253 ErrorInfo
.ErrorRange
= ErrorInfo
.NoteRange
= CS
->getSourceRange();
12257 return checkType(ErrorInfo
);
12261 StmtResult
Sema::ActOnOpenMPAtomicDirective(ArrayRef
<OMPClause
*> Clauses
,
12263 SourceLocation StartLoc
,
12264 SourceLocation EndLoc
) {
12265 // Register location of the first atomic directive.
12266 DSAStack
->addAtomicDirectiveLoc(StartLoc
);
12268 return StmtError();
12270 // 1.2.2 OpenMP Language Terminology
12271 // Structured block - An executable statement with a single entry at the
12272 // top and a single exit at the bottom.
12273 // The point of exit cannot be a branch out of the structured block.
12274 // longjmp() and throw() must not violate the entry/exit criteria.
12275 OpenMPClauseKind AtomicKind
= OMPC_unknown
;
12276 SourceLocation AtomicKindLoc
;
12277 OpenMPClauseKind MemOrderKind
= OMPC_unknown
;
12278 SourceLocation MemOrderLoc
;
12279 bool MutexClauseEncountered
= false;
12280 llvm::SmallSet
<OpenMPClauseKind
, 2> EncounteredAtomicKinds
;
12281 for (const OMPClause
*C
: Clauses
) {
12282 switch (C
->getClauseKind()) {
12286 MutexClauseEncountered
= true;
12289 case OMPC_compare
: {
12290 if (AtomicKind
!= OMPC_unknown
&& MutexClauseEncountered
) {
12291 Diag(C
->getBeginLoc(), diag::err_omp_atomic_several_clauses
)
12292 << SourceRange(C
->getBeginLoc(), C
->getEndLoc());
12293 Diag(AtomicKindLoc
, diag::note_omp_previous_mem_order_clause
)
12294 << getOpenMPClauseName(AtomicKind
);
12296 AtomicKind
= C
->getClauseKind();
12297 AtomicKindLoc
= C
->getBeginLoc();
12298 if (!EncounteredAtomicKinds
.insert(C
->getClauseKind()).second
) {
12299 Diag(C
->getBeginLoc(), diag::err_omp_atomic_several_clauses
)
12300 << SourceRange(C
->getBeginLoc(), C
->getEndLoc());
12301 Diag(AtomicKindLoc
, diag::note_omp_previous_mem_order_clause
)
12302 << getOpenMPClauseName(AtomicKind
);
12311 case OMPC_relaxed
: {
12312 if (MemOrderKind
!= OMPC_unknown
) {
12313 Diag(C
->getBeginLoc(), diag::err_omp_several_mem_order_clauses
)
12314 << getOpenMPDirectiveName(OMPD_atomic
) << 0
12315 << SourceRange(C
->getBeginLoc(), C
->getEndLoc());
12316 Diag(MemOrderLoc
, diag::note_omp_previous_mem_order_clause
)
12317 << getOpenMPClauseName(MemOrderKind
);
12319 MemOrderKind
= C
->getClauseKind();
12320 MemOrderLoc
= C
->getBeginLoc();
12324 // The following clauses are allowed, but we don't need to do anything here.
12328 llvm_unreachable("unknown clause is encountered");
12331 bool IsCompareCapture
= false;
12332 if (EncounteredAtomicKinds
.contains(OMPC_compare
) &&
12333 EncounteredAtomicKinds
.contains(OMPC_capture
)) {
12334 IsCompareCapture
= true;
12335 AtomicKind
= OMPC_compare
;
12337 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12338 // If atomic-clause is read then memory-order-clause must not be acq_rel or
12340 // If atomic-clause is write then memory-order-clause must not be acq_rel or
12342 // If atomic-clause is update or not present then memory-order-clause must not
12343 // be acq_rel or acquire.
12344 if ((AtomicKind
== OMPC_read
&&
12345 (MemOrderKind
== OMPC_acq_rel
|| MemOrderKind
== OMPC_release
)) ||
12346 ((AtomicKind
== OMPC_write
|| AtomicKind
== OMPC_update
||
12347 AtomicKind
== OMPC_unknown
) &&
12348 (MemOrderKind
== OMPC_acq_rel
|| MemOrderKind
== OMPC_acquire
))) {
12349 SourceLocation Loc
= AtomicKindLoc
;
12350 if (AtomicKind
== OMPC_unknown
)
12352 Diag(Loc
, diag::err_omp_atomic_incompatible_mem_order_clause
)
12353 << getOpenMPClauseName(AtomicKind
)
12354 << (AtomicKind
== OMPC_unknown
? 1 : 0)
12355 << getOpenMPClauseName(MemOrderKind
);
12356 Diag(MemOrderLoc
, diag::note_omp_previous_mem_order_clause
)
12357 << getOpenMPClauseName(MemOrderKind
);
12360 Stmt
*Body
= AStmt
;
12361 if (auto *EWC
= dyn_cast
<ExprWithCleanups
>(Body
))
12362 Body
= EWC
->getSubExpr();
12367 Expr
*UE
= nullptr;
12369 Expr
*CE
= nullptr;
12371 bool IsXLHSInRHSPart
= false;
12372 bool IsPostfixUpdate
= false;
12373 bool IsFailOnly
= false;
12374 // OpenMP [2.12.6, atomic Construct]
12375 // In the next expressions:
12376 // * x and v (as applicable) are both l-value expressions with scalar type.
12377 // * During the execution of an atomic region, multiple syntactic
12378 // occurrences of x must designate the same storage location.
12379 // * Neither of v and expr (as applicable) may access the storage location
12380 // designated by x.
12381 // * Neither of x and expr (as applicable) may access the storage location
12382 // designated by v.
12383 // * expr is an expression with scalar type.
12384 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12385 // * binop, binop=, ++, and -- are not overloaded operators.
12386 // * The expression x binop expr must be numerically equivalent to x binop
12387 // (expr). This requirement is satisfied if the operators in expr have
12388 // precedence greater than binop, or by using parentheses around expr or
12389 // subexpressions of expr.
12390 // * The expression expr binop x must be numerically equivalent to (expr)
12391 // binop x. This requirement is satisfied if the operators in expr have
12392 // precedence equal to or greater than binop, or by using parentheses around
12393 // expr or subexpressions of expr.
12394 // * For forms that allow multiple occurrences of x, the number of times
12395 // that x is evaluated is unspecified.
12396 if (AtomicKind
== OMPC_read
) {
12403 } ErrorFound
= NoError
;
12404 SourceLocation ErrorLoc
, NoteLoc
;
12405 SourceRange ErrorRange
, NoteRange
;
12406 // If clause is read:
12408 if (const auto *AtomicBody
= dyn_cast
<Expr
>(Body
)) {
12409 const auto *AtomicBinOp
=
12410 dyn_cast
<BinaryOperator
>(AtomicBody
->IgnoreParenImpCasts());
12411 if (AtomicBinOp
&& AtomicBinOp
->getOpcode() == BO_Assign
) {
12412 X
= AtomicBinOp
->getRHS()->IgnoreParenImpCasts();
12413 V
= AtomicBinOp
->getLHS()->IgnoreParenImpCasts();
12414 if ((X
->isInstantiationDependent() || X
->getType()->isScalarType()) &&
12415 (V
->isInstantiationDependent() || V
->getType()->isScalarType())) {
12416 if (!X
->isLValue() || !V
->isLValue()) {
12417 const Expr
*NotLValueExpr
= X
->isLValue() ? V
: X
;
12418 ErrorFound
= NotAnLValue
;
12419 ErrorLoc
= AtomicBinOp
->getExprLoc();
12420 ErrorRange
= AtomicBinOp
->getSourceRange();
12421 NoteLoc
= NotLValueExpr
->getExprLoc();
12422 NoteRange
= NotLValueExpr
->getSourceRange();
12424 } else if (!X
->isInstantiationDependent() ||
12425 !V
->isInstantiationDependent()) {
12426 const Expr
*NotScalarExpr
=
12427 (X
->isInstantiationDependent() || X
->getType()->isScalarType())
12430 ErrorFound
= NotAScalarType
;
12431 ErrorLoc
= AtomicBinOp
->getExprLoc();
12432 ErrorRange
= AtomicBinOp
->getSourceRange();
12433 NoteLoc
= NotScalarExpr
->getExprLoc();
12434 NoteRange
= NotScalarExpr
->getSourceRange();
12436 } else if (!AtomicBody
->isInstantiationDependent()) {
12437 ErrorFound
= NotAnAssignmentOp
;
12438 ErrorLoc
= AtomicBody
->getExprLoc();
12439 ErrorRange
= AtomicBody
->getSourceRange();
12440 NoteLoc
= AtomicBinOp
? AtomicBinOp
->getOperatorLoc()
12441 : AtomicBody
->getExprLoc();
12442 NoteRange
= AtomicBinOp
? AtomicBinOp
->getSourceRange()
12443 : AtomicBody
->getSourceRange();
12446 ErrorFound
= NotAnExpression
;
12447 NoteLoc
= ErrorLoc
= Body
->getBeginLoc();
12448 NoteRange
= ErrorRange
= SourceRange(NoteLoc
, NoteLoc
);
12450 if (ErrorFound
!= NoError
) {
12451 Diag(ErrorLoc
, diag::err_omp_atomic_read_not_expression_statement
)
12453 Diag(NoteLoc
, diag::note_omp_atomic_read_write
)
12454 << ErrorFound
<< NoteRange
;
12455 return StmtError();
12457 if (CurContext
->isDependentContext())
12459 } else if (AtomicKind
== OMPC_write
) {
12466 } ErrorFound
= NoError
;
12467 SourceLocation ErrorLoc
, NoteLoc
;
12468 SourceRange ErrorRange
, NoteRange
;
12469 // If clause is write:
12471 if (const auto *AtomicBody
= dyn_cast
<Expr
>(Body
)) {
12472 const auto *AtomicBinOp
=
12473 dyn_cast
<BinaryOperator
>(AtomicBody
->IgnoreParenImpCasts());
12474 if (AtomicBinOp
&& AtomicBinOp
->getOpcode() == BO_Assign
) {
12475 X
= AtomicBinOp
->getLHS();
12476 E
= AtomicBinOp
->getRHS();
12477 if ((X
->isInstantiationDependent() || X
->getType()->isScalarType()) &&
12478 (E
->isInstantiationDependent() || E
->getType()->isScalarType())) {
12479 if (!X
->isLValue()) {
12480 ErrorFound
= NotAnLValue
;
12481 ErrorLoc
= AtomicBinOp
->getExprLoc();
12482 ErrorRange
= AtomicBinOp
->getSourceRange();
12483 NoteLoc
= X
->getExprLoc();
12484 NoteRange
= X
->getSourceRange();
12486 } else if (!X
->isInstantiationDependent() ||
12487 !E
->isInstantiationDependent()) {
12488 const Expr
*NotScalarExpr
=
12489 (X
->isInstantiationDependent() || X
->getType()->isScalarType())
12492 ErrorFound
= NotAScalarType
;
12493 ErrorLoc
= AtomicBinOp
->getExprLoc();
12494 ErrorRange
= AtomicBinOp
->getSourceRange();
12495 NoteLoc
= NotScalarExpr
->getExprLoc();
12496 NoteRange
= NotScalarExpr
->getSourceRange();
12498 } else if (!AtomicBody
->isInstantiationDependent()) {
12499 ErrorFound
= NotAnAssignmentOp
;
12500 ErrorLoc
= AtomicBody
->getExprLoc();
12501 ErrorRange
= AtomicBody
->getSourceRange();
12502 NoteLoc
= AtomicBinOp
? AtomicBinOp
->getOperatorLoc()
12503 : AtomicBody
->getExprLoc();
12504 NoteRange
= AtomicBinOp
? AtomicBinOp
->getSourceRange()
12505 : AtomicBody
->getSourceRange();
12508 ErrorFound
= NotAnExpression
;
12509 NoteLoc
= ErrorLoc
= Body
->getBeginLoc();
12510 NoteRange
= ErrorRange
= SourceRange(NoteLoc
, NoteLoc
);
12512 if (ErrorFound
!= NoError
) {
12513 Diag(ErrorLoc
, diag::err_omp_atomic_write_not_expression_statement
)
12515 Diag(NoteLoc
, diag::note_omp_atomic_read_write
)
12516 << ErrorFound
<< NoteRange
;
12517 return StmtError();
12519 if (CurContext
->isDependentContext())
12521 } else if (AtomicKind
== OMPC_update
|| AtomicKind
== OMPC_unknown
) {
12522 // If clause is update:
12528 // x = x binop expr;
12529 // x = expr binop x;
12530 OpenMPAtomicUpdateChecker
Checker(*this);
12531 if (Checker
.checkStatement(
12533 (AtomicKind
== OMPC_update
)
12534 ? diag::err_omp_atomic_update_not_expression_statement
12535 : diag::err_omp_atomic_not_expression_statement
,
12536 diag::note_omp_atomic_update
))
12537 return StmtError();
12538 if (!CurContext
->isDependentContext()) {
12539 E
= Checker
.getExpr();
12540 X
= Checker
.getX();
12541 UE
= Checker
.getUpdateExpr();
12542 IsXLHSInRHSPart
= Checker
.isXLHSInRHSPart();
12544 } else if (AtomicKind
== OMPC_capture
) {
12547 NotACompoundStatement
,
12548 NotTwoSubstatements
,
12549 NotASpecificExpression
,
12551 } ErrorFound
= NoError
;
12552 SourceLocation ErrorLoc
, NoteLoc
;
12553 SourceRange ErrorRange
, NoteRange
;
12554 if (const auto *AtomicBody
= dyn_cast
<Expr
>(Body
)) {
12555 // If clause is a capture:
12560 // v = x binop= expr;
12561 // v = x = x binop expr;
12562 // v = x = expr binop x;
12563 const auto *AtomicBinOp
=
12564 dyn_cast
<BinaryOperator
>(AtomicBody
->IgnoreParenImpCasts());
12565 if (AtomicBinOp
&& AtomicBinOp
->getOpcode() == BO_Assign
) {
12566 V
= AtomicBinOp
->getLHS();
12567 Body
= AtomicBinOp
->getRHS()->IgnoreParenImpCasts();
12568 OpenMPAtomicUpdateChecker
Checker(*this);
12569 if (Checker
.checkStatement(
12570 Body
, diag::err_omp_atomic_capture_not_expression_statement
,
12571 diag::note_omp_atomic_update
))
12572 return StmtError();
12573 E
= Checker
.getExpr();
12574 X
= Checker
.getX();
12575 UE
= Checker
.getUpdateExpr();
12576 IsXLHSInRHSPart
= Checker
.isXLHSInRHSPart();
12577 IsPostfixUpdate
= Checker
.isPostfixUpdate();
12578 } else if (!AtomicBody
->isInstantiationDependent()) {
12579 ErrorLoc
= AtomicBody
->getExprLoc();
12580 ErrorRange
= AtomicBody
->getSourceRange();
12581 NoteLoc
= AtomicBinOp
? AtomicBinOp
->getOperatorLoc()
12582 : AtomicBody
->getExprLoc();
12583 NoteRange
= AtomicBinOp
? AtomicBinOp
->getSourceRange()
12584 : AtomicBody
->getSourceRange();
12585 ErrorFound
= NotAnAssignmentOp
;
12587 if (ErrorFound
!= NoError
) {
12588 Diag(ErrorLoc
, diag::err_omp_atomic_capture_not_expression_statement
)
12590 Diag(NoteLoc
, diag::note_omp_atomic_capture
) << ErrorFound
<< NoteRange
;
12591 return StmtError();
12593 if (CurContext
->isDependentContext())
12594 UE
= V
= E
= X
= nullptr;
12596 // If clause is a capture:
12597 // { v = x; x = expr; }
12602 // { v = x; x binop= expr; }
12603 // { v = x; x = x binop expr; }
12604 // { v = x; x = expr binop x; }
12609 // { x binop= expr; v = x; }
12610 // { x = x binop expr; v = x; }
12611 // { x = expr binop x; v = x; }
12612 if (auto *CS
= dyn_cast
<CompoundStmt
>(Body
)) {
12613 // Check that this is { expr1; expr2; }
12614 if (CS
->size() == 2) {
12615 Stmt
*First
= CS
->body_front();
12616 Stmt
*Second
= CS
->body_back();
12617 if (auto *EWC
= dyn_cast
<ExprWithCleanups
>(First
))
12618 First
= EWC
->getSubExpr()->IgnoreParenImpCasts();
12619 if (auto *EWC
= dyn_cast
<ExprWithCleanups
>(Second
))
12620 Second
= EWC
->getSubExpr()->IgnoreParenImpCasts();
12621 // Need to find what subexpression is 'v' and what is 'x'.
12622 OpenMPAtomicUpdateChecker
Checker(*this);
12623 bool IsUpdateExprFound
= !Checker
.checkStatement(Second
);
12624 BinaryOperator
*BinOp
= nullptr;
12625 if (IsUpdateExprFound
) {
12626 BinOp
= dyn_cast
<BinaryOperator
>(First
);
12627 IsUpdateExprFound
= BinOp
&& BinOp
->getOpcode() == BO_Assign
;
12629 if (IsUpdateExprFound
&& !CurContext
->isDependentContext()) {
12634 // { v = x; x binop= expr; }
12635 // { v = x; x = x binop expr; }
12636 // { v = x; x = expr binop x; }
12637 // Check that the first expression has form v = x.
12638 Expr
*PossibleX
= BinOp
->getRHS()->IgnoreParenImpCasts();
12639 llvm::FoldingSetNodeID XId
, PossibleXId
;
12640 Checker
.getX()->Profile(XId
, Context
, /*Canonical=*/true);
12641 PossibleX
->Profile(PossibleXId
, Context
, /*Canonical=*/true);
12642 IsUpdateExprFound
= XId
== PossibleXId
;
12643 if (IsUpdateExprFound
) {
12644 V
= BinOp
->getLHS();
12645 X
= Checker
.getX();
12646 E
= Checker
.getExpr();
12647 UE
= Checker
.getUpdateExpr();
12648 IsXLHSInRHSPart
= Checker
.isXLHSInRHSPart();
12649 IsPostfixUpdate
= true;
12652 if (!IsUpdateExprFound
) {
12653 IsUpdateExprFound
= !Checker
.checkStatement(First
);
12655 if (IsUpdateExprFound
) {
12656 BinOp
= dyn_cast
<BinaryOperator
>(Second
);
12657 IsUpdateExprFound
= BinOp
&& BinOp
->getOpcode() == BO_Assign
;
12659 if (IsUpdateExprFound
&& !CurContext
->isDependentContext()) {
12664 // { x binop= expr; v = x; }
12665 // { x = x binop expr; v = x; }
12666 // { x = expr binop x; v = x; }
12667 // Check that the second expression has form v = x.
12668 Expr
*PossibleX
= BinOp
->getRHS()->IgnoreParenImpCasts();
12669 llvm::FoldingSetNodeID XId
, PossibleXId
;
12670 Checker
.getX()->Profile(XId
, Context
, /*Canonical=*/true);
12671 PossibleX
->Profile(PossibleXId
, Context
, /*Canonical=*/true);
12672 IsUpdateExprFound
= XId
== PossibleXId
;
12673 if (IsUpdateExprFound
) {
12674 V
= BinOp
->getLHS();
12675 X
= Checker
.getX();
12676 E
= Checker
.getExpr();
12677 UE
= Checker
.getUpdateExpr();
12678 IsXLHSInRHSPart
= Checker
.isXLHSInRHSPart();
12679 IsPostfixUpdate
= false;
12683 if (!IsUpdateExprFound
) {
12684 // { v = x; x = expr; }
12685 auto *FirstExpr
= dyn_cast
<Expr
>(First
);
12686 auto *SecondExpr
= dyn_cast
<Expr
>(Second
);
12687 if (!FirstExpr
|| !SecondExpr
||
12688 !(FirstExpr
->isInstantiationDependent() ||
12689 SecondExpr
->isInstantiationDependent())) {
12690 auto *FirstBinOp
= dyn_cast
<BinaryOperator
>(First
);
12691 if (!FirstBinOp
|| FirstBinOp
->getOpcode() != BO_Assign
) {
12692 ErrorFound
= NotAnAssignmentOp
;
12693 NoteLoc
= ErrorLoc
= FirstBinOp
? FirstBinOp
->getOperatorLoc()
12694 : First
->getBeginLoc();
12695 NoteRange
= ErrorRange
= FirstBinOp
12696 ? FirstBinOp
->getSourceRange()
12697 : SourceRange(ErrorLoc
, ErrorLoc
);
12699 auto *SecondBinOp
= dyn_cast
<BinaryOperator
>(Second
);
12700 if (!SecondBinOp
|| SecondBinOp
->getOpcode() != BO_Assign
) {
12701 ErrorFound
= NotAnAssignmentOp
;
12702 NoteLoc
= ErrorLoc
= SecondBinOp
12703 ? SecondBinOp
->getOperatorLoc()
12704 : Second
->getBeginLoc();
12705 NoteRange
= ErrorRange
=
12706 SecondBinOp
? SecondBinOp
->getSourceRange()
12707 : SourceRange(ErrorLoc
, ErrorLoc
);
12709 Expr
*PossibleXRHSInFirst
=
12710 FirstBinOp
->getRHS()->IgnoreParenImpCasts();
12711 Expr
*PossibleXLHSInSecond
=
12712 SecondBinOp
->getLHS()->IgnoreParenImpCasts();
12713 llvm::FoldingSetNodeID X1Id
, X2Id
;
12714 PossibleXRHSInFirst
->Profile(X1Id
, Context
,
12715 /*Canonical=*/true);
12716 PossibleXLHSInSecond
->Profile(X2Id
, Context
,
12717 /*Canonical=*/true);
12718 IsUpdateExprFound
= X1Id
== X2Id
;
12719 if (IsUpdateExprFound
) {
12720 V
= FirstBinOp
->getLHS();
12721 X
= SecondBinOp
->getLHS();
12722 E
= SecondBinOp
->getRHS();
12724 IsXLHSInRHSPart
= false;
12725 IsPostfixUpdate
= true;
12727 ErrorFound
= NotASpecificExpression
;
12728 ErrorLoc
= FirstBinOp
->getExprLoc();
12729 ErrorRange
= FirstBinOp
->getSourceRange();
12730 NoteLoc
= SecondBinOp
->getLHS()->getExprLoc();
12731 NoteRange
= SecondBinOp
->getRHS()->getSourceRange();
12738 NoteLoc
= ErrorLoc
= Body
->getBeginLoc();
12739 NoteRange
= ErrorRange
=
12740 SourceRange(Body
->getBeginLoc(), Body
->getBeginLoc());
12741 ErrorFound
= NotTwoSubstatements
;
12744 NoteLoc
= ErrorLoc
= Body
->getBeginLoc();
12745 NoteRange
= ErrorRange
=
12746 SourceRange(Body
->getBeginLoc(), Body
->getBeginLoc());
12747 ErrorFound
= NotACompoundStatement
;
12750 if (ErrorFound
!= NoError
) {
12751 Diag(ErrorLoc
, diag::err_omp_atomic_capture_not_compound_statement
)
12753 Diag(NoteLoc
, diag::note_omp_atomic_capture
) << ErrorFound
<< NoteRange
;
12754 return StmtError();
12756 if (CurContext
->isDependentContext())
12757 UE
= V
= E
= X
= nullptr;
12758 } else if (AtomicKind
== OMPC_compare
) {
12759 if (IsCompareCapture
) {
12760 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo
;
12761 OpenMPAtomicCompareCaptureChecker
Checker(*this);
12762 if (!Checker
.checkStmt(Body
, ErrorInfo
)) {
12763 Diag(ErrorInfo
.ErrorLoc
, diag::err_omp_atomic_compare_capture
)
12764 << ErrorInfo
.ErrorRange
;
12765 Diag(ErrorInfo
.NoteLoc
, diag::note_omp_atomic_compare
)
12766 << ErrorInfo
.Error
<< ErrorInfo
.NoteRange
;
12767 return StmtError();
12769 X
= Checker
.getX();
12770 E
= Checker
.getE();
12771 D
= Checker
.getD();
12772 CE
= Checker
.getCond();
12773 V
= Checker
.getV();
12774 R
= Checker
.getR();
12775 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12776 IsXLHSInRHSPart
= Checker
.isXBinopExpr();
12777 IsFailOnly
= Checker
.isFailOnly();
12778 IsPostfixUpdate
= Checker
.isPostfixUpdate();
12780 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo
;
12781 OpenMPAtomicCompareChecker
Checker(*this);
12782 if (!Checker
.checkStmt(Body
, ErrorInfo
)) {
12783 Diag(ErrorInfo
.ErrorLoc
, diag::err_omp_atomic_compare
)
12784 << ErrorInfo
.ErrorRange
;
12785 Diag(ErrorInfo
.NoteLoc
, diag::note_omp_atomic_compare
)
12786 << ErrorInfo
.Error
<< ErrorInfo
.NoteRange
;
12787 return StmtError();
12789 X
= Checker
.getX();
12790 E
= Checker
.getE();
12791 D
= Checker
.getD();
12792 CE
= Checker
.getCond();
12793 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12794 IsXLHSInRHSPart
= Checker
.isXBinopExpr();
12798 setFunctionHasBranchProtectedScope();
12800 return OMPAtomicDirective::Create(
12801 Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
12802 {X
, V
, R
, E
, UE
, D
, CE
, IsXLHSInRHSPart
, IsPostfixUpdate
, IsFailOnly
});
12805 StmtResult
Sema::ActOnOpenMPTargetDirective(ArrayRef
<OMPClause
*> Clauses
,
12807 SourceLocation StartLoc
,
12808 SourceLocation EndLoc
) {
12810 return StmtError();
12812 auto *CS
= cast
<CapturedStmt
>(AStmt
);
12813 // 1.2.2 OpenMP Language Terminology
12814 // Structured block - An executable statement with a single entry at the
12815 // top and a single exit at the bottom.
12816 // The point of exit cannot be a branch out of the structured block.
12817 // longjmp() and throw() must not violate the entry/exit criteria.
12818 CS
->getCapturedDecl()->setNothrow();
12819 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target
);
12820 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
12821 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
12822 // 1.2.2 OpenMP Language Terminology
12823 // Structured block - An executable statement with a single entry at the
12824 // top and a single exit at the bottom.
12825 // The point of exit cannot be a branch out of the structured block.
12826 // longjmp() and throw() must not violate the entry/exit criteria.
12827 CS
->getCapturedDecl()->setNothrow();
12830 // OpenMP [2.16, Nesting of Regions]
12831 // If specified, a teams construct must be contained within a target
12832 // construct. That target construct must contain no statements or directives
12833 // outside of the teams construct.
12834 if (DSAStack
->hasInnerTeamsRegion()) {
12835 const Stmt
*S
= CS
->IgnoreContainers(/*IgnoreCaptured=*/true);
12836 bool OMPTeamsFound
= true;
12837 if (const auto *CS
= dyn_cast
<CompoundStmt
>(S
)) {
12838 auto I
= CS
->body_begin();
12839 while (I
!= CS
->body_end()) {
12840 const auto *OED
= dyn_cast
<OMPExecutableDirective
>(*I
);
12841 if (!OED
|| !isOpenMPTeamsDirective(OED
->getDirectiveKind()) ||
12844 OMPTeamsFound
= false;
12849 assert(I
!= CS
->body_end() && "Not found statement");
12852 const auto *OED
= dyn_cast
<OMPExecutableDirective
>(S
);
12853 OMPTeamsFound
= OED
&& isOpenMPTeamsDirective(OED
->getDirectiveKind());
12855 if (!OMPTeamsFound
) {
12856 Diag(StartLoc
, diag::err_omp_target_contains_not_only_teams
);
12857 Diag(DSAStack
->getInnerTeamsRegionLoc(),
12858 diag::note_omp_nested_teams_construct_here
);
12859 Diag(S
->getBeginLoc(), diag::note_omp_nested_statement_here
)
12860 << isa
<OMPExecutableDirective
>(S
);
12861 return StmtError();
12865 setFunctionHasBranchProtectedScope();
12867 return OMPTargetDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
);
12871 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef
<OMPClause
*> Clauses
,
12872 Stmt
*AStmt
, SourceLocation StartLoc
,
12873 SourceLocation EndLoc
) {
12875 return StmtError();
12877 auto *CS
= cast
<CapturedStmt
>(AStmt
);
12878 // 1.2.2 OpenMP Language Terminology
12879 // Structured block - An executable statement with a single entry at the
12880 // top and a single exit at the bottom.
12881 // The point of exit cannot be a branch out of the structured block.
12882 // longjmp() and throw() must not violate the entry/exit criteria.
12883 CS
->getCapturedDecl()->setNothrow();
12884 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_parallel
);
12885 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
12886 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
12887 // 1.2.2 OpenMP Language Terminology
12888 // Structured block - An executable statement with a single entry at the
12889 // top and a single exit at the bottom.
12890 // The point of exit cannot be a branch out of the structured block.
12891 // longjmp() and throw() must not violate the entry/exit criteria.
12892 CS
->getCapturedDecl()->setNothrow();
12895 setFunctionHasBranchProtectedScope();
12897 return OMPTargetParallelDirective::Create(
12898 Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
12899 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
12902 StmtResult
Sema::ActOnOpenMPTargetParallelForDirective(
12903 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
12904 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
12906 return StmtError();
12908 auto *CS
= cast
<CapturedStmt
>(AStmt
);
12909 // 1.2.2 OpenMP Language Terminology
12910 // Structured block - An executable statement with a single entry at the
12911 // top and a single exit at the bottom.
12912 // The point of exit cannot be a branch out of the structured block.
12913 // longjmp() and throw() must not violate the entry/exit criteria.
12914 CS
->getCapturedDecl()->setNothrow();
12915 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_parallel_for
);
12916 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
12917 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
12918 // 1.2.2 OpenMP Language Terminology
12919 // Structured block - An executable statement with a single entry at the
12920 // top and a single exit at the bottom.
12921 // The point of exit cannot be a branch out of the structured block.
12922 // longjmp() and throw() must not violate the entry/exit criteria.
12923 CS
->getCapturedDecl()->setNothrow();
12926 OMPLoopBasedDirective::HelperExprs B
;
12927 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12928 // define the nested loops number.
12929 unsigned NestedLoopCount
=
12930 checkOpenMPLoop(OMPD_target_parallel_for
, getCollapseNumberExpr(Clauses
),
12931 getOrderedNumberExpr(Clauses
), CS
, *this, *DSAStack
,
12932 VarsWithImplicitDSA
, B
);
12933 if (NestedLoopCount
== 0)
12934 return StmtError();
12936 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
12937 "omp target parallel for loop exprs were not built");
12939 if (!CurContext
->isDependentContext()) {
12940 // Finalize the clauses that need pre-built expressions for CodeGen.
12941 for (OMPClause
*C
: Clauses
) {
12942 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
12943 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
12944 B
.NumIterations
, *this, CurScope
,
12946 return StmtError();
12950 setFunctionHasBranchProtectedScope();
12951 return OMPTargetParallelForDirective::Create(
12952 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
12953 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
12956 /// Check for existence of a map clause in the list of clauses.
12957 static bool hasClauses(ArrayRef
<OMPClause
*> Clauses
,
12958 const OpenMPClauseKind K
) {
12959 return llvm::any_of(
12960 Clauses
, [K
](const OMPClause
*C
) { return C
->getClauseKind() == K
; });
12963 template <typename
... Params
>
12964 static bool hasClauses(ArrayRef
<OMPClause
*> Clauses
, const OpenMPClauseKind K
,
12965 const Params
... ClauseTypes
) {
12966 return hasClauses(Clauses
, K
) || hasClauses(Clauses
, ClauseTypes
...);
12969 /// Check if the variables in the mapping clause are externally visible.
12970 static bool isClauseMappable(ArrayRef
<OMPClause
*> Clauses
) {
12971 for (const OMPClause
*C
: Clauses
) {
12972 if (auto *TC
= dyn_cast
<OMPToClause
>(C
))
12973 return llvm::all_of(TC
->all_decls(), [](ValueDecl
*VD
) {
12974 return !VD
|| !VD
->hasAttr
<OMPDeclareTargetDeclAttr
>() ||
12975 (VD
->isExternallyVisible() &&
12976 VD
->getVisibility() != HiddenVisibility
);
12978 else if (auto *FC
= dyn_cast
<OMPFromClause
>(C
))
12979 return llvm::all_of(FC
->all_decls(), [](ValueDecl
*VD
) {
12980 return !VD
|| !VD
->hasAttr
<OMPDeclareTargetDeclAttr
>() ||
12981 (VD
->isExternallyVisible() &&
12982 VD
->getVisibility() != HiddenVisibility
);
12989 StmtResult
Sema::ActOnOpenMPTargetDataDirective(ArrayRef
<OMPClause
*> Clauses
,
12991 SourceLocation StartLoc
,
12992 SourceLocation EndLoc
) {
12994 return StmtError();
12996 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
12998 // OpenMP [2.12.2, target data Construct, Restrictions]
12999 // At least one map, use_device_addr or use_device_ptr clause must appear on
13001 if (!hasClauses(Clauses
, OMPC_map
, OMPC_use_device_ptr
) &&
13002 (LangOpts
.OpenMP
< 50 || !hasClauses(Clauses
, OMPC_use_device_addr
))) {
13003 StringRef Expected
;
13004 if (LangOpts
.OpenMP
< 50)
13005 Expected
= "'map' or 'use_device_ptr'";
13007 Expected
= "'map', 'use_device_ptr', or 'use_device_addr'";
13008 Diag(StartLoc
, diag::err_omp_no_clause_for_directive
)
13009 << Expected
<< getOpenMPDirectiveName(OMPD_target_data
);
13010 return StmtError();
13013 setFunctionHasBranchProtectedScope();
13015 return OMPTargetDataDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
13020 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef
<OMPClause
*> Clauses
,
13021 SourceLocation StartLoc
,
13022 SourceLocation EndLoc
, Stmt
*AStmt
) {
13024 return StmtError();
13026 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13027 // 1.2.2 OpenMP Language Terminology
13028 // Structured block - An executable statement with a single entry at the
13029 // top and a single exit at the bottom.
13030 // The point of exit cannot be a branch out of the structured block.
13031 // longjmp() and throw() must not violate the entry/exit criteria.
13032 CS
->getCapturedDecl()->setNothrow();
13033 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_enter_data
);
13034 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13035 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13036 // 1.2.2 OpenMP Language Terminology
13037 // Structured block - An executable statement with a single entry at the
13038 // top and a single exit at the bottom.
13039 // The point of exit cannot be a branch out of the structured block.
13040 // longjmp() and throw() must not violate the entry/exit criteria.
13041 CS
->getCapturedDecl()->setNothrow();
13044 // OpenMP [2.10.2, Restrictions, p. 99]
13045 // At least one map clause must appear on the directive.
13046 if (!hasClauses(Clauses
, OMPC_map
)) {
13047 Diag(StartLoc
, diag::err_omp_no_clause_for_directive
)
13048 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data
);
13049 return StmtError();
13052 return OMPTargetEnterDataDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
13057 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef
<OMPClause
*> Clauses
,
13058 SourceLocation StartLoc
,
13059 SourceLocation EndLoc
, Stmt
*AStmt
) {
13061 return StmtError();
13063 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13064 // 1.2.2 OpenMP Language Terminology
13065 // Structured block - An executable statement with a single entry at the
13066 // top and a single exit at the bottom.
13067 // The point of exit cannot be a branch out of the structured block.
13068 // longjmp() and throw() must not violate the entry/exit criteria.
13069 CS
->getCapturedDecl()->setNothrow();
13070 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_exit_data
);
13071 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13072 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13073 // 1.2.2 OpenMP Language Terminology
13074 // Structured block - An executable statement with a single entry at the
13075 // top and a single exit at the bottom.
13076 // The point of exit cannot be a branch out of the structured block.
13077 // longjmp() and throw() must not violate the entry/exit criteria.
13078 CS
->getCapturedDecl()->setNothrow();
13081 // OpenMP [2.10.3, Restrictions, p. 102]
13082 // At least one map clause must appear on the directive.
13083 if (!hasClauses(Clauses
, OMPC_map
)) {
13084 Diag(StartLoc
, diag::err_omp_no_clause_for_directive
)
13085 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data
);
13086 return StmtError();
13089 return OMPTargetExitDataDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
13093 StmtResult
Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef
<OMPClause
*> Clauses
,
13094 SourceLocation StartLoc
,
13095 SourceLocation EndLoc
,
13098 return StmtError();
13100 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13101 // 1.2.2 OpenMP Language Terminology
13102 // Structured block - An executable statement with a single entry at the
13103 // top and a single exit at the bottom.
13104 // The point of exit cannot be a branch out of the structured block.
13105 // longjmp() and throw() must not violate the entry/exit criteria.
13106 CS
->getCapturedDecl()->setNothrow();
13107 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_update
);
13108 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13109 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13110 // 1.2.2 OpenMP Language Terminology
13111 // Structured block - An executable statement with a single entry at the
13112 // top and a single exit at the bottom.
13113 // The point of exit cannot be a branch out of the structured block.
13114 // longjmp() and throw() must not violate the entry/exit criteria.
13115 CS
->getCapturedDecl()->setNothrow();
13118 if (!hasClauses(Clauses
, OMPC_to
, OMPC_from
)) {
13119 Diag(StartLoc
, diag::err_omp_at_least_one_motion_clause_required
);
13120 return StmtError();
13123 if (!isClauseMappable(Clauses
)) {
13124 Diag(StartLoc
, diag::err_omp_cannot_update_with_internal_linkage
);
13125 return StmtError();
13128 return OMPTargetUpdateDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
13132 StmtResult
Sema::ActOnOpenMPTeamsDirective(ArrayRef
<OMPClause
*> Clauses
,
13133 Stmt
*AStmt
, SourceLocation StartLoc
,
13134 SourceLocation EndLoc
) {
13136 return StmtError();
13138 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13139 // 1.2.2 OpenMP Language Terminology
13140 // Structured block - An executable statement with a single entry at the
13141 // top and a single exit at the bottom.
13142 // The point of exit cannot be a branch out of the structured block.
13143 // longjmp() and throw() must not violate the entry/exit criteria.
13144 CS
->getCapturedDecl()->setNothrow();
13146 setFunctionHasBranchProtectedScope();
13148 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
13150 return OMPTeamsDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
);
13154 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc
,
13155 SourceLocation EndLoc
,
13156 OpenMPDirectiveKind CancelRegion
) {
13157 if (DSAStack
->isParentNowaitRegion()) {
13158 Diag(StartLoc
, diag::err_omp_parent_cancel_region_nowait
) << 0;
13159 return StmtError();
13161 if (DSAStack
->isParentOrderedRegion()) {
13162 Diag(StartLoc
, diag::err_omp_parent_cancel_region_ordered
) << 0;
13163 return StmtError();
13165 return OMPCancellationPointDirective::Create(Context
, StartLoc
, EndLoc
,
13169 StmtResult
Sema::ActOnOpenMPCancelDirective(ArrayRef
<OMPClause
*> Clauses
,
13170 SourceLocation StartLoc
,
13171 SourceLocation EndLoc
,
13172 OpenMPDirectiveKind CancelRegion
) {
13173 if (DSAStack
->isParentNowaitRegion()) {
13174 Diag(StartLoc
, diag::err_omp_parent_cancel_region_nowait
) << 1;
13175 return StmtError();
13177 if (DSAStack
->isParentOrderedRegion()) {
13178 Diag(StartLoc
, diag::err_omp_parent_cancel_region_ordered
) << 1;
13179 return StmtError();
13181 DSAStack
->setParentCancelRegion(/*Cancel=*/true);
13182 return OMPCancelDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
13186 static bool checkReductionClauseWithNogroup(Sema
&S
,
13187 ArrayRef
<OMPClause
*> Clauses
) {
13188 const OMPClause
*ReductionClause
= nullptr;
13189 const OMPClause
*NogroupClause
= nullptr;
13190 for (const OMPClause
*C
: Clauses
) {
13191 if (C
->getClauseKind() == OMPC_reduction
) {
13192 ReductionClause
= C
;
13197 if (C
->getClauseKind() == OMPC_nogroup
) {
13199 if (ReductionClause
)
13204 if (ReductionClause
&& NogroupClause
) {
13205 S
.Diag(ReductionClause
->getBeginLoc(), diag::err_omp_reduction_with_nogroup
)
13206 << SourceRange(NogroupClause
->getBeginLoc(),
13207 NogroupClause
->getEndLoc());
13213 StmtResult
Sema::ActOnOpenMPTaskLoopDirective(
13214 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13215 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13217 return StmtError();
13219 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13220 OMPLoopBasedDirective::HelperExprs B
;
13221 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13222 // define the nested loops number.
13223 unsigned NestedLoopCount
=
13224 checkOpenMPLoop(OMPD_taskloop
, getCollapseNumberExpr(Clauses
),
13225 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13226 VarsWithImplicitDSA
, B
);
13227 if (NestedLoopCount
== 0)
13228 return StmtError();
13230 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13231 "omp for loop exprs were not built");
13233 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13234 // The grainsize clause and num_tasks clause are mutually exclusive and may
13235 // not appear on the same taskloop directive.
13236 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13237 {OMPC_grainsize
, OMPC_num_tasks
}))
13238 return StmtError();
13239 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13240 // If a reduction clause is present on the taskloop directive, the nogroup
13241 // clause must not be specified.
13242 if (checkReductionClauseWithNogroup(*this, Clauses
))
13243 return StmtError();
13245 setFunctionHasBranchProtectedScope();
13246 return OMPTaskLoopDirective::Create(Context
, StartLoc
, EndLoc
,
13247 NestedLoopCount
, Clauses
, AStmt
, B
,
13248 DSAStack
->isCancelRegion());
13251 StmtResult
Sema::ActOnOpenMPTaskLoopSimdDirective(
13252 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13253 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13255 return StmtError();
13257 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13258 OMPLoopBasedDirective::HelperExprs B
;
13259 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13260 // define the nested loops number.
13261 unsigned NestedLoopCount
=
13262 checkOpenMPLoop(OMPD_taskloop_simd
, getCollapseNumberExpr(Clauses
),
13263 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13264 VarsWithImplicitDSA
, B
);
13265 if (NestedLoopCount
== 0)
13266 return StmtError();
13268 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13269 "omp for loop exprs were not built");
13271 if (!CurContext
->isDependentContext()) {
13272 // Finalize the clauses that need pre-built expressions for CodeGen.
13273 for (OMPClause
*C
: Clauses
) {
13274 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13275 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13276 B
.NumIterations
, *this, CurScope
,
13278 return StmtError();
13282 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13283 // The grainsize clause and num_tasks clause are mutually exclusive and may
13284 // not appear on the same taskloop directive.
13285 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13286 {OMPC_grainsize
, OMPC_num_tasks
}))
13287 return StmtError();
13288 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13289 // If a reduction clause is present on the taskloop directive, the nogroup
13290 // clause must not be specified.
13291 if (checkReductionClauseWithNogroup(*this, Clauses
))
13292 return StmtError();
13293 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13294 return StmtError();
13296 setFunctionHasBranchProtectedScope();
13297 return OMPTaskLoopSimdDirective::Create(Context
, StartLoc
, EndLoc
,
13298 NestedLoopCount
, Clauses
, AStmt
, B
);
13301 StmtResult
Sema::ActOnOpenMPMasterTaskLoopDirective(
13302 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13303 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13305 return StmtError();
13307 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13308 OMPLoopBasedDirective::HelperExprs B
;
13309 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13310 // define the nested loops number.
13311 unsigned NestedLoopCount
=
13312 checkOpenMPLoop(OMPD_master_taskloop
, getCollapseNumberExpr(Clauses
),
13313 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13314 VarsWithImplicitDSA
, B
);
13315 if (NestedLoopCount
== 0)
13316 return StmtError();
13318 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13319 "omp for loop exprs were not built");
13321 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13322 // The grainsize clause and num_tasks clause are mutually exclusive and may
13323 // not appear on the same taskloop directive.
13324 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13325 {OMPC_grainsize
, OMPC_num_tasks
}))
13326 return StmtError();
13327 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13328 // If a reduction clause is present on the taskloop directive, the nogroup
13329 // clause must not be specified.
13330 if (checkReductionClauseWithNogroup(*this, Clauses
))
13331 return StmtError();
13333 setFunctionHasBranchProtectedScope();
13334 return OMPMasterTaskLoopDirective::Create(Context
, StartLoc
, EndLoc
,
13335 NestedLoopCount
, Clauses
, AStmt
, B
,
13336 DSAStack
->isCancelRegion());
13339 StmtResult
Sema::ActOnOpenMPMaskedTaskLoopDirective(
13340 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13341 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13343 return StmtError();
13345 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13346 OMPLoopBasedDirective::HelperExprs B
;
13347 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13348 // define the nested loops number.
13349 unsigned NestedLoopCount
=
13350 checkOpenMPLoop(OMPD_masked_taskloop
, getCollapseNumberExpr(Clauses
),
13351 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13352 VarsWithImplicitDSA
, B
);
13353 if (NestedLoopCount
== 0)
13354 return StmtError();
13356 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13357 "omp for loop exprs were not built");
13359 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13360 // The grainsize clause and num_tasks clause are mutually exclusive and may
13361 // not appear on the same taskloop directive.
13362 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13363 {OMPC_grainsize
, OMPC_num_tasks
}))
13364 return StmtError();
13365 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13366 // If a reduction clause is present on the taskloop directive, the nogroup
13367 // clause must not be specified.
13368 if (checkReductionClauseWithNogroup(*this, Clauses
))
13369 return StmtError();
13371 setFunctionHasBranchProtectedScope();
13372 return OMPMaskedTaskLoopDirective::Create(Context
, StartLoc
, EndLoc
,
13373 NestedLoopCount
, Clauses
, AStmt
, B
,
13374 DSAStack
->isCancelRegion());
13377 StmtResult
Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13378 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13379 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13381 return StmtError();
13383 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13384 OMPLoopBasedDirective::HelperExprs B
;
13385 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13386 // define the nested loops number.
13387 unsigned NestedLoopCount
=
13388 checkOpenMPLoop(OMPD_master_taskloop_simd
, getCollapseNumberExpr(Clauses
),
13389 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13390 VarsWithImplicitDSA
, B
);
13391 if (NestedLoopCount
== 0)
13392 return StmtError();
13394 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13395 "omp for loop exprs were not built");
13397 if (!CurContext
->isDependentContext()) {
13398 // Finalize the clauses that need pre-built expressions for CodeGen.
13399 for (OMPClause
*C
: Clauses
) {
13400 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13401 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13402 B
.NumIterations
, *this, CurScope
,
13404 return StmtError();
13408 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13409 // The grainsize clause and num_tasks clause are mutually exclusive and may
13410 // not appear on the same taskloop directive.
13411 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13412 {OMPC_grainsize
, OMPC_num_tasks
}))
13413 return StmtError();
13414 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13415 // If a reduction clause is present on the taskloop directive, the nogroup
13416 // clause must not be specified.
13417 if (checkReductionClauseWithNogroup(*this, Clauses
))
13418 return StmtError();
13419 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13420 return StmtError();
13422 setFunctionHasBranchProtectedScope();
13423 return OMPMasterTaskLoopSimdDirective::Create(
13424 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13427 StmtResult
Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13428 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13429 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13431 return StmtError();
13433 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13434 OMPLoopBasedDirective::HelperExprs B
;
13435 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13436 // define the nested loops number.
13437 unsigned NestedLoopCount
=
13438 checkOpenMPLoop(OMPD_masked_taskloop_simd
, getCollapseNumberExpr(Clauses
),
13439 /*OrderedLoopCountExpr=*/nullptr, AStmt
, *this, *DSAStack
,
13440 VarsWithImplicitDSA
, B
);
13441 if (NestedLoopCount
== 0)
13442 return StmtError();
13444 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13445 "omp for loop exprs were not built");
13447 if (!CurContext
->isDependentContext()) {
13448 // Finalize the clauses that need pre-built expressions for CodeGen.
13449 for (OMPClause
*C
: Clauses
) {
13450 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13451 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13452 B
.NumIterations
, *this, CurScope
,
13454 return StmtError();
13458 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13459 // The grainsize clause and num_tasks clause are mutually exclusive and may
13460 // not appear on the same taskloop directive.
13461 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13462 {OMPC_grainsize
, OMPC_num_tasks
}))
13463 return StmtError();
13464 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13465 // If a reduction clause is present on the taskloop directive, the nogroup
13466 // clause must not be specified.
13467 if (checkReductionClauseWithNogroup(*this, Clauses
))
13468 return StmtError();
13469 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13470 return StmtError();
13472 setFunctionHasBranchProtectedScope();
13473 return OMPMaskedTaskLoopSimdDirective::Create(
13474 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13477 StmtResult
Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13478 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13479 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13481 return StmtError();
13483 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13484 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13485 // 1.2.2 OpenMP Language Terminology
13486 // Structured block - An executable statement with a single entry at the
13487 // top and a single exit at the bottom.
13488 // The point of exit cannot be a branch out of the structured block.
13489 // longjmp() and throw() must not violate the entry/exit criteria.
13490 CS
->getCapturedDecl()->setNothrow();
13491 for (int ThisCaptureLevel
=
13492 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop
);
13493 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13494 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13495 // 1.2.2 OpenMP Language Terminology
13496 // Structured block - An executable statement with a single entry at the
13497 // top and a single exit at the bottom.
13498 // The point of exit cannot be a branch out of the structured block.
13499 // longjmp() and throw() must not violate the entry/exit criteria.
13500 CS
->getCapturedDecl()->setNothrow();
13503 OMPLoopBasedDirective::HelperExprs B
;
13504 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13505 // define the nested loops number.
13506 unsigned NestedLoopCount
= checkOpenMPLoop(
13507 OMPD_parallel_master_taskloop
, getCollapseNumberExpr(Clauses
),
13508 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
13509 VarsWithImplicitDSA
, B
);
13510 if (NestedLoopCount
== 0)
13511 return StmtError();
13513 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13514 "omp for loop exprs were not built");
13516 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13517 // The grainsize clause and num_tasks clause are mutually exclusive and may
13518 // not appear on the same taskloop directive.
13519 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13520 {OMPC_grainsize
, OMPC_num_tasks
}))
13521 return StmtError();
13522 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13523 // If a reduction clause is present on the taskloop directive, the nogroup
13524 // clause must not be specified.
13525 if (checkReductionClauseWithNogroup(*this, Clauses
))
13526 return StmtError();
13528 setFunctionHasBranchProtectedScope();
13529 return OMPParallelMasterTaskLoopDirective::Create(
13530 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
13531 DSAStack
->isCancelRegion());
13534 StmtResult
Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13535 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13536 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13538 return StmtError();
13540 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13541 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13542 // 1.2.2 OpenMP Language Terminology
13543 // Structured block - An executable statement with a single entry at the
13544 // top and a single exit at the bottom.
13545 // The point of exit cannot be a branch out of the structured block.
13546 // longjmp() and throw() must not violate the entry/exit criteria.
13547 CS
->getCapturedDecl()->setNothrow();
13548 for (int ThisCaptureLevel
=
13549 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop
);
13550 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13551 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13552 // 1.2.2 OpenMP Language Terminology
13553 // Structured block - An executable statement with a single entry at the
13554 // top and a single exit at the bottom.
13555 // The point of exit cannot be a branch out of the structured block.
13556 // longjmp() and throw() must not violate the entry/exit criteria.
13557 CS
->getCapturedDecl()->setNothrow();
13560 OMPLoopBasedDirective::HelperExprs B
;
13561 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13562 // define the nested loops number.
13563 unsigned NestedLoopCount
= checkOpenMPLoop(
13564 OMPD_parallel_masked_taskloop
, getCollapseNumberExpr(Clauses
),
13565 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
13566 VarsWithImplicitDSA
, B
);
13567 if (NestedLoopCount
== 0)
13568 return StmtError();
13570 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13571 "omp for loop exprs were not built");
13573 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13574 // The grainsize clause and num_tasks clause are mutually exclusive and may
13575 // not appear on the same taskloop directive.
13576 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13577 {OMPC_grainsize
, OMPC_num_tasks
}))
13578 return StmtError();
13579 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13580 // If a reduction clause is present on the taskloop directive, the nogroup
13581 // clause must not be specified.
13582 if (checkReductionClauseWithNogroup(*this, Clauses
))
13583 return StmtError();
13585 setFunctionHasBranchProtectedScope();
13586 return OMPParallelMaskedTaskLoopDirective::Create(
13587 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
13588 DSAStack
->isCancelRegion());
13591 StmtResult
Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13592 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13593 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13595 return StmtError();
13597 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13598 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13599 // 1.2.2 OpenMP Language Terminology
13600 // Structured block - An executable statement with a single entry at the
13601 // top and a single exit at the bottom.
13602 // The point of exit cannot be a branch out of the structured block.
13603 // longjmp() and throw() must not violate the entry/exit criteria.
13604 CS
->getCapturedDecl()->setNothrow();
13605 for (int ThisCaptureLevel
=
13606 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd
);
13607 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13608 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13609 // 1.2.2 OpenMP Language Terminology
13610 // Structured block - An executable statement with a single entry at the
13611 // top and a single exit at the bottom.
13612 // The point of exit cannot be a branch out of the structured block.
13613 // longjmp() and throw() must not violate the entry/exit criteria.
13614 CS
->getCapturedDecl()->setNothrow();
13617 OMPLoopBasedDirective::HelperExprs B
;
13618 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13619 // define the nested loops number.
13620 unsigned NestedLoopCount
= checkOpenMPLoop(
13621 OMPD_parallel_master_taskloop_simd
, getCollapseNumberExpr(Clauses
),
13622 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
13623 VarsWithImplicitDSA
, B
);
13624 if (NestedLoopCount
== 0)
13625 return StmtError();
13627 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13628 "omp for loop exprs were not built");
13630 if (!CurContext
->isDependentContext()) {
13631 // Finalize the clauses that need pre-built expressions for CodeGen.
13632 for (OMPClause
*C
: Clauses
) {
13633 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13634 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13635 B
.NumIterations
, *this, CurScope
,
13637 return StmtError();
13641 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13642 // The grainsize clause and num_tasks clause are mutually exclusive and may
13643 // not appear on the same taskloop directive.
13644 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13645 {OMPC_grainsize
, OMPC_num_tasks
}))
13646 return StmtError();
13647 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13648 // If a reduction clause is present on the taskloop directive, the nogroup
13649 // clause must not be specified.
13650 if (checkReductionClauseWithNogroup(*this, Clauses
))
13651 return StmtError();
13652 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13653 return StmtError();
13655 setFunctionHasBranchProtectedScope();
13656 return OMPParallelMasterTaskLoopSimdDirective::Create(
13657 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13660 StmtResult
Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
13661 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13662 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13664 return StmtError();
13666 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13667 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13668 // 1.2.2 OpenMP Language Terminology
13669 // Structured block - An executable statement with a single entry at the
13670 // top and a single exit at the bottom.
13671 // The point of exit cannot be a branch out of the structured block.
13672 // longjmp() and throw() must not violate the entry/exit criteria.
13673 CS
->getCapturedDecl()->setNothrow();
13674 for (int ThisCaptureLevel
=
13675 getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd
);
13676 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13677 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13678 // 1.2.2 OpenMP Language Terminology
13679 // Structured block - An executable statement with a single entry at the
13680 // top and a single exit at the bottom.
13681 // The point of exit cannot be a branch out of the structured block.
13682 // longjmp() and throw() must not violate the entry/exit criteria.
13683 CS
->getCapturedDecl()->setNothrow();
13686 OMPLoopBasedDirective::HelperExprs B
;
13687 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13688 // define the nested loops number.
13689 unsigned NestedLoopCount
= checkOpenMPLoop(
13690 OMPD_parallel_masked_taskloop_simd
, getCollapseNumberExpr(Clauses
),
13691 /*OrderedLoopCountExpr=*/nullptr, CS
, *this, *DSAStack
,
13692 VarsWithImplicitDSA
, B
);
13693 if (NestedLoopCount
== 0)
13694 return StmtError();
13696 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13697 "omp for loop exprs were not built");
13699 if (!CurContext
->isDependentContext()) {
13700 // Finalize the clauses that need pre-built expressions for CodeGen.
13701 for (OMPClause
*C
: Clauses
) {
13702 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13703 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13704 B
.NumIterations
, *this, CurScope
,
13706 return StmtError();
13710 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13711 // The grainsize clause and num_tasks clause are mutually exclusive and may
13712 // not appear on the same taskloop directive.
13713 if (checkMutuallyExclusiveClauses(*this, Clauses
,
13714 {OMPC_grainsize
, OMPC_num_tasks
}))
13715 return StmtError();
13716 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13717 // If a reduction clause is present on the taskloop directive, the nogroup
13718 // clause must not be specified.
13719 if (checkReductionClauseWithNogroup(*this, Clauses
))
13720 return StmtError();
13721 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13722 return StmtError();
13724 setFunctionHasBranchProtectedScope();
13725 return OMPParallelMaskedTaskLoopSimdDirective::Create(
13726 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13729 StmtResult
Sema::ActOnOpenMPDistributeDirective(
13730 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13731 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13733 return StmtError();
13735 assert(isa
<CapturedStmt
>(AStmt
) && "Captured statement expected");
13736 OMPLoopBasedDirective::HelperExprs B
;
13737 // In presence of clause 'collapse' with number of loops, it will
13738 // define the nested loops number.
13739 unsigned NestedLoopCount
=
13740 checkOpenMPLoop(OMPD_distribute
, getCollapseNumberExpr(Clauses
),
13741 nullptr /*ordered not a clause on distribute*/, AStmt
,
13742 *this, *DSAStack
, VarsWithImplicitDSA
, B
);
13743 if (NestedLoopCount
== 0)
13744 return StmtError();
13746 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13747 "omp for loop exprs were not built");
13749 setFunctionHasBranchProtectedScope();
13750 return OMPDistributeDirective::Create(Context
, StartLoc
, EndLoc
,
13751 NestedLoopCount
, Clauses
, AStmt
, B
);
13754 StmtResult
Sema::ActOnOpenMPDistributeParallelForDirective(
13755 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13756 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13758 return StmtError();
13760 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13761 // 1.2.2 OpenMP Language Terminology
13762 // Structured block - An executable statement with a single entry at the
13763 // top and a single exit at the bottom.
13764 // The point of exit cannot be a branch out of the structured block.
13765 // longjmp() and throw() must not violate the entry/exit criteria.
13766 CS
->getCapturedDecl()->setNothrow();
13767 for (int ThisCaptureLevel
=
13768 getOpenMPCaptureLevels(OMPD_distribute_parallel_for
);
13769 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13770 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13771 // 1.2.2 OpenMP Language Terminology
13772 // Structured block - An executable statement with a single entry at the
13773 // top and a single exit at the bottom.
13774 // The point of exit cannot be a branch out of the structured block.
13775 // longjmp() and throw() must not violate the entry/exit criteria.
13776 CS
->getCapturedDecl()->setNothrow();
13779 OMPLoopBasedDirective::HelperExprs B
;
13780 // In presence of clause 'collapse' with number of loops, it will
13781 // define the nested loops number.
13782 unsigned NestedLoopCount
= checkOpenMPLoop(
13783 OMPD_distribute_parallel_for
, getCollapseNumberExpr(Clauses
),
13784 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
13785 VarsWithImplicitDSA
, B
);
13786 if (NestedLoopCount
== 0)
13787 return StmtError();
13789 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13790 "omp for loop exprs were not built");
13792 setFunctionHasBranchProtectedScope();
13793 return OMPDistributeParallelForDirective::Create(
13794 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
13795 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
13798 StmtResult
Sema::ActOnOpenMPDistributeParallelForSimdDirective(
13799 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13800 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13802 return StmtError();
13804 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13805 // 1.2.2 OpenMP Language Terminology
13806 // Structured block - An executable statement with a single entry at the
13807 // top and a single exit at the bottom.
13808 // The point of exit cannot be a branch out of the structured block.
13809 // longjmp() and throw() must not violate the entry/exit criteria.
13810 CS
->getCapturedDecl()->setNothrow();
13811 for (int ThisCaptureLevel
=
13812 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd
);
13813 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13814 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13815 // 1.2.2 OpenMP Language Terminology
13816 // Structured block - An executable statement with a single entry at the
13817 // top and a single exit at the bottom.
13818 // The point of exit cannot be a branch out of the structured block.
13819 // longjmp() and throw() must not violate the entry/exit criteria.
13820 CS
->getCapturedDecl()->setNothrow();
13823 OMPLoopBasedDirective::HelperExprs B
;
13824 // In presence of clause 'collapse' with number of loops, it will
13825 // define the nested loops number.
13826 unsigned NestedLoopCount
= checkOpenMPLoop(
13827 OMPD_distribute_parallel_for_simd
, getCollapseNumberExpr(Clauses
),
13828 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
13829 VarsWithImplicitDSA
, B
);
13830 if (NestedLoopCount
== 0)
13831 return StmtError();
13833 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13834 "omp for loop exprs were not built");
13836 if (!CurContext
->isDependentContext()) {
13837 // Finalize the clauses that need pre-built expressions for CodeGen.
13838 for (OMPClause
*C
: Clauses
) {
13839 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13840 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13841 B
.NumIterations
, *this, CurScope
,
13843 return StmtError();
13847 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13848 return StmtError();
13850 setFunctionHasBranchProtectedScope();
13851 return OMPDistributeParallelForSimdDirective::Create(
13852 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13855 StmtResult
Sema::ActOnOpenMPDistributeSimdDirective(
13856 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13857 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13859 return StmtError();
13861 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13862 // 1.2.2 OpenMP Language Terminology
13863 // Structured block - An executable statement with a single entry at the
13864 // top and a single exit at the bottom.
13865 // The point of exit cannot be a branch out of the structured block.
13866 // longjmp() and throw() must not violate the entry/exit criteria.
13867 CS
->getCapturedDecl()->setNothrow();
13868 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_distribute_simd
);
13869 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13870 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13871 // 1.2.2 OpenMP Language Terminology
13872 // Structured block - An executable statement with a single entry at the
13873 // top and a single exit at the bottom.
13874 // The point of exit cannot be a branch out of the structured block.
13875 // longjmp() and throw() must not violate the entry/exit criteria.
13876 CS
->getCapturedDecl()->setNothrow();
13879 OMPLoopBasedDirective::HelperExprs B
;
13880 // In presence of clause 'collapse' with number of loops, it will
13881 // define the nested loops number.
13882 unsigned NestedLoopCount
=
13883 checkOpenMPLoop(OMPD_distribute_simd
, getCollapseNumberExpr(Clauses
),
13884 nullptr /*ordered not a clause on distribute*/, CS
, *this,
13885 *DSAStack
, VarsWithImplicitDSA
, B
);
13886 if (NestedLoopCount
== 0)
13887 return StmtError();
13889 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13890 "omp for loop exprs were not built");
13892 if (!CurContext
->isDependentContext()) {
13893 // Finalize the clauses that need pre-built expressions for CodeGen.
13894 for (OMPClause
*C
: Clauses
) {
13895 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13896 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13897 B
.NumIterations
, *this, CurScope
,
13899 return StmtError();
13903 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13904 return StmtError();
13906 setFunctionHasBranchProtectedScope();
13907 return OMPDistributeSimdDirective::Create(Context
, StartLoc
, EndLoc
,
13908 NestedLoopCount
, Clauses
, AStmt
, B
);
13911 StmtResult
Sema::ActOnOpenMPTargetParallelForSimdDirective(
13912 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13913 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13915 return StmtError();
13917 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13918 // 1.2.2 OpenMP Language Terminology
13919 // Structured block - An executable statement with a single entry at the
13920 // top and a single exit at the bottom.
13921 // The point of exit cannot be a branch out of the structured block.
13922 // longjmp() and throw() must not violate the entry/exit criteria.
13923 CS
->getCapturedDecl()->setNothrow();
13924 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_parallel_for
);
13925 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13926 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13927 // 1.2.2 OpenMP Language Terminology
13928 // Structured block - An executable statement with a single entry at the
13929 // top and a single exit at the bottom.
13930 // The point of exit cannot be a branch out of the structured block.
13931 // longjmp() and throw() must not violate the entry/exit criteria.
13932 CS
->getCapturedDecl()->setNothrow();
13935 OMPLoopBasedDirective::HelperExprs B
;
13936 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13937 // define the nested loops number.
13938 unsigned NestedLoopCount
= checkOpenMPLoop(
13939 OMPD_target_parallel_for_simd
, getCollapseNumberExpr(Clauses
),
13940 getOrderedNumberExpr(Clauses
), CS
, *this, *DSAStack
, VarsWithImplicitDSA
,
13942 if (NestedLoopCount
== 0)
13943 return StmtError();
13945 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
13946 "omp target parallel for simd loop exprs were not built");
13948 if (!CurContext
->isDependentContext()) {
13949 // Finalize the clauses that need pre-built expressions for CodeGen.
13950 for (OMPClause
*C
: Clauses
) {
13951 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
13952 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
13953 B
.NumIterations
, *this, CurScope
,
13955 return StmtError();
13958 if (checkSimdlenSafelenSpecified(*this, Clauses
))
13959 return StmtError();
13961 setFunctionHasBranchProtectedScope();
13962 return OMPTargetParallelForSimdDirective::Create(
13963 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
13966 StmtResult
Sema::ActOnOpenMPTargetSimdDirective(
13967 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
13968 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
13970 return StmtError();
13972 auto *CS
= cast
<CapturedStmt
>(AStmt
);
13973 // 1.2.2 OpenMP Language Terminology
13974 // Structured block - An executable statement with a single entry at the
13975 // top and a single exit at the bottom.
13976 // The point of exit cannot be a branch out of the structured block.
13977 // longjmp() and throw() must not violate the entry/exit criteria.
13978 CS
->getCapturedDecl()->setNothrow();
13979 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_simd
);
13980 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
13981 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
13982 // 1.2.2 OpenMP Language Terminology
13983 // Structured block - An executable statement with a single entry at the
13984 // top and a single exit at the bottom.
13985 // The point of exit cannot be a branch out of the structured block.
13986 // longjmp() and throw() must not violate the entry/exit criteria.
13987 CS
->getCapturedDecl()->setNothrow();
13990 OMPLoopBasedDirective::HelperExprs B
;
13991 // In presence of clause 'collapse' with number of loops, it will define the
13992 // nested loops number.
13993 unsigned NestedLoopCount
=
13994 checkOpenMPLoop(OMPD_target_simd
, getCollapseNumberExpr(Clauses
),
13995 getOrderedNumberExpr(Clauses
), CS
, *this, *DSAStack
,
13996 VarsWithImplicitDSA
, B
);
13997 if (NestedLoopCount
== 0)
13998 return StmtError();
14000 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14001 "omp target simd loop exprs were not built");
14003 if (!CurContext
->isDependentContext()) {
14004 // Finalize the clauses that need pre-built expressions for CodeGen.
14005 for (OMPClause
*C
: Clauses
) {
14006 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14007 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14008 B
.NumIterations
, *this, CurScope
,
14010 return StmtError();
14014 if (checkSimdlenSafelenSpecified(*this, Clauses
))
14015 return StmtError();
14017 setFunctionHasBranchProtectedScope();
14018 return OMPTargetSimdDirective::Create(Context
, StartLoc
, EndLoc
,
14019 NestedLoopCount
, Clauses
, AStmt
, B
);
14022 StmtResult
Sema::ActOnOpenMPTeamsDistributeDirective(
14023 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14024 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14026 return StmtError();
14028 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14029 // 1.2.2 OpenMP Language Terminology
14030 // Structured block - An executable statement with a single entry at the
14031 // top and a single exit at the bottom.
14032 // The point of exit cannot be a branch out of the structured block.
14033 // longjmp() and throw() must not violate the entry/exit criteria.
14034 CS
->getCapturedDecl()->setNothrow();
14035 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_teams_distribute
);
14036 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14037 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14038 // 1.2.2 OpenMP Language Terminology
14039 // Structured block - An executable statement with a single entry at the
14040 // top and a single exit at the bottom.
14041 // The point of exit cannot be a branch out of the structured block.
14042 // longjmp() and throw() must not violate the entry/exit criteria.
14043 CS
->getCapturedDecl()->setNothrow();
14046 OMPLoopBasedDirective::HelperExprs B
;
14047 // In presence of clause 'collapse' with number of loops, it will
14048 // define the nested loops number.
14049 unsigned NestedLoopCount
=
14050 checkOpenMPLoop(OMPD_teams_distribute
, getCollapseNumberExpr(Clauses
),
14051 nullptr /*ordered not a clause on distribute*/, CS
, *this,
14052 *DSAStack
, VarsWithImplicitDSA
, B
);
14053 if (NestedLoopCount
== 0)
14054 return StmtError();
14056 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14057 "omp teams distribute loop exprs were not built");
14059 setFunctionHasBranchProtectedScope();
14061 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
14063 return OMPTeamsDistributeDirective::Create(
14064 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14067 StmtResult
Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14068 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14069 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14071 return StmtError();
14073 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14074 // 1.2.2 OpenMP Language Terminology
14075 // Structured block - An executable statement with a single entry at the
14076 // top and a single exit at the bottom.
14077 // The point of exit cannot be a branch out of the structured block.
14078 // longjmp() and throw() must not violate the entry/exit criteria.
14079 CS
->getCapturedDecl()->setNothrow();
14080 for (int ThisCaptureLevel
=
14081 getOpenMPCaptureLevels(OMPD_teams_distribute_simd
);
14082 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14083 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14084 // 1.2.2 OpenMP Language Terminology
14085 // Structured block - An executable statement with a single entry at the
14086 // top and a single exit at the bottom.
14087 // The point of exit cannot be a branch out of the structured block.
14088 // longjmp() and throw() must not violate the entry/exit criteria.
14089 CS
->getCapturedDecl()->setNothrow();
14092 OMPLoopBasedDirective::HelperExprs B
;
14093 // In presence of clause 'collapse' with number of loops, it will
14094 // define the nested loops number.
14095 unsigned NestedLoopCount
= checkOpenMPLoop(
14096 OMPD_teams_distribute_simd
, getCollapseNumberExpr(Clauses
),
14097 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14098 VarsWithImplicitDSA
, B
);
14100 if (NestedLoopCount
== 0)
14101 return StmtError();
14103 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14104 "omp teams distribute simd loop exprs were not built");
14106 if (!CurContext
->isDependentContext()) {
14107 // Finalize the clauses that need pre-built expressions for CodeGen.
14108 for (OMPClause
*C
: Clauses
) {
14109 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14110 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14111 B
.NumIterations
, *this, CurScope
,
14113 return StmtError();
14117 if (checkSimdlenSafelenSpecified(*this, Clauses
))
14118 return StmtError();
14120 setFunctionHasBranchProtectedScope();
14122 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
14124 return OMPTeamsDistributeSimdDirective::Create(
14125 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14128 StmtResult
Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14129 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14130 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14132 return StmtError();
14134 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14135 // 1.2.2 OpenMP Language Terminology
14136 // Structured block - An executable statement with a single entry at the
14137 // top and a single exit at the bottom.
14138 // The point of exit cannot be a branch out of the structured block.
14139 // longjmp() and throw() must not violate the entry/exit criteria.
14140 CS
->getCapturedDecl()->setNothrow();
14142 for (int ThisCaptureLevel
=
14143 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd
);
14144 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14145 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14146 // 1.2.2 OpenMP Language Terminology
14147 // Structured block - An executable statement with a single entry at the
14148 // top and a single exit at the bottom.
14149 // The point of exit cannot be a branch out of the structured block.
14150 // longjmp() and throw() must not violate the entry/exit criteria.
14151 CS
->getCapturedDecl()->setNothrow();
14154 OMPLoopBasedDirective::HelperExprs B
;
14155 // In presence of clause 'collapse' with number of loops, it will
14156 // define the nested loops number.
14157 unsigned NestedLoopCount
= checkOpenMPLoop(
14158 OMPD_teams_distribute_parallel_for_simd
, getCollapseNumberExpr(Clauses
),
14159 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14160 VarsWithImplicitDSA
, B
);
14162 if (NestedLoopCount
== 0)
14163 return StmtError();
14165 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14166 "omp for loop exprs were not built");
14168 if (!CurContext
->isDependentContext()) {
14169 // Finalize the clauses that need pre-built expressions for CodeGen.
14170 for (OMPClause
*C
: Clauses
) {
14171 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14172 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14173 B
.NumIterations
, *this, CurScope
,
14175 return StmtError();
14179 if (checkSimdlenSafelenSpecified(*this, Clauses
))
14180 return StmtError();
14182 setFunctionHasBranchProtectedScope();
14184 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
14186 return OMPTeamsDistributeParallelForSimdDirective::Create(
14187 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14190 StmtResult
Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14191 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14192 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14194 return StmtError();
14196 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14197 // 1.2.2 OpenMP Language Terminology
14198 // Structured block - An executable statement with a single entry at the
14199 // top and a single exit at the bottom.
14200 // The point of exit cannot be a branch out of the structured block.
14201 // longjmp() and throw() must not violate the entry/exit criteria.
14202 CS
->getCapturedDecl()->setNothrow();
14204 for (int ThisCaptureLevel
=
14205 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for
);
14206 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14207 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14208 // 1.2.2 OpenMP Language Terminology
14209 // Structured block - An executable statement with a single entry at the
14210 // top and a single exit at the bottom.
14211 // The point of exit cannot be a branch out of the structured block.
14212 // longjmp() and throw() must not violate the entry/exit criteria.
14213 CS
->getCapturedDecl()->setNothrow();
14216 OMPLoopBasedDirective::HelperExprs B
;
14217 // In presence of clause 'collapse' with number of loops, it will
14218 // define the nested loops number.
14219 unsigned NestedLoopCount
= checkOpenMPLoop(
14220 OMPD_teams_distribute_parallel_for
, getCollapseNumberExpr(Clauses
),
14221 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14222 VarsWithImplicitDSA
, B
);
14224 if (NestedLoopCount
== 0)
14225 return StmtError();
14227 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14228 "omp for loop exprs were not built");
14230 setFunctionHasBranchProtectedScope();
14232 DSAStack
->setParentTeamsRegionLoc(StartLoc
);
14234 return OMPTeamsDistributeParallelForDirective::Create(
14235 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
14236 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
14239 StmtResult
Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef
<OMPClause
*> Clauses
,
14241 SourceLocation StartLoc
,
14242 SourceLocation EndLoc
) {
14244 return StmtError();
14246 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14247 // 1.2.2 OpenMP Language Terminology
14248 // Structured block - An executable statement with a single entry at the
14249 // top and a single exit at the bottom.
14250 // The point of exit cannot be a branch out of the structured block.
14251 // longjmp() and throw() must not violate the entry/exit criteria.
14252 CS
->getCapturedDecl()->setNothrow();
14254 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(OMPD_target_teams
);
14255 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14256 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14257 // 1.2.2 OpenMP Language Terminology
14258 // Structured block - An executable statement with a single entry at the
14259 // top and a single exit at the bottom.
14260 // The point of exit cannot be a branch out of the structured block.
14261 // longjmp() and throw() must not violate the entry/exit criteria.
14262 CS
->getCapturedDecl()->setNothrow();
14264 setFunctionHasBranchProtectedScope();
14266 return OMPTargetTeamsDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
14270 StmtResult
Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14271 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14272 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14274 return StmtError();
14276 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14277 // 1.2.2 OpenMP Language Terminology
14278 // Structured block - An executable statement with a single entry at the
14279 // top and a single exit at the bottom.
14280 // The point of exit cannot be a branch out of the structured block.
14281 // longjmp() and throw() must not violate the entry/exit criteria.
14282 CS
->getCapturedDecl()->setNothrow();
14283 for (int ThisCaptureLevel
=
14284 getOpenMPCaptureLevels(OMPD_target_teams_distribute
);
14285 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14286 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14287 // 1.2.2 OpenMP Language Terminology
14288 // Structured block - An executable statement with a single entry at the
14289 // top and a single exit at the bottom.
14290 // The point of exit cannot be a branch out of the structured block.
14291 // longjmp() and throw() must not violate the entry/exit criteria.
14292 CS
->getCapturedDecl()->setNothrow();
14295 OMPLoopBasedDirective::HelperExprs B
;
14296 // In presence of clause 'collapse' with number of loops, it will
14297 // define the nested loops number.
14298 unsigned NestedLoopCount
= checkOpenMPLoop(
14299 OMPD_target_teams_distribute
, getCollapseNumberExpr(Clauses
),
14300 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14301 VarsWithImplicitDSA
, B
);
14302 if (NestedLoopCount
== 0)
14303 return StmtError();
14305 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14306 "omp target teams distribute loop exprs were not built");
14308 setFunctionHasBranchProtectedScope();
14309 return OMPTargetTeamsDistributeDirective::Create(
14310 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14313 StmtResult
Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14314 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14315 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14317 return StmtError();
14319 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14320 // 1.2.2 OpenMP Language Terminology
14321 // Structured block - An executable statement with a single entry at the
14322 // top and a single exit at the bottom.
14323 // The point of exit cannot be a branch out of the structured block.
14324 // longjmp() and throw() must not violate the entry/exit criteria.
14325 CS
->getCapturedDecl()->setNothrow();
14326 for (int ThisCaptureLevel
=
14327 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for
);
14328 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14329 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14330 // 1.2.2 OpenMP Language Terminology
14331 // Structured block - An executable statement with a single entry at the
14332 // top and a single exit at the bottom.
14333 // The point of exit cannot be a branch out of the structured block.
14334 // longjmp() and throw() must not violate the entry/exit criteria.
14335 CS
->getCapturedDecl()->setNothrow();
14338 OMPLoopBasedDirective::HelperExprs B
;
14339 // In presence of clause 'collapse' with number of loops, it will
14340 // define the nested loops number.
14341 unsigned NestedLoopCount
= checkOpenMPLoop(
14342 OMPD_target_teams_distribute_parallel_for
, getCollapseNumberExpr(Clauses
),
14343 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14344 VarsWithImplicitDSA
, B
);
14345 if (NestedLoopCount
== 0)
14346 return StmtError();
14348 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14349 "omp target teams distribute parallel for loop exprs were not built");
14351 if (!CurContext
->isDependentContext()) {
14352 // Finalize the clauses that need pre-built expressions for CodeGen.
14353 for (OMPClause
*C
: Clauses
) {
14354 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14355 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14356 B
.NumIterations
, *this, CurScope
,
14358 return StmtError();
14362 setFunctionHasBranchProtectedScope();
14363 return OMPTargetTeamsDistributeParallelForDirective::Create(
14364 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
,
14365 DSAStack
->getTaskgroupReductionRef(), DSAStack
->isCancelRegion());
14368 StmtResult
Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14369 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14370 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14372 return StmtError();
14374 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14375 // 1.2.2 OpenMP Language Terminology
14376 // Structured block - An executable statement with a single entry at the
14377 // top and a single exit at the bottom.
14378 // The point of exit cannot be a branch out of the structured block.
14379 // longjmp() and throw() must not violate the entry/exit criteria.
14380 CS
->getCapturedDecl()->setNothrow();
14381 for (int ThisCaptureLevel
= getOpenMPCaptureLevels(
14382 OMPD_target_teams_distribute_parallel_for_simd
);
14383 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14384 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14385 // 1.2.2 OpenMP Language Terminology
14386 // Structured block - An executable statement with a single entry at the
14387 // top and a single exit at the bottom.
14388 // The point of exit cannot be a branch out of the structured block.
14389 // longjmp() and throw() must not violate the entry/exit criteria.
14390 CS
->getCapturedDecl()->setNothrow();
14393 OMPLoopBasedDirective::HelperExprs B
;
14394 // In presence of clause 'collapse' with number of loops, it will
14395 // define the nested loops number.
14396 unsigned NestedLoopCount
=
14397 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd
,
14398 getCollapseNumberExpr(Clauses
),
14399 nullptr /*ordered not a clause on distribute*/, CS
, *this,
14400 *DSAStack
, VarsWithImplicitDSA
, B
);
14401 if (NestedLoopCount
== 0)
14402 return StmtError();
14404 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14405 "omp target teams distribute parallel for simd loop exprs were not "
14408 if (!CurContext
->isDependentContext()) {
14409 // Finalize the clauses that need pre-built expressions for CodeGen.
14410 for (OMPClause
*C
: Clauses
) {
14411 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14412 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14413 B
.NumIterations
, *this, CurScope
,
14415 return StmtError();
14419 if (checkSimdlenSafelenSpecified(*this, Clauses
))
14420 return StmtError();
14422 setFunctionHasBranchProtectedScope();
14423 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14424 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14427 StmtResult
Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14428 ArrayRef
<OMPClause
*> Clauses
, Stmt
*AStmt
, SourceLocation StartLoc
,
14429 SourceLocation EndLoc
, VarsWithInheritedDSAType
&VarsWithImplicitDSA
) {
14431 return StmtError();
14433 auto *CS
= cast
<CapturedStmt
>(AStmt
);
14434 // 1.2.2 OpenMP Language Terminology
14435 // Structured block - An executable statement with a single entry at the
14436 // top and a single exit at the bottom.
14437 // The point of exit cannot be a branch out of the structured block.
14438 // longjmp() and throw() must not violate the entry/exit criteria.
14439 CS
->getCapturedDecl()->setNothrow();
14440 for (int ThisCaptureLevel
=
14441 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd
);
14442 ThisCaptureLevel
> 1; --ThisCaptureLevel
) {
14443 CS
= cast
<CapturedStmt
>(CS
->getCapturedStmt());
14444 // 1.2.2 OpenMP Language Terminology
14445 // Structured block - An executable statement with a single entry at the
14446 // top and a single exit at the bottom.
14447 // The point of exit cannot be a branch out of the structured block.
14448 // longjmp() and throw() must not violate the entry/exit criteria.
14449 CS
->getCapturedDecl()->setNothrow();
14452 OMPLoopBasedDirective::HelperExprs B
;
14453 // In presence of clause 'collapse' with number of loops, it will
14454 // define the nested loops number.
14455 unsigned NestedLoopCount
= checkOpenMPLoop(
14456 OMPD_target_teams_distribute_simd
, getCollapseNumberExpr(Clauses
),
14457 nullptr /*ordered not a clause on distribute*/, CS
, *this, *DSAStack
,
14458 VarsWithImplicitDSA
, B
);
14459 if (NestedLoopCount
== 0)
14460 return StmtError();
14462 assert((CurContext
->isDependentContext() || B
.builtAll()) &&
14463 "omp target teams distribute simd loop exprs were not built");
14465 if (!CurContext
->isDependentContext()) {
14466 // Finalize the clauses that need pre-built expressions for CodeGen.
14467 for (OMPClause
*C
: Clauses
) {
14468 if (auto *LC
= dyn_cast
<OMPLinearClause
>(C
))
14469 if (FinishOpenMPLinearClause(*LC
, cast
<DeclRefExpr
>(B
.IterationVarRef
),
14470 B
.NumIterations
, *this, CurScope
,
14472 return StmtError();
14476 if (checkSimdlenSafelenSpecified(*this, Clauses
))
14477 return StmtError();
14479 setFunctionHasBranchProtectedScope();
14480 return OMPTargetTeamsDistributeSimdDirective::Create(
14481 Context
, StartLoc
, EndLoc
, NestedLoopCount
, Clauses
, AStmt
, B
);
14484 bool Sema::checkTransformableLoopNest(
14485 OpenMPDirectiveKind Kind
, Stmt
*AStmt
, int NumLoops
,
14486 SmallVectorImpl
<OMPLoopBasedDirective::HelperExprs
> &LoopHelpers
,
14488 SmallVectorImpl
<SmallVector
<llvm::PointerUnion
<Stmt
*, Decl
*>, 0>>
14490 OriginalInits
.emplace_back();
14491 bool Result
= OMPLoopBasedDirective::doForAllLoops(
14492 AStmt
->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops
,
14493 [this, &LoopHelpers
, &Body
, &OriginalInits
, Kind
](unsigned Cnt
,
14495 VarsWithInheritedDSAType TmpDSA
;
14496 unsigned SingleNumLoops
=
14497 checkOpenMPLoop(Kind
, nullptr, nullptr, CurStmt
, *this, *DSAStack
,
14498 TmpDSA
, LoopHelpers
[Cnt
]);
14499 if (SingleNumLoops
== 0)
14501 assert(SingleNumLoops
== 1 && "Expect single loop iteration space");
14502 if (auto *For
= dyn_cast
<ForStmt
>(CurStmt
)) {
14503 OriginalInits
.back().push_back(For
->getInit());
14504 Body
= For
->getBody();
14506 assert(isa
<CXXForRangeStmt
>(CurStmt
) &&
14507 "Expected canonical for or range-based for loops.");
14508 auto *CXXFor
= cast
<CXXForRangeStmt
>(CurStmt
);
14509 OriginalInits
.back().push_back(CXXFor
->getBeginStmt());
14510 Body
= CXXFor
->getBody();
14512 OriginalInits
.emplace_back();
14515 [&OriginalInits
](OMPLoopBasedDirective
*Transform
) {
14516 Stmt
*DependentPreInits
;
14517 if (auto *Dir
= dyn_cast
<OMPTileDirective
>(Transform
))
14518 DependentPreInits
= Dir
->getPreInits();
14519 else if (auto *Dir
= dyn_cast
<OMPUnrollDirective
>(Transform
))
14520 DependentPreInits
= Dir
->getPreInits();
14522 llvm_unreachable("Unhandled loop transformation");
14523 if (!DependentPreInits
)
14525 llvm::append_range(OriginalInits
.back(),
14526 cast
<DeclStmt
>(DependentPreInits
)->getDeclGroup());
14528 assert(OriginalInits
.back().empty() && "No preinit after innermost loop");
14529 OriginalInits
.pop_back();
14533 StmtResult
Sema::ActOnOpenMPTileDirective(ArrayRef
<OMPClause
*> Clauses
,
14534 Stmt
*AStmt
, SourceLocation StartLoc
,
14535 SourceLocation EndLoc
) {
14536 auto SizesClauses
=
14537 OMPExecutableDirective::getClausesOfKind
<OMPSizesClause
>(Clauses
);
14538 if (SizesClauses
.empty()) {
14539 // A missing 'sizes' clause is already reported by the parser.
14540 return StmtError();
14542 const OMPSizesClause
*SizesClause
= *SizesClauses
.begin();
14543 unsigned NumLoops
= SizesClause
->getNumSizes();
14545 // Empty statement should only be possible if there already was an error.
14547 return StmtError();
14549 // Verify and diagnose loop nest.
14550 SmallVector
<OMPLoopBasedDirective::HelperExprs
, 4> LoopHelpers(NumLoops
);
14551 Stmt
*Body
= nullptr;
14552 SmallVector
<SmallVector
<llvm::PointerUnion
<Stmt
*, Decl
*>, 0>, 4>
14554 if (!checkTransformableLoopNest(OMPD_tile
, AStmt
, NumLoops
, LoopHelpers
, Body
,
14556 return StmtError();
14558 // Delay tiling to when template is completely instantiated.
14559 if (CurContext
->isDependentContext())
14560 return OMPTileDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
,
14561 NumLoops
, AStmt
, nullptr, nullptr);
14563 SmallVector
<Decl
*, 4> PreInits
;
14565 // Create iteration variables for the generated loops.
14566 SmallVector
<VarDecl
*, 4> FloorIndVars
;
14567 SmallVector
<VarDecl
*, 4> TileIndVars
;
14568 FloorIndVars
.resize(NumLoops
);
14569 TileIndVars
.resize(NumLoops
);
14570 for (unsigned I
= 0; I
< NumLoops
; ++I
) {
14571 OMPLoopBasedDirective::HelperExprs
&LoopHelper
= LoopHelpers
[I
];
14573 assert(LoopHelper
.Counters
.size() == 1 &&
14574 "Expect single-dimensional loop iteration space");
14575 auto *OrigCntVar
= cast
<DeclRefExpr
>(LoopHelper
.Counters
.front());
14576 std::string OrigVarName
= OrigCntVar
->getNameInfo().getAsString();
14577 DeclRefExpr
*IterVarRef
= cast
<DeclRefExpr
>(LoopHelper
.IterationVarRef
);
14578 QualType CntTy
= IterVarRef
->getType();
14580 // Iteration variable for the floor (i.e. outer) loop.
14582 std::string FloorCntName
=
14583 (Twine(".floor_") + llvm::utostr(I
) + ".iv." + OrigVarName
).str();
14584 VarDecl
*FloorCntDecl
=
14585 buildVarDecl(*this, {}, CntTy
, FloorCntName
, nullptr, OrigCntVar
);
14586 FloorIndVars
[I
] = FloorCntDecl
;
14589 // Iteration variable for the tile (i.e. inner) loop.
14591 std::string TileCntName
=
14592 (Twine(".tile_") + llvm::utostr(I
) + ".iv." + OrigVarName
).str();
14594 // Reuse the iteration variable created by checkOpenMPLoop. It is also
14595 // used by the expressions to derive the original iteration variable's
14596 // value from the logical iteration number.
14597 auto *TileCntDecl
= cast
<VarDecl
>(IterVarRef
->getDecl());
14598 TileCntDecl
->setDeclName(&PP
.getIdentifierTable().get(TileCntName
));
14599 TileIndVars
[I
] = TileCntDecl
;
14601 for (auto &P
: OriginalInits
[I
]) {
14602 if (auto *D
= P
.dyn_cast
<Decl
*>())
14603 PreInits
.push_back(D
);
14604 else if (auto *PI
= dyn_cast_or_null
<DeclStmt
>(P
.dyn_cast
<Stmt
*>()))
14605 PreInits
.append(PI
->decl_begin(), PI
->decl_end());
14607 if (auto *PI
= cast_or_null
<DeclStmt
>(LoopHelper
.PreInits
))
14608 PreInits
.append(PI
->decl_begin(), PI
->decl_end());
14609 // Gather declarations for the data members used as counters.
14610 for (Expr
*CounterRef
: LoopHelper
.Counters
) {
14611 auto *CounterDecl
= cast
<DeclRefExpr
>(CounterRef
)->getDecl();
14612 if (isa
<OMPCapturedExprDecl
>(CounterDecl
))
14613 PreInits
.push_back(CounterDecl
);
14617 // Once the original iteration values are set, append the innermost body.
14618 Stmt
*Inner
= Body
;
14620 // Create tile loops from the inside to the outside.
14621 for (int I
= NumLoops
- 1; I
>= 0; --I
) {
14622 OMPLoopBasedDirective::HelperExprs
&LoopHelper
= LoopHelpers
[I
];
14623 Expr
*NumIterations
= LoopHelper
.NumIterations
;
14624 auto *OrigCntVar
= cast
<DeclRefExpr
>(LoopHelper
.Counters
[0]);
14625 QualType CntTy
= OrigCntVar
->getType();
14626 Expr
*DimTileSize
= SizesClause
->getSizesRefs()[I
];
14627 Scope
*CurScope
= getCurScope();
14629 // Commonly used variables.
14630 DeclRefExpr
*TileIV
= buildDeclRefExpr(*this, TileIndVars
[I
], CntTy
,
14631 OrigCntVar
->getExprLoc());
14632 DeclRefExpr
*FloorIV
= buildDeclRefExpr(*this, FloorIndVars
[I
], CntTy
,
14633 OrigCntVar
->getExprLoc());
14635 // For init-statement: auto .tile.iv = .floor.iv
14636 AddInitializerToDecl(TileIndVars
[I
], DefaultLvalueConversion(FloorIV
).get(),
14637 /*DirectInit=*/false);
14638 Decl
*CounterDecl
= TileIndVars
[I
];
14639 StmtResult InitStmt
= new (Context
)
14640 DeclStmt(DeclGroupRef::Create(Context
, &CounterDecl
, 1),
14641 OrigCntVar
->getBeginLoc(), OrigCntVar
->getEndLoc());
14642 if (!InitStmt
.isUsable())
14643 return StmtError();
14645 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14647 ExprResult EndOfTile
= BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(),
14648 BO_Add
, FloorIV
, DimTileSize
);
14649 if (!EndOfTile
.isUsable())
14650 return StmtError();
14651 ExprResult IsPartialTile
=
14652 BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(), BO_LT
,
14653 NumIterations
, EndOfTile
.get());
14654 if (!IsPartialTile
.isUsable())
14655 return StmtError();
14656 ExprResult MinTileAndIterSpace
= ActOnConditionalOp(
14657 LoopHelper
.Cond
->getBeginLoc(), LoopHelper
.Cond
->getEndLoc(),
14658 IsPartialTile
.get(), NumIterations
, EndOfTile
.get());
14659 if (!MinTileAndIterSpace
.isUsable())
14660 return StmtError();
14661 ExprResult CondExpr
= BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(),
14662 BO_LT
, TileIV
, MinTileAndIterSpace
.get());
14663 if (!CondExpr
.isUsable())
14664 return StmtError();
14666 // For incr-statement: ++.tile.iv
14667 ExprResult IncrStmt
=
14668 BuildUnaryOp(CurScope
, LoopHelper
.Inc
->getExprLoc(), UO_PreInc
, TileIV
);
14669 if (!IncrStmt
.isUsable())
14670 return StmtError();
14672 // Statements to set the original iteration variable's value from the
14673 // logical iteration number.
14674 // Generated for loop is:
14675 // Original_for_init;
14676 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14677 // NumIterations); ++.tile.iv) {
14679 // Original_counter_update;
14681 // FIXME: If the innermost body is an loop itself, inserting these
14682 // statements stops it being recognized as a perfectly nested loop (e.g.
14683 // for applying tiling again). If this is the case, sink the expressions
14684 // further into the inner loop.
14685 SmallVector
<Stmt
*, 4> BodyParts
;
14686 BodyParts
.append(LoopHelper
.Updates
.begin(), LoopHelper
.Updates
.end());
14687 BodyParts
.push_back(Inner
);
14688 Inner
= CompoundStmt::Create(Context
, BodyParts
, FPOptionsOverride(),
14689 Inner
->getBeginLoc(), Inner
->getEndLoc());
14690 Inner
= new (Context
)
14691 ForStmt(Context
, InitStmt
.get(), CondExpr
.get(), nullptr,
14692 IncrStmt
.get(), Inner
, LoopHelper
.Init
->getBeginLoc(),
14693 LoopHelper
.Init
->getBeginLoc(), LoopHelper
.Inc
->getEndLoc());
14696 // Create floor loops from the inside to the outside.
14697 for (int I
= NumLoops
- 1; I
>= 0; --I
) {
14698 auto &LoopHelper
= LoopHelpers
[I
];
14699 Expr
*NumIterations
= LoopHelper
.NumIterations
;
14700 DeclRefExpr
*OrigCntVar
= cast
<DeclRefExpr
>(LoopHelper
.Counters
[0]);
14701 QualType CntTy
= OrigCntVar
->getType();
14702 Expr
*DimTileSize
= SizesClause
->getSizesRefs()[I
];
14703 Scope
*CurScope
= getCurScope();
14705 // Commonly used variables.
14706 DeclRefExpr
*FloorIV
= buildDeclRefExpr(*this, FloorIndVars
[I
], CntTy
,
14707 OrigCntVar
->getExprLoc());
14709 // For init-statement: auto .floor.iv = 0
14710 AddInitializerToDecl(
14712 ActOnIntegerConstant(LoopHelper
.Init
->getExprLoc(), 0).get(),
14713 /*DirectInit=*/false);
14714 Decl
*CounterDecl
= FloorIndVars
[I
];
14715 StmtResult InitStmt
= new (Context
)
14716 DeclStmt(DeclGroupRef::Create(Context
, &CounterDecl
, 1),
14717 OrigCntVar
->getBeginLoc(), OrigCntVar
->getEndLoc());
14718 if (!InitStmt
.isUsable())
14719 return StmtError();
14721 // For cond-expression: .floor.iv < NumIterations
14722 ExprResult CondExpr
= BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(),
14723 BO_LT
, FloorIV
, NumIterations
);
14724 if (!CondExpr
.isUsable())
14725 return StmtError();
14727 // For incr-statement: .floor.iv += DimTileSize
14728 ExprResult IncrStmt
= BuildBinOp(CurScope
, LoopHelper
.Inc
->getExprLoc(),
14729 BO_AddAssign
, FloorIV
, DimTileSize
);
14730 if (!IncrStmt
.isUsable())
14731 return StmtError();
14733 Inner
= new (Context
)
14734 ForStmt(Context
, InitStmt
.get(), CondExpr
.get(), nullptr,
14735 IncrStmt
.get(), Inner
, LoopHelper
.Init
->getBeginLoc(),
14736 LoopHelper
.Init
->getBeginLoc(), LoopHelper
.Inc
->getEndLoc());
14739 return OMPTileDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, NumLoops
,
14741 buildPreInits(Context
, PreInits
));
14744 StmtResult
Sema::ActOnOpenMPUnrollDirective(ArrayRef
<OMPClause
*> Clauses
,
14746 SourceLocation StartLoc
,
14747 SourceLocation EndLoc
) {
14748 // Empty statement should only be possible if there already was an error.
14750 return StmtError();
14752 if (checkMutuallyExclusiveClauses(*this, Clauses
, {OMPC_partial
, OMPC_full
}))
14753 return StmtError();
14755 const OMPFullClause
*FullClause
=
14756 OMPExecutableDirective::getSingleClause
<OMPFullClause
>(Clauses
);
14757 const OMPPartialClause
*PartialClause
=
14758 OMPExecutableDirective::getSingleClause
<OMPPartialClause
>(Clauses
);
14759 assert(!(FullClause
&& PartialClause
) &&
14760 "mutual exclusivity must have been checked before");
14762 constexpr unsigned NumLoops
= 1;
14763 Stmt
*Body
= nullptr;
14764 SmallVector
<OMPLoopBasedDirective::HelperExprs
, NumLoops
> LoopHelpers(
14766 SmallVector
<SmallVector
<llvm::PointerUnion
<Stmt
*, Decl
*>, 0>, NumLoops
+ 1>
14768 if (!checkTransformableLoopNest(OMPD_unroll
, AStmt
, NumLoops
, LoopHelpers
,
14769 Body
, OriginalInits
))
14770 return StmtError();
14772 unsigned NumGeneratedLoops
= PartialClause
? 1 : 0;
14774 // Delay unrolling to when template is completely instantiated.
14775 if (CurContext
->isDependentContext())
14776 return OMPUnrollDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
14777 NumGeneratedLoops
, nullptr, nullptr);
14779 OMPLoopBasedDirective::HelperExprs
&LoopHelper
= LoopHelpers
.front();
14782 if (!VerifyPositiveIntegerConstantInClause(
14783 LoopHelper
.NumIterations
, OMPC_full
, /*StrictlyPositive=*/false,
14784 /*SuppressExprDiags=*/true)
14786 Diag(AStmt
->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count
);
14787 Diag(FullClause
->getBeginLoc(), diag::note_omp_directive_here
)
14788 << "#pragma omp unroll full";
14789 return StmtError();
14793 // The generated loop may only be passed to other loop-associated directive
14794 // when a partial clause is specified. Without the requirement it is
14795 // sufficient to generate loop unroll metadata at code-generation.
14796 if (NumGeneratedLoops
== 0)
14797 return OMPUnrollDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
14798 NumGeneratedLoops
, nullptr, nullptr);
14800 // Otherwise, we need to provide a de-sugared/transformed AST that can be
14801 // associated with another loop directive.
14803 // The canonical loop analysis return by checkTransformableLoopNest assumes
14804 // the following structure to be the same loop without transformations or
14805 // directives applied: \code OriginalInits; LoopHelper.PreInits;
14806 // LoopHelper.Counters;
14807 // for (; IV < LoopHelper.NumIterations; ++IV) {
14808 // LoopHelper.Updates;
14812 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14813 // and referenced by LoopHelper.IterationVarRef.
14815 // The unrolling directive transforms this into the following loop:
14817 // OriginalInits; \
14818 // LoopHelper.PreInits; > NewPreInits
14819 // LoopHelper.Counters; /
14820 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14821 // #pragma clang loop unroll_count(Factor)
14822 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14824 // LoopHelper.Updates;
14829 // where UIV is a new logical iteration counter. IV must be the same VarDecl
14830 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14831 // references it. If the partially unrolled loop is associated with another
14832 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14833 // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14834 // OpenMP canonical loop. The inner loop is not an associable canonical loop
14835 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14836 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14837 // property of the OMPLoopBasedDirective instead of statements in
14838 // CompoundStatement. This is to allow the loop to become a non-outermost loop
14839 // of a canonical loop nest where these PreInits are emitted before the
14840 // outermost directive.
14842 // Determine the PreInit declarations.
14843 SmallVector
<Decl
*, 4> PreInits
;
14844 assert(OriginalInits
.size() == 1 &&
14845 "Expecting a single-dimensional loop iteration space");
14846 for (auto &P
: OriginalInits
[0]) {
14847 if (auto *D
= P
.dyn_cast
<Decl
*>())
14848 PreInits
.push_back(D
);
14849 else if (auto *PI
= dyn_cast_or_null
<DeclStmt
>(P
.dyn_cast
<Stmt
*>()))
14850 PreInits
.append(PI
->decl_begin(), PI
->decl_end());
14852 if (auto *PI
= cast_or_null
<DeclStmt
>(LoopHelper
.PreInits
))
14853 PreInits
.append(PI
->decl_begin(), PI
->decl_end());
14854 // Gather declarations for the data members used as counters.
14855 for (Expr
*CounterRef
: LoopHelper
.Counters
) {
14856 auto *CounterDecl
= cast
<DeclRefExpr
>(CounterRef
)->getDecl();
14857 if (isa
<OMPCapturedExprDecl
>(CounterDecl
))
14858 PreInits
.push_back(CounterDecl
);
14861 auto *IterationVarRef
= cast
<DeclRefExpr
>(LoopHelper
.IterationVarRef
);
14862 QualType IVTy
= IterationVarRef
->getType();
14863 assert(LoopHelper
.Counters
.size() == 1 &&
14864 "Expecting a single-dimensional loop iteration space");
14865 auto *OrigVar
= cast
<DeclRefExpr
>(LoopHelper
.Counters
.front());
14867 // Determine the unroll factor.
14869 SourceLocation FactorLoc
;
14870 if (Expr
*FactorVal
= PartialClause
->getFactor()) {
14871 Factor
= FactorVal
->getIntegerConstantExpr(Context
)->getZExtValue();
14872 FactorLoc
= FactorVal
->getExprLoc();
14874 // TODO: Use a better profitability model.
14877 assert(Factor
> 0 && "Expected positive unroll factor");
14878 auto MakeFactorExpr
= [this, Factor
, IVTy
, FactorLoc
]() {
14879 return IntegerLiteral::Create(
14880 Context
, llvm::APInt(Context
.getIntWidth(IVTy
), Factor
), IVTy
,
14884 // Iteration variable SourceLocations.
14885 SourceLocation OrigVarLoc
= OrigVar
->getExprLoc();
14886 SourceLocation OrigVarLocBegin
= OrigVar
->getBeginLoc();
14887 SourceLocation OrigVarLocEnd
= OrigVar
->getEndLoc();
14889 // Internal variable names.
14890 std::string OrigVarName
= OrigVar
->getNameInfo().getAsString();
14891 std::string OuterIVName
= (Twine(".unrolled.iv.") + OrigVarName
).str();
14892 std::string InnerIVName
= (Twine(".unroll_inner.iv.") + OrigVarName
).str();
14893 std::string InnerTripCountName
=
14894 (Twine(".unroll_inner.tripcount.") + OrigVarName
).str();
14896 // Create the iteration variable for the unrolled loop.
14897 VarDecl
*OuterIVDecl
=
14898 buildVarDecl(*this, {}, IVTy
, OuterIVName
, nullptr, OrigVar
);
14899 auto MakeOuterRef
= [this, OuterIVDecl
, IVTy
, OrigVarLoc
]() {
14900 return buildDeclRefExpr(*this, OuterIVDecl
, IVTy
, OrigVarLoc
);
14903 // Iteration variable for the inner loop: Reuse the iteration variable created
14904 // by checkOpenMPLoop.
14905 auto *InnerIVDecl
= cast
<VarDecl
>(IterationVarRef
->getDecl());
14906 InnerIVDecl
->setDeclName(&PP
.getIdentifierTable().get(InnerIVName
));
14907 auto MakeInnerRef
= [this, InnerIVDecl
, IVTy
, OrigVarLoc
]() {
14908 return buildDeclRefExpr(*this, InnerIVDecl
, IVTy
, OrigVarLoc
);
14911 // Make a copy of the NumIterations expression for each use: By the AST
14912 // constraints, every expression object in a DeclContext must be unique.
14913 CaptureVars
CopyTransformer(*this);
14914 auto MakeNumIterations
= [&CopyTransformer
, &LoopHelper
]() -> Expr
* {
14915 return AssertSuccess(
14916 CopyTransformer
.TransformExpr(LoopHelper
.NumIterations
));
14919 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14920 ExprResult LValueConv
= DefaultLvalueConversion(MakeOuterRef());
14921 AddInitializerToDecl(InnerIVDecl
, LValueConv
.get(), /*DirectInit=*/false);
14922 StmtResult InnerInit
= new (Context
)
14923 DeclStmt(DeclGroupRef(InnerIVDecl
), OrigVarLocBegin
, OrigVarLocEnd
);
14924 if (!InnerInit
.isUsable())
14925 return StmtError();
14927 // Inner For cond-expression:
14929 // .unroll_inner.iv < .unrolled.iv + Factor &&
14930 // .unroll_inner.iv < NumIterations
14932 // This conjunction of two conditions allows ScalarEvolution to derive the
14933 // maximum trip count of the inner loop.
14934 ExprResult EndOfTile
= BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(),
14935 BO_Add
, MakeOuterRef(), MakeFactorExpr());
14936 if (!EndOfTile
.isUsable())
14937 return StmtError();
14938 ExprResult InnerCond1
= BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(),
14939 BO_LT
, MakeInnerRef(), EndOfTile
.get());
14940 if (!InnerCond1
.isUsable())
14941 return StmtError();
14942 ExprResult InnerCond2
=
14943 BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(), BO_LT
, MakeInnerRef(),
14944 MakeNumIterations());
14945 if (!InnerCond2
.isUsable())
14946 return StmtError();
14947 ExprResult InnerCond
=
14948 BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(), BO_LAnd
,
14949 InnerCond1
.get(), InnerCond2
.get());
14950 if (!InnerCond
.isUsable())
14951 return StmtError();
14953 // Inner For incr-statement: ++.unroll_inner.iv
14954 ExprResult InnerIncr
= BuildUnaryOp(CurScope
, LoopHelper
.Inc
->getExprLoc(),
14955 UO_PreInc
, MakeInnerRef());
14956 if (!InnerIncr
.isUsable())
14957 return StmtError();
14959 // Inner For statement.
14960 SmallVector
<Stmt
*> InnerBodyStmts
;
14961 InnerBodyStmts
.append(LoopHelper
.Updates
.begin(), LoopHelper
.Updates
.end());
14962 InnerBodyStmts
.push_back(Body
);
14963 CompoundStmt
*InnerBody
=
14964 CompoundStmt::Create(Context
, InnerBodyStmts
, FPOptionsOverride(),
14965 Body
->getBeginLoc(), Body
->getEndLoc());
14966 ForStmt
*InnerFor
= new (Context
)
14967 ForStmt(Context
, InnerInit
.get(), InnerCond
.get(), nullptr,
14968 InnerIncr
.get(), InnerBody
, LoopHelper
.Init
->getBeginLoc(),
14969 LoopHelper
.Init
->getBeginLoc(), LoopHelper
.Inc
->getEndLoc());
14971 // Unroll metadata for the inner loop.
14972 // This needs to take into account the remainder portion of the unrolled loop,
14973 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14974 // supports multiple loop exits. Instead, unroll using a factor equivalent to
14975 // the maximum trip count, which will also generate a remainder loop. Just
14976 // `unroll(enable)` (which could have been useful if the user has not
14977 // specified a concrete factor; even though the outer loop cannot be
14978 // influenced anymore, would avoid more code bloat than necessary) will refuse
14979 // the loop because "Won't unroll; remainder loop could not be generated when
14980 // assuming runtime trip count". Even if it did work, it must not choose a
14981 // larger unroll factor than the maximum loop length, or it would always just
14982 // execute the remainder loop.
14983 LoopHintAttr
*UnrollHintAttr
=
14984 LoopHintAttr::CreateImplicit(Context
, LoopHintAttr::UnrollCount
,
14985 LoopHintAttr::Numeric
, MakeFactorExpr());
14986 AttributedStmt
*InnerUnrolled
=
14987 AttributedStmt::Create(Context
, StartLoc
, {UnrollHintAttr
}, InnerFor
);
14989 // Outer For init-statement: auto .unrolled.iv = 0
14990 AddInitializerToDecl(
14991 OuterIVDecl
, ActOnIntegerConstant(LoopHelper
.Init
->getExprLoc(), 0).get(),
14992 /*DirectInit=*/false);
14993 StmtResult OuterInit
= new (Context
)
14994 DeclStmt(DeclGroupRef(OuterIVDecl
), OrigVarLocBegin
, OrigVarLocEnd
);
14995 if (!OuterInit
.isUsable())
14996 return StmtError();
14998 // Outer For cond-expression: .unrolled.iv < NumIterations
14999 ExprResult OuterConde
=
15000 BuildBinOp(CurScope
, LoopHelper
.Cond
->getExprLoc(), BO_LT
, MakeOuterRef(),
15001 MakeNumIterations());
15002 if (!OuterConde
.isUsable())
15003 return StmtError();
15005 // Outer For incr-statement: .unrolled.iv += Factor
15006 ExprResult OuterIncr
=
15007 BuildBinOp(CurScope
, LoopHelper
.Inc
->getExprLoc(), BO_AddAssign
,
15008 MakeOuterRef(), MakeFactorExpr());
15009 if (!OuterIncr
.isUsable())
15010 return StmtError();
15012 // Outer For statement.
15013 ForStmt
*OuterFor
= new (Context
)
15014 ForStmt(Context
, OuterInit
.get(), OuterConde
.get(), nullptr,
15015 OuterIncr
.get(), InnerUnrolled
, LoopHelper
.Init
->getBeginLoc(),
15016 LoopHelper
.Init
->getBeginLoc(), LoopHelper
.Inc
->getEndLoc());
15018 return OMPUnrollDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
, AStmt
,
15019 NumGeneratedLoops
, OuterFor
,
15020 buildPreInits(Context
, PreInits
));
15023 OMPClause
*Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind
, Expr
*Expr
,
15024 SourceLocation StartLoc
,
15025 SourceLocation LParenLoc
,
15026 SourceLocation EndLoc
) {
15027 OMPClause
*Res
= nullptr;
15030 Res
= ActOnOpenMPFinalClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15032 case OMPC_num_threads
:
15033 Res
= ActOnOpenMPNumThreadsClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15036 Res
= ActOnOpenMPSafelenClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15039 Res
= ActOnOpenMPSimdlenClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15041 case OMPC_allocator
:
15042 Res
= ActOnOpenMPAllocatorClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15044 case OMPC_collapse
:
15045 Res
= ActOnOpenMPCollapseClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15048 Res
= ActOnOpenMPOrderedClause(StartLoc
, EndLoc
, LParenLoc
, Expr
);
15050 case OMPC_num_teams
:
15051 Res
= ActOnOpenMPNumTeamsClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15053 case OMPC_thread_limit
:
15054 Res
= ActOnOpenMPThreadLimitClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15056 case OMPC_priority
:
15057 Res
= ActOnOpenMPPriorityClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15059 case OMPC_grainsize
:
15060 Res
= ActOnOpenMPGrainsizeClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15062 case OMPC_num_tasks
:
15063 Res
= ActOnOpenMPNumTasksClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15066 Res
= ActOnOpenMPHintClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15069 Res
= ActOnOpenMPDepobjClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15072 Res
= ActOnOpenMPDetachClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15074 case OMPC_novariants
:
15075 Res
= ActOnOpenMPNovariantsClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15077 case OMPC_nocontext
:
15078 Res
= ActOnOpenMPNocontextClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15081 Res
= ActOnOpenMPFilterClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15084 Res
= ActOnOpenMPPartialClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15087 Res
= ActOnOpenMPAlignClause(Expr
, StartLoc
, LParenLoc
, EndLoc
);
15092 case OMPC_proc_bind
:
15093 case OMPC_schedule
:
15095 case OMPC_firstprivate
:
15096 case OMPC_lastprivate
:
15098 case OMPC_reduction
:
15099 case OMPC_task_reduction
:
15100 case OMPC_in_reduction
:
15104 case OMPC_copyprivate
:
15107 case OMPC_mergeable
:
15108 case OMPC_threadprivate
:
15110 case OMPC_allocate
:
15127 case OMPC_dist_schedule
:
15128 case OMPC_defaultmap
:
15133 case OMPC_use_device_ptr
:
15134 case OMPC_use_device_addr
:
15135 case OMPC_is_device_ptr
:
15136 case OMPC_unified_address
:
15137 case OMPC_unified_shared_memory
:
15138 case OMPC_reverse_offload
:
15139 case OMPC_dynamic_allocators
:
15140 case OMPC_atomic_default_mem_order
:
15141 case OMPC_device_type
:
15143 case OMPC_nontemporal
:
15146 case OMPC_inclusive
:
15147 case OMPC_exclusive
:
15148 case OMPC_uses_allocators
:
15149 case OMPC_affinity
:
15153 llvm_unreachable("Clause is not allowed.");
15158 // An OpenMP directive such as 'target parallel' has two captured regions:
15159 // for the 'target' and 'parallel' respectively. This function returns
15160 // the region in which to capture expressions associated with a clause.
15161 // A return value of OMPD_unknown signifies that the expression should not
15163 static OpenMPDirectiveKind
getOpenMPCaptureRegionForClause(
15164 OpenMPDirectiveKind DKind
, OpenMPClauseKind CKind
, unsigned OpenMPVersion
,
15165 OpenMPDirectiveKind NameModifier
= OMPD_unknown
) {
15166 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
15170 case OMPD_target_parallel_for_simd
:
15171 if (OpenMPVersion
>= 50 &&
15172 (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)) {
15173 CaptureRegion
= OMPD_parallel
;
15177 case OMPD_target_parallel
:
15178 case OMPD_target_parallel_for
:
15179 case OMPD_target_parallel_loop
:
15180 // If this clause applies to the nested 'parallel' region, capture within
15181 // the 'target' region, otherwise do not capture.
15182 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_parallel
)
15183 CaptureRegion
= OMPD_target
;
15185 case OMPD_target_teams_distribute_parallel_for_simd
:
15186 if (OpenMPVersion
>= 50 &&
15187 (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)) {
15188 CaptureRegion
= OMPD_parallel
;
15192 case OMPD_target_teams_distribute_parallel_for
:
15193 // If this clause applies to the nested 'parallel' region, capture within
15194 // the 'teams' region, otherwise do not capture.
15195 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_parallel
)
15196 CaptureRegion
= OMPD_teams
;
15198 case OMPD_teams_distribute_parallel_for_simd
:
15199 if (OpenMPVersion
>= 50 &&
15200 (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)) {
15201 CaptureRegion
= OMPD_parallel
;
15205 case OMPD_teams_distribute_parallel_for
:
15206 CaptureRegion
= OMPD_teams
;
15208 case OMPD_target_update
:
15209 case OMPD_target_enter_data
:
15210 case OMPD_target_exit_data
:
15211 CaptureRegion
= OMPD_task
;
15213 case OMPD_parallel_masked_taskloop
:
15214 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_taskloop
)
15215 CaptureRegion
= OMPD_parallel
;
15217 case OMPD_parallel_master_taskloop
:
15218 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_taskloop
)
15219 CaptureRegion
= OMPD_parallel
;
15221 case OMPD_parallel_masked_taskloop_simd
:
15222 if ((OpenMPVersion
<= 45 && NameModifier
== OMPD_unknown
) ||
15223 NameModifier
== OMPD_taskloop
) {
15224 CaptureRegion
= OMPD_parallel
;
15227 if (OpenMPVersion
<= 45)
15229 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)
15230 CaptureRegion
= OMPD_taskloop
;
15232 case OMPD_parallel_master_taskloop_simd
:
15233 if ((OpenMPVersion
<= 45 && NameModifier
== OMPD_unknown
) ||
15234 NameModifier
== OMPD_taskloop
) {
15235 CaptureRegion
= OMPD_parallel
;
15238 if (OpenMPVersion
<= 45)
15240 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)
15241 CaptureRegion
= OMPD_taskloop
;
15243 case OMPD_parallel_for_simd
:
15244 if (OpenMPVersion
<= 45)
15246 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)
15247 CaptureRegion
= OMPD_parallel
;
15249 case OMPD_taskloop_simd
:
15250 case OMPD_master_taskloop_simd
:
15251 case OMPD_masked_taskloop_simd
:
15252 if (OpenMPVersion
<= 45)
15254 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)
15255 CaptureRegion
= OMPD_taskloop
;
15257 case OMPD_distribute_parallel_for_simd
:
15258 if (OpenMPVersion
<= 45)
15260 if (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
)
15261 CaptureRegion
= OMPD_parallel
;
15263 case OMPD_target_simd
:
15264 if (OpenMPVersion
>= 50 &&
15265 (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
))
15266 CaptureRegion
= OMPD_target
;
15268 case OMPD_teams_distribute_simd
:
15269 case OMPD_target_teams_distribute_simd
:
15270 if (OpenMPVersion
>= 50 &&
15271 (NameModifier
== OMPD_unknown
|| NameModifier
== OMPD_simd
))
15272 CaptureRegion
= OMPD_teams
;
15275 case OMPD_parallel
:
15276 case OMPD_parallel_master
:
15277 case OMPD_parallel_masked
:
15278 case OMPD_parallel_sections
:
15279 case OMPD_parallel_for
:
15280 case OMPD_parallel_loop
:
15282 case OMPD_target_teams
:
15283 case OMPD_target_teams_distribute
:
15284 case OMPD_target_teams_loop
:
15285 case OMPD_distribute_parallel_for
:
15287 case OMPD_taskloop
:
15288 case OMPD_master_taskloop
:
15289 case OMPD_masked_taskloop
:
15290 case OMPD_target_data
:
15292 case OMPD_for_simd
:
15293 case OMPD_distribute_simd
:
15294 // Do not capture if-clause expressions.
15296 case OMPD_threadprivate
:
15297 case OMPD_allocate
:
15298 case OMPD_taskyield
:
15300 case OMPD_taskwait
:
15301 case OMPD_cancellation_point
:
15305 case OMPD_declare_reduction
:
15306 case OMPD_declare_mapper
:
15307 case OMPD_declare_simd
:
15308 case OMPD_declare_variant
:
15309 case OMPD_begin_declare_variant
:
15310 case OMPD_end_declare_variant
:
15311 case OMPD_declare_target
:
15312 case OMPD_end_declare_target
:
15314 case OMPD_teams_loop
:
15319 case OMPD_sections
:
15324 case OMPD_critical
:
15325 case OMPD_taskgroup
:
15326 case OMPD_distribute
:
15329 case OMPD_teams_distribute
:
15330 case OMPD_requires
:
15331 case OMPD_metadirective
:
15332 llvm_unreachable("Unexpected OpenMP directive with if-clause");
15335 llvm_unreachable("Unknown OpenMP directive");
15338 case OMPC_num_threads
:
15340 case OMPD_target_parallel
:
15341 case OMPD_target_parallel_for
:
15342 case OMPD_target_parallel_for_simd
:
15343 case OMPD_target_parallel_loop
:
15344 CaptureRegion
= OMPD_target
;
15346 case OMPD_teams_distribute_parallel_for
:
15347 case OMPD_teams_distribute_parallel_for_simd
:
15348 case OMPD_target_teams_distribute_parallel_for
:
15349 case OMPD_target_teams_distribute_parallel_for_simd
:
15350 CaptureRegion
= OMPD_teams
;
15352 case OMPD_parallel
:
15353 case OMPD_parallel_master
:
15354 case OMPD_parallel_masked
:
15355 case OMPD_parallel_sections
:
15356 case OMPD_parallel_for
:
15357 case OMPD_parallel_for_simd
:
15358 case OMPD_parallel_loop
:
15359 case OMPD_distribute_parallel_for
:
15360 case OMPD_distribute_parallel_for_simd
:
15361 case OMPD_parallel_master_taskloop
:
15362 case OMPD_parallel_masked_taskloop
:
15363 case OMPD_parallel_master_taskloop_simd
:
15364 case OMPD_parallel_masked_taskloop_simd
:
15365 // Do not capture num_threads-clause expressions.
15367 case OMPD_target_data
:
15368 case OMPD_target_enter_data
:
15369 case OMPD_target_exit_data
:
15370 case OMPD_target_update
:
15372 case OMPD_target_simd
:
15373 case OMPD_target_teams
:
15374 case OMPD_target_teams_distribute
:
15375 case OMPD_target_teams_distribute_simd
:
15378 case OMPD_taskloop
:
15379 case OMPD_taskloop_simd
:
15380 case OMPD_master_taskloop
:
15381 case OMPD_masked_taskloop
:
15382 case OMPD_master_taskloop_simd
:
15383 case OMPD_masked_taskloop_simd
:
15384 case OMPD_threadprivate
:
15385 case OMPD_allocate
:
15386 case OMPD_taskyield
:
15388 case OMPD_taskwait
:
15389 case OMPD_cancellation_point
:
15393 case OMPD_declare_reduction
:
15394 case OMPD_declare_mapper
:
15395 case OMPD_declare_simd
:
15396 case OMPD_declare_variant
:
15397 case OMPD_begin_declare_variant
:
15398 case OMPD_end_declare_variant
:
15399 case OMPD_declare_target
:
15400 case OMPD_end_declare_target
:
15402 case OMPD_teams_loop
:
15403 case OMPD_target_teams_loop
:
15409 case OMPD_for_simd
:
15410 case OMPD_sections
:
15415 case OMPD_critical
:
15416 case OMPD_taskgroup
:
15417 case OMPD_distribute
:
15420 case OMPD_distribute_simd
:
15421 case OMPD_teams_distribute
:
15422 case OMPD_teams_distribute_simd
:
15423 case OMPD_requires
:
15424 case OMPD_metadirective
:
15425 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15428 llvm_unreachable("Unknown OpenMP directive");
15431 case OMPC_num_teams
:
15433 case OMPD_target_teams
:
15434 case OMPD_target_teams_distribute
:
15435 case OMPD_target_teams_distribute_simd
:
15436 case OMPD_target_teams_distribute_parallel_for
:
15437 case OMPD_target_teams_distribute_parallel_for_simd
:
15438 case OMPD_target_teams_loop
:
15439 CaptureRegion
= OMPD_target
;
15441 case OMPD_teams_distribute_parallel_for
:
15442 case OMPD_teams_distribute_parallel_for_simd
:
15444 case OMPD_teams_distribute
:
15445 case OMPD_teams_distribute_simd
:
15446 case OMPD_teams_loop
:
15447 // Do not capture num_teams-clause expressions.
15449 case OMPD_distribute_parallel_for
:
15450 case OMPD_distribute_parallel_for_simd
:
15452 case OMPD_taskloop
:
15453 case OMPD_taskloop_simd
:
15454 case OMPD_master_taskloop
:
15455 case OMPD_masked_taskloop
:
15456 case OMPD_master_taskloop_simd
:
15457 case OMPD_masked_taskloop_simd
:
15458 case OMPD_parallel_master_taskloop
:
15459 case OMPD_parallel_masked_taskloop
:
15460 case OMPD_parallel_master_taskloop_simd
:
15461 case OMPD_parallel_masked_taskloop_simd
:
15462 case OMPD_target_data
:
15463 case OMPD_target_enter_data
:
15464 case OMPD_target_exit_data
:
15465 case OMPD_target_update
:
15467 case OMPD_parallel
:
15468 case OMPD_parallel_master
:
15469 case OMPD_parallel_masked
:
15470 case OMPD_parallel_sections
:
15471 case OMPD_parallel_for
:
15472 case OMPD_parallel_for_simd
:
15473 case OMPD_parallel_loop
:
15475 case OMPD_target_simd
:
15476 case OMPD_target_parallel
:
15477 case OMPD_target_parallel_for
:
15478 case OMPD_target_parallel_for_simd
:
15479 case OMPD_target_parallel_loop
:
15480 case OMPD_threadprivate
:
15481 case OMPD_allocate
:
15482 case OMPD_taskyield
:
15484 case OMPD_taskwait
:
15485 case OMPD_cancellation_point
:
15489 case OMPD_declare_reduction
:
15490 case OMPD_declare_mapper
:
15491 case OMPD_declare_simd
:
15492 case OMPD_declare_variant
:
15493 case OMPD_begin_declare_variant
:
15494 case OMPD_end_declare_variant
:
15495 case OMPD_declare_target
:
15496 case OMPD_end_declare_target
:
15502 case OMPD_for_simd
:
15503 case OMPD_sections
:
15508 case OMPD_critical
:
15509 case OMPD_taskgroup
:
15510 case OMPD_distribute
:
15513 case OMPD_distribute_simd
:
15514 case OMPD_requires
:
15515 case OMPD_metadirective
:
15516 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15519 llvm_unreachable("Unknown OpenMP directive");
15522 case OMPC_thread_limit
:
15524 case OMPD_target_teams
:
15525 case OMPD_target_teams_distribute
:
15526 case OMPD_target_teams_distribute_simd
:
15527 case OMPD_target_teams_distribute_parallel_for
:
15528 case OMPD_target_teams_distribute_parallel_for_simd
:
15529 case OMPD_target_teams_loop
:
15530 CaptureRegion
= OMPD_target
;
15532 case OMPD_teams_distribute_parallel_for
:
15533 case OMPD_teams_distribute_parallel_for_simd
:
15535 case OMPD_teams_distribute
:
15536 case OMPD_teams_distribute_simd
:
15537 case OMPD_teams_loop
:
15538 // Do not capture thread_limit-clause expressions.
15540 case OMPD_distribute_parallel_for
:
15541 case OMPD_distribute_parallel_for_simd
:
15543 case OMPD_taskloop
:
15544 case OMPD_taskloop_simd
:
15545 case OMPD_master_taskloop
:
15546 case OMPD_masked_taskloop
:
15547 case OMPD_master_taskloop_simd
:
15548 case OMPD_masked_taskloop_simd
:
15549 case OMPD_parallel_master_taskloop
:
15550 case OMPD_parallel_masked_taskloop
:
15551 case OMPD_parallel_master_taskloop_simd
:
15552 case OMPD_parallel_masked_taskloop_simd
:
15553 case OMPD_target_data
:
15554 case OMPD_target_enter_data
:
15555 case OMPD_target_exit_data
:
15556 case OMPD_target_update
:
15558 case OMPD_parallel
:
15559 case OMPD_parallel_master
:
15560 case OMPD_parallel_masked
:
15561 case OMPD_parallel_sections
:
15562 case OMPD_parallel_for
:
15563 case OMPD_parallel_for_simd
:
15564 case OMPD_parallel_loop
:
15566 case OMPD_target_simd
:
15567 case OMPD_target_parallel
:
15568 case OMPD_target_parallel_for
:
15569 case OMPD_target_parallel_for_simd
:
15570 case OMPD_target_parallel_loop
:
15571 case OMPD_threadprivate
:
15572 case OMPD_allocate
:
15573 case OMPD_taskyield
:
15575 case OMPD_taskwait
:
15576 case OMPD_cancellation_point
:
15580 case OMPD_declare_reduction
:
15581 case OMPD_declare_mapper
:
15582 case OMPD_declare_simd
:
15583 case OMPD_declare_variant
:
15584 case OMPD_begin_declare_variant
:
15585 case OMPD_end_declare_variant
:
15586 case OMPD_declare_target
:
15587 case OMPD_end_declare_target
:
15593 case OMPD_for_simd
:
15594 case OMPD_sections
:
15599 case OMPD_critical
:
15600 case OMPD_taskgroup
:
15601 case OMPD_distribute
:
15604 case OMPD_distribute_simd
:
15605 case OMPD_requires
:
15606 case OMPD_metadirective
:
15607 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
15610 llvm_unreachable("Unknown OpenMP directive");
15613 case OMPC_schedule
:
15615 case OMPD_parallel_for
:
15616 case OMPD_parallel_for_simd
:
15617 case OMPD_distribute_parallel_for
:
15618 case OMPD_distribute_parallel_for_simd
:
15619 case OMPD_teams_distribute_parallel_for
:
15620 case OMPD_teams_distribute_parallel_for_simd
:
15621 case OMPD_target_parallel_for
:
15622 case OMPD_target_parallel_for_simd
:
15623 case OMPD_target_teams_distribute_parallel_for
:
15624 case OMPD_target_teams_distribute_parallel_for_simd
:
15625 CaptureRegion
= OMPD_parallel
;
15628 case OMPD_for_simd
:
15629 // Do not capture schedule-clause expressions.
15632 case OMPD_taskloop
:
15633 case OMPD_taskloop_simd
:
15634 case OMPD_master_taskloop
:
15635 case OMPD_masked_taskloop
:
15636 case OMPD_master_taskloop_simd
:
15637 case OMPD_masked_taskloop_simd
:
15638 case OMPD_parallel_master_taskloop
:
15639 case OMPD_parallel_masked_taskloop
:
15640 case OMPD_parallel_master_taskloop_simd
:
15641 case OMPD_parallel_masked_taskloop_simd
:
15642 case OMPD_target_data
:
15643 case OMPD_target_enter_data
:
15644 case OMPD_target_exit_data
:
15645 case OMPD_target_update
:
15647 case OMPD_teams_distribute
:
15648 case OMPD_teams_distribute_simd
:
15649 case OMPD_target_teams_distribute
:
15650 case OMPD_target_teams_distribute_simd
:
15652 case OMPD_target_simd
:
15653 case OMPD_target_parallel
:
15655 case OMPD_parallel
:
15656 case OMPD_parallel_master
:
15657 case OMPD_parallel_masked
:
15658 case OMPD_parallel_sections
:
15659 case OMPD_threadprivate
:
15660 case OMPD_allocate
:
15661 case OMPD_taskyield
:
15663 case OMPD_taskwait
:
15664 case OMPD_cancellation_point
:
15668 case OMPD_declare_reduction
:
15669 case OMPD_declare_mapper
:
15670 case OMPD_declare_simd
:
15671 case OMPD_declare_variant
:
15672 case OMPD_begin_declare_variant
:
15673 case OMPD_end_declare_variant
:
15674 case OMPD_declare_target
:
15675 case OMPD_end_declare_target
:
15677 case OMPD_teams_loop
:
15678 case OMPD_target_teams_loop
:
15679 case OMPD_parallel_loop
:
15680 case OMPD_target_parallel_loop
:
15684 case OMPD_sections
:
15689 case OMPD_critical
:
15690 case OMPD_taskgroup
:
15691 case OMPD_distribute
:
15694 case OMPD_distribute_simd
:
15695 case OMPD_target_teams
:
15696 case OMPD_requires
:
15697 case OMPD_metadirective
:
15698 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
15701 llvm_unreachable("Unknown OpenMP directive");
15704 case OMPC_dist_schedule
:
15706 case OMPD_teams_distribute_parallel_for
:
15707 case OMPD_teams_distribute_parallel_for_simd
:
15708 case OMPD_teams_distribute
:
15709 case OMPD_teams_distribute_simd
:
15710 case OMPD_target_teams_distribute_parallel_for
:
15711 case OMPD_target_teams_distribute_parallel_for_simd
:
15712 case OMPD_target_teams_distribute
:
15713 case OMPD_target_teams_distribute_simd
:
15714 CaptureRegion
= OMPD_teams
;
15716 case OMPD_distribute_parallel_for
:
15717 case OMPD_distribute_parallel_for_simd
:
15718 case OMPD_distribute
:
15719 case OMPD_distribute_simd
:
15720 // Do not capture dist_schedule-clause expressions.
15722 case OMPD_parallel_for
:
15723 case OMPD_parallel_for_simd
:
15724 case OMPD_target_parallel_for_simd
:
15725 case OMPD_target_parallel_for
:
15727 case OMPD_taskloop
:
15728 case OMPD_taskloop_simd
:
15729 case OMPD_master_taskloop
:
15730 case OMPD_masked_taskloop
:
15731 case OMPD_master_taskloop_simd
:
15732 case OMPD_masked_taskloop_simd
:
15733 case OMPD_parallel_master_taskloop
:
15734 case OMPD_parallel_masked_taskloop
:
15735 case OMPD_parallel_master_taskloop_simd
:
15736 case OMPD_parallel_masked_taskloop_simd
:
15737 case OMPD_target_data
:
15738 case OMPD_target_enter_data
:
15739 case OMPD_target_exit_data
:
15740 case OMPD_target_update
:
15743 case OMPD_target_simd
:
15744 case OMPD_target_parallel
:
15746 case OMPD_parallel
:
15747 case OMPD_parallel_master
:
15748 case OMPD_parallel_masked
:
15749 case OMPD_parallel_sections
:
15750 case OMPD_threadprivate
:
15751 case OMPD_allocate
:
15752 case OMPD_taskyield
:
15754 case OMPD_taskwait
:
15755 case OMPD_cancellation_point
:
15759 case OMPD_declare_reduction
:
15760 case OMPD_declare_mapper
:
15761 case OMPD_declare_simd
:
15762 case OMPD_declare_variant
:
15763 case OMPD_begin_declare_variant
:
15764 case OMPD_end_declare_variant
:
15765 case OMPD_declare_target
:
15766 case OMPD_end_declare_target
:
15768 case OMPD_teams_loop
:
15769 case OMPD_target_teams_loop
:
15770 case OMPD_parallel_loop
:
15771 case OMPD_target_parallel_loop
:
15776 case OMPD_for_simd
:
15777 case OMPD_sections
:
15782 case OMPD_critical
:
15783 case OMPD_taskgroup
:
15786 case OMPD_target_teams
:
15787 case OMPD_requires
:
15788 case OMPD_metadirective
:
15789 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
15792 llvm_unreachable("Unknown OpenMP directive");
15797 case OMPD_target_update
:
15798 case OMPD_target_enter_data
:
15799 case OMPD_target_exit_data
:
15801 case OMPD_target_simd
:
15802 case OMPD_target_teams
:
15803 case OMPD_target_parallel
:
15804 case OMPD_target_teams_distribute
:
15805 case OMPD_target_teams_distribute_simd
:
15806 case OMPD_target_parallel_for
:
15807 case OMPD_target_parallel_for_simd
:
15808 case OMPD_target_parallel_loop
:
15809 case OMPD_target_teams_distribute_parallel_for
:
15810 case OMPD_target_teams_distribute_parallel_for_simd
:
15811 case OMPD_target_teams_loop
:
15812 case OMPD_dispatch
:
15813 CaptureRegion
= OMPD_task
;
15815 case OMPD_target_data
:
15817 // Do not capture device-clause expressions.
15819 case OMPD_teams_distribute_parallel_for
:
15820 case OMPD_teams_distribute_parallel_for_simd
:
15822 case OMPD_teams_distribute
:
15823 case OMPD_teams_distribute_simd
:
15824 case OMPD_distribute_parallel_for
:
15825 case OMPD_distribute_parallel_for_simd
:
15827 case OMPD_taskloop
:
15828 case OMPD_taskloop_simd
:
15829 case OMPD_master_taskloop
:
15830 case OMPD_masked_taskloop
:
15831 case OMPD_master_taskloop_simd
:
15832 case OMPD_masked_taskloop_simd
:
15833 case OMPD_parallel_master_taskloop
:
15834 case OMPD_parallel_masked_taskloop
:
15835 case OMPD_parallel_master_taskloop_simd
:
15836 case OMPD_parallel_masked_taskloop_simd
:
15838 case OMPD_parallel
:
15839 case OMPD_parallel_master
:
15840 case OMPD_parallel_masked
:
15841 case OMPD_parallel_sections
:
15842 case OMPD_parallel_for
:
15843 case OMPD_parallel_for_simd
:
15844 case OMPD_threadprivate
:
15845 case OMPD_allocate
:
15846 case OMPD_taskyield
:
15848 case OMPD_taskwait
:
15849 case OMPD_cancellation_point
:
15853 case OMPD_declare_reduction
:
15854 case OMPD_declare_mapper
:
15855 case OMPD_declare_simd
:
15856 case OMPD_declare_variant
:
15857 case OMPD_begin_declare_variant
:
15858 case OMPD_end_declare_variant
:
15859 case OMPD_declare_target
:
15860 case OMPD_end_declare_target
:
15862 case OMPD_teams_loop
:
15863 case OMPD_parallel_loop
:
15868 case OMPD_for_simd
:
15869 case OMPD_sections
:
15874 case OMPD_critical
:
15875 case OMPD_taskgroup
:
15876 case OMPD_distribute
:
15879 case OMPD_distribute_simd
:
15880 case OMPD_requires
:
15881 case OMPD_metadirective
:
15882 llvm_unreachable("Unexpected OpenMP directive with device-clause");
15885 llvm_unreachable("Unknown OpenMP directive");
15888 case OMPC_grainsize
:
15889 case OMPC_num_tasks
:
15891 case OMPC_priority
:
15894 case OMPD_taskloop
:
15895 case OMPD_taskloop_simd
:
15896 case OMPD_master_taskloop
:
15897 case OMPD_masked_taskloop
:
15898 case OMPD_master_taskloop_simd
:
15899 case OMPD_masked_taskloop_simd
:
15901 case OMPD_parallel_masked_taskloop
:
15902 case OMPD_parallel_masked_taskloop_simd
:
15903 case OMPD_parallel_master_taskloop
:
15904 case OMPD_parallel_master_taskloop_simd
:
15905 CaptureRegion
= OMPD_parallel
;
15907 case OMPD_target_update
:
15908 case OMPD_target_enter_data
:
15909 case OMPD_target_exit_data
:
15911 case OMPD_target_simd
:
15912 case OMPD_target_teams
:
15913 case OMPD_target_parallel
:
15914 case OMPD_target_teams_distribute
:
15915 case OMPD_target_teams_distribute_simd
:
15916 case OMPD_target_parallel_for
:
15917 case OMPD_target_parallel_for_simd
:
15918 case OMPD_target_teams_distribute_parallel_for
:
15919 case OMPD_target_teams_distribute_parallel_for_simd
:
15920 case OMPD_target_data
:
15921 case OMPD_teams_distribute_parallel_for
:
15922 case OMPD_teams_distribute_parallel_for_simd
:
15924 case OMPD_teams_distribute
:
15925 case OMPD_teams_distribute_simd
:
15926 case OMPD_distribute_parallel_for
:
15927 case OMPD_distribute_parallel_for_simd
:
15929 case OMPD_parallel
:
15930 case OMPD_parallel_master
:
15931 case OMPD_parallel_masked
:
15932 case OMPD_parallel_sections
:
15933 case OMPD_parallel_for
:
15934 case OMPD_parallel_for_simd
:
15935 case OMPD_threadprivate
:
15936 case OMPD_allocate
:
15937 case OMPD_taskyield
:
15939 case OMPD_taskwait
:
15940 case OMPD_cancellation_point
:
15944 case OMPD_declare_reduction
:
15945 case OMPD_declare_mapper
:
15946 case OMPD_declare_simd
:
15947 case OMPD_declare_variant
:
15948 case OMPD_begin_declare_variant
:
15949 case OMPD_end_declare_variant
:
15950 case OMPD_declare_target
:
15951 case OMPD_end_declare_target
:
15953 case OMPD_teams_loop
:
15954 case OMPD_target_teams_loop
:
15955 case OMPD_parallel_loop
:
15956 case OMPD_target_parallel_loop
:
15961 case OMPD_for_simd
:
15962 case OMPD_sections
:
15967 case OMPD_critical
:
15968 case OMPD_taskgroup
:
15969 case OMPD_distribute
:
15972 case OMPD_distribute_simd
:
15973 case OMPD_requires
:
15974 case OMPD_metadirective
:
15975 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
15978 llvm_unreachable("Unknown OpenMP directive");
15981 case OMPC_novariants
:
15982 case OMPC_nocontext
:
15984 case OMPD_dispatch
:
15985 CaptureRegion
= OMPD_task
;
15988 llvm_unreachable("Unexpected OpenMP directive");
15992 // Do not capture filter-clause expressions.
15995 if (DKind
== OMPD_metadirective
) {
15996 CaptureRegion
= OMPD_metadirective
;
15997 } else if (DKind
== OMPD_unknown
) {
15998 llvm_unreachable("Unknown OpenMP directive");
16000 llvm_unreachable("Unexpected OpenMP directive with when clause");
16003 case OMPC_firstprivate
:
16004 case OMPC_lastprivate
:
16005 case OMPC_reduction
:
16006 case OMPC_task_reduction
:
16007 case OMPC_in_reduction
:
16010 case OMPC_proc_bind
:
16014 case OMPC_allocator
:
16015 case OMPC_collapse
:
16020 case OMPC_copyprivate
:
16024 case OMPC_mergeable
:
16025 case OMPC_threadprivate
:
16026 case OMPC_allocate
:
16045 case OMPC_defaultmap
:
16050 case OMPC_use_device_ptr
:
16051 case OMPC_use_device_addr
:
16052 case OMPC_is_device_ptr
:
16053 case OMPC_unified_address
:
16054 case OMPC_unified_shared_memory
:
16055 case OMPC_reverse_offload
:
16056 case OMPC_dynamic_allocators
:
16057 case OMPC_atomic_default_mem_order
:
16058 case OMPC_device_type
:
16060 case OMPC_nontemporal
:
16064 case OMPC_inclusive
:
16065 case OMPC_exclusive
:
16066 case OMPC_uses_allocators
:
16067 case OMPC_affinity
:
16070 llvm_unreachable("Unexpected OpenMP clause.");
16072 return CaptureRegion
;
16075 OMPClause
*Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier
,
16076 Expr
*Condition
, SourceLocation StartLoc
,
16077 SourceLocation LParenLoc
,
16078 SourceLocation NameModifierLoc
,
16079 SourceLocation ColonLoc
,
16080 SourceLocation EndLoc
) {
16081 Expr
*ValExpr
= Condition
;
16082 Stmt
*HelperValStmt
= nullptr;
16083 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
16084 if (!Condition
->isValueDependent() && !Condition
->isTypeDependent() &&
16085 !Condition
->isInstantiationDependent() &&
16086 !Condition
->containsUnexpandedParameterPack()) {
16087 ExprResult Val
= CheckBooleanCondition(StartLoc
, Condition
);
16088 if (Val
.isInvalid())
16091 ValExpr
= Val
.get();
16093 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
16094 CaptureRegion
= getOpenMPCaptureRegionForClause(
16095 DKind
, OMPC_if
, LangOpts
.OpenMP
, NameModifier
);
16096 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
16097 ValExpr
= MakeFullExpr(ValExpr
).get();
16098 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
16099 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
16100 HelperValStmt
= buildPreInits(Context
, Captures
);
16104 return new (Context
)
16105 OMPIfClause(NameModifier
, ValExpr
, HelperValStmt
, CaptureRegion
, StartLoc
,
16106 LParenLoc
, NameModifierLoc
, ColonLoc
, EndLoc
);
16109 OMPClause
*Sema::ActOnOpenMPFinalClause(Expr
*Condition
,
16110 SourceLocation StartLoc
,
16111 SourceLocation LParenLoc
,
16112 SourceLocation EndLoc
) {
16113 Expr
*ValExpr
= Condition
;
16114 Stmt
*HelperValStmt
= nullptr;
16115 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
16116 if (!Condition
->isValueDependent() && !Condition
->isTypeDependent() &&
16117 !Condition
->isInstantiationDependent() &&
16118 !Condition
->containsUnexpandedParameterPack()) {
16119 ExprResult Val
= CheckBooleanCondition(StartLoc
, Condition
);
16120 if (Val
.isInvalid())
16123 ValExpr
= MakeFullExpr(Val
.get()).get();
16125 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
16127 getOpenMPCaptureRegionForClause(DKind
, OMPC_final
, LangOpts
.OpenMP
);
16128 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
16129 ValExpr
= MakeFullExpr(ValExpr
).get();
16130 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
16131 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
16132 HelperValStmt
= buildPreInits(Context
, Captures
);
16136 return new (Context
) OMPFinalClause(ValExpr
, HelperValStmt
, CaptureRegion
,
16137 StartLoc
, LParenLoc
, EndLoc
);
16140 ExprResult
Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc
,
16143 return ExprError();
16145 class IntConvertDiagnoser
: public ICEConvertDiagnoser
{
16147 IntConvertDiagnoser()
16148 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16149 SemaDiagnosticBuilder
diagnoseNotInt(Sema
&S
, SourceLocation Loc
,
16150 QualType T
) override
{
16151 return S
.Diag(Loc
, diag::err_omp_not_integral
) << T
;
16153 SemaDiagnosticBuilder
diagnoseIncomplete(Sema
&S
, SourceLocation Loc
,
16154 QualType T
) override
{
16155 return S
.Diag(Loc
, diag::err_omp_incomplete_type
) << T
;
16157 SemaDiagnosticBuilder
diagnoseExplicitConv(Sema
&S
, SourceLocation Loc
,
16159 QualType ConvTy
) override
{
16160 return S
.Diag(Loc
, diag::err_omp_explicit_conversion
) << T
<< ConvTy
;
16162 SemaDiagnosticBuilder
noteExplicitConv(Sema
&S
, CXXConversionDecl
*Conv
,
16163 QualType ConvTy
) override
{
16164 return S
.Diag(Conv
->getLocation(), diag::note_omp_conversion_here
)
16165 << ConvTy
->isEnumeralType() << ConvTy
;
16167 SemaDiagnosticBuilder
diagnoseAmbiguous(Sema
&S
, SourceLocation Loc
,
16168 QualType T
) override
{
16169 return S
.Diag(Loc
, diag::err_omp_ambiguous_conversion
) << T
;
16171 SemaDiagnosticBuilder
noteAmbiguous(Sema
&S
, CXXConversionDecl
*Conv
,
16172 QualType ConvTy
) override
{
16173 return S
.Diag(Conv
->getLocation(), diag::note_omp_conversion_here
)
16174 << ConvTy
->isEnumeralType() << ConvTy
;
16176 SemaDiagnosticBuilder
diagnoseConversion(Sema
&, SourceLocation
, QualType
,
16177 QualType
) override
{
16178 llvm_unreachable("conversion functions are permitted");
16180 } ConvertDiagnoser
;
16181 return PerformContextualImplicitConversion(Loc
, Op
, ConvertDiagnoser
);
16185 isNonNegativeIntegerValue(Expr
*&ValExpr
, Sema
&SemaRef
, OpenMPClauseKind CKind
,
16186 bool StrictlyPositive
, bool BuildCapture
= false,
16187 OpenMPDirectiveKind DKind
= OMPD_unknown
,
16188 OpenMPDirectiveKind
*CaptureRegion
= nullptr,
16189 Stmt
**HelperValStmt
= nullptr) {
16190 if (!ValExpr
->isTypeDependent() && !ValExpr
->isValueDependent() &&
16191 !ValExpr
->isInstantiationDependent()) {
16192 SourceLocation Loc
= ValExpr
->getExprLoc();
16194 SemaRef
.PerformOpenMPImplicitIntegerConversion(Loc
, ValExpr
);
16195 if (Value
.isInvalid())
16198 ValExpr
= Value
.get();
16199 // The expression must evaluate to a non-negative integer value.
16200 if (Optional
<llvm::APSInt
> Result
=
16201 ValExpr
->getIntegerConstantExpr(SemaRef
.Context
)) {
16202 if (Result
->isSigned() &&
16203 !((!StrictlyPositive
&& Result
->isNonNegative()) ||
16204 (StrictlyPositive
&& Result
->isStrictlyPositive()))) {
16205 SemaRef
.Diag(Loc
, diag::err_omp_negative_expression_in_clause
)
16206 << getOpenMPClauseName(CKind
) << (StrictlyPositive
? 1 : 0)
16207 << ValExpr
->getSourceRange();
16214 getOpenMPCaptureRegionForClause(DKind
, CKind
, SemaRef
.LangOpts
.OpenMP
);
16215 if (*CaptureRegion
!= OMPD_unknown
&&
16216 !SemaRef
.CurContext
->isDependentContext()) {
16217 ValExpr
= SemaRef
.MakeFullExpr(ValExpr
).get();
16218 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
16219 ValExpr
= tryBuildCapture(SemaRef
, ValExpr
, Captures
).get();
16220 *HelperValStmt
= buildPreInits(SemaRef
.Context
, Captures
);
16226 OMPClause
*Sema::ActOnOpenMPNumThreadsClause(Expr
*NumThreads
,
16227 SourceLocation StartLoc
,
16228 SourceLocation LParenLoc
,
16229 SourceLocation EndLoc
) {
16230 Expr
*ValExpr
= NumThreads
;
16231 Stmt
*HelperValStmt
= nullptr;
16233 // OpenMP [2.5, Restrictions]
16234 // The num_threads expression must evaluate to a positive integer value.
16235 if (!isNonNegativeIntegerValue(ValExpr
, *this, OMPC_num_threads
,
16236 /*StrictlyPositive=*/true))
16239 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
16240 OpenMPDirectiveKind CaptureRegion
=
16241 getOpenMPCaptureRegionForClause(DKind
, OMPC_num_threads
, LangOpts
.OpenMP
);
16242 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
16243 ValExpr
= MakeFullExpr(ValExpr
).get();
16244 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
16245 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
16246 HelperValStmt
= buildPreInits(Context
, Captures
);
16249 return new (Context
) OMPNumThreadsClause(
16250 ValExpr
, HelperValStmt
, CaptureRegion
, StartLoc
, LParenLoc
, EndLoc
);
16253 ExprResult
Sema::VerifyPositiveIntegerConstantInClause(Expr
*E
,
16254 OpenMPClauseKind CKind
,
16255 bool StrictlyPositive
,
16256 bool SuppressExprDiags
) {
16258 return ExprError();
16259 if (E
->isValueDependent() || E
->isTypeDependent() ||
16260 E
->isInstantiationDependent() || E
->containsUnexpandedParameterPack())
16263 llvm::APSInt Result
;
16265 if (SuppressExprDiags
) {
16266 // Use a custom diagnoser that suppresses 'note' diagnostics about the
16268 struct SuppressedDiagnoser
: public Sema::VerifyICEDiagnoser
{
16269 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16270 Sema::SemaDiagnosticBuilder
diagnoseNotICE(Sema
&S
,
16271 SourceLocation Loc
) override
{
16272 llvm_unreachable("Diagnostic suppressed");
16275 ICE
= VerifyIntegerConstantExpression(E
, &Result
, Diagnoser
, AllowFold
);
16277 ICE
= VerifyIntegerConstantExpression(E
, &Result
, /*FIXME*/ AllowFold
);
16279 if (ICE
.isInvalid())
16280 return ExprError();
16282 if ((StrictlyPositive
&& !Result
.isStrictlyPositive()) ||
16283 (!StrictlyPositive
&& !Result
.isNonNegative())) {
16284 Diag(E
->getExprLoc(), diag::err_omp_negative_expression_in_clause
)
16285 << getOpenMPClauseName(CKind
) << (StrictlyPositive
? 1 : 0)
16286 << E
->getSourceRange();
16287 return ExprError();
16289 if ((CKind
== OMPC_aligned
|| CKind
== OMPC_align
) && !Result
.isPowerOf2()) {
16290 Diag(E
->getExprLoc(), diag::warn_omp_alignment_not_power_of_two
)
16291 << E
->getSourceRange();
16292 return ExprError();
16294 if (CKind
== OMPC_collapse
&& DSAStack
->getAssociatedLoops() == 1)
16295 DSAStack
->setAssociatedLoops(Result
.getExtValue());
16296 else if (CKind
== OMPC_ordered
)
16297 DSAStack
->setAssociatedLoops(Result
.getExtValue());
16301 OMPClause
*Sema::ActOnOpenMPSafelenClause(Expr
*Len
, SourceLocation StartLoc
,
16302 SourceLocation LParenLoc
,
16303 SourceLocation EndLoc
) {
16304 // OpenMP [2.8.1, simd construct, Description]
16305 // The parameter of the safelen clause must be a constant
16306 // positive integer expression.
16307 ExprResult Safelen
= VerifyPositiveIntegerConstantInClause(Len
, OMPC_safelen
);
16308 if (Safelen
.isInvalid())
16310 return new (Context
)
16311 OMPSafelenClause(Safelen
.get(), StartLoc
, LParenLoc
, EndLoc
);
16314 OMPClause
*Sema::ActOnOpenMPSimdlenClause(Expr
*Len
, SourceLocation StartLoc
,
16315 SourceLocation LParenLoc
,
16316 SourceLocation EndLoc
) {
16317 // OpenMP [2.8.1, simd construct, Description]
16318 // The parameter of the simdlen clause must be a constant
16319 // positive integer expression.
16320 ExprResult Simdlen
= VerifyPositiveIntegerConstantInClause(Len
, OMPC_simdlen
);
16321 if (Simdlen
.isInvalid())
16323 return new (Context
)
16324 OMPSimdlenClause(Simdlen
.get(), StartLoc
, LParenLoc
, EndLoc
);
16327 /// Tries to find omp_allocator_handle_t type.
16328 static bool findOMPAllocatorHandleT(Sema
&S
, SourceLocation Loc
,
16329 DSAStackTy
*Stack
) {
16330 QualType OMPAllocatorHandleT
= Stack
->getOMPAllocatorHandleT();
16331 if (!OMPAllocatorHandleT
.isNull())
16333 // Build the predefined allocator expressions.
16334 bool ErrorFound
= false;
16335 for (int I
= 0; I
< OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
; ++I
) {
16336 auto AllocatorKind
= static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I
);
16337 StringRef Allocator
=
16338 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind
);
16339 DeclarationName AllocatorName
= &S
.getASTContext().Idents
.get(Allocator
);
16340 auto *VD
= dyn_cast_or_null
<ValueDecl
>(
16341 S
.LookupSingleName(S
.TUScope
, AllocatorName
, Loc
, Sema::LookupAnyName
));
16346 QualType AllocatorType
=
16347 VD
->getType().getNonLValueExprType(S
.getASTContext());
16348 ExprResult Res
= S
.BuildDeclRefExpr(VD
, AllocatorType
, VK_LValue
, Loc
);
16349 if (!Res
.isUsable()) {
16353 if (OMPAllocatorHandleT
.isNull())
16354 OMPAllocatorHandleT
= AllocatorType
;
16355 if (!S
.getASTContext().hasSameType(OMPAllocatorHandleT
, AllocatorType
)) {
16359 Stack
->setAllocator(AllocatorKind
, Res
.get());
16362 S
.Diag(Loc
, diag::err_omp_implied_type_not_found
)
16363 << "omp_allocator_handle_t";
16366 OMPAllocatorHandleT
.addConst();
16367 Stack
->setOMPAllocatorHandleT(OMPAllocatorHandleT
);
16371 OMPClause
*Sema::ActOnOpenMPAllocatorClause(Expr
*A
, SourceLocation StartLoc
,
16372 SourceLocation LParenLoc
,
16373 SourceLocation EndLoc
) {
16374 // OpenMP [2.11.3, allocate Directive, Description]
16375 // allocator is an expression of omp_allocator_handle_t type.
16376 if (!findOMPAllocatorHandleT(*this, A
->getExprLoc(), DSAStack
))
16379 ExprResult Allocator
= DefaultLvalueConversion(A
);
16380 if (Allocator
.isInvalid())
16382 Allocator
= PerformImplicitConversion(Allocator
.get(),
16383 DSAStack
->getOMPAllocatorHandleT(),
16384 Sema::AA_Initializing
,
16385 /*AllowExplicit=*/true);
16386 if (Allocator
.isInvalid())
16388 return new (Context
)
16389 OMPAllocatorClause(Allocator
.get(), StartLoc
, LParenLoc
, EndLoc
);
16392 OMPClause
*Sema::ActOnOpenMPCollapseClause(Expr
*NumForLoops
,
16393 SourceLocation StartLoc
,
16394 SourceLocation LParenLoc
,
16395 SourceLocation EndLoc
) {
16396 // OpenMP [2.7.1, loop construct, Description]
16397 // OpenMP [2.8.1, simd construct, Description]
16398 // OpenMP [2.9.6, distribute construct, Description]
16399 // The parameter of the collapse clause must be a constant
16400 // positive integer expression.
16401 ExprResult NumForLoopsResult
=
16402 VerifyPositiveIntegerConstantInClause(NumForLoops
, OMPC_collapse
);
16403 if (NumForLoopsResult
.isInvalid())
16405 return new (Context
)
16406 OMPCollapseClause(NumForLoopsResult
.get(), StartLoc
, LParenLoc
, EndLoc
);
16409 OMPClause
*Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc
,
16410 SourceLocation EndLoc
,
16411 SourceLocation LParenLoc
,
16412 Expr
*NumForLoops
) {
16413 // OpenMP [2.7.1, loop construct, Description]
16414 // OpenMP [2.8.1, simd construct, Description]
16415 // OpenMP [2.9.6, distribute construct, Description]
16416 // The parameter of the ordered clause must be a constant
16417 // positive integer expression if any.
16418 if (NumForLoops
&& LParenLoc
.isValid()) {
16419 ExprResult NumForLoopsResult
=
16420 VerifyPositiveIntegerConstantInClause(NumForLoops
, OMPC_ordered
);
16421 if (NumForLoopsResult
.isInvalid())
16423 NumForLoops
= NumForLoopsResult
.get();
16425 NumForLoops
= nullptr;
16427 auto *Clause
= OMPOrderedClause::Create(
16428 Context
, NumForLoops
, NumForLoops
? DSAStack
->getAssociatedLoops() : 0,
16429 StartLoc
, LParenLoc
, EndLoc
);
16430 DSAStack
->setOrderedRegion(/*IsOrdered=*/true, NumForLoops
, Clause
);
16434 OMPClause
*Sema::ActOnOpenMPSimpleClause(
16435 OpenMPClauseKind Kind
, unsigned Argument
, SourceLocation ArgumentLoc
,
16436 SourceLocation StartLoc
, SourceLocation LParenLoc
, SourceLocation EndLoc
) {
16437 OMPClause
*Res
= nullptr;
16440 Res
= ActOnOpenMPDefaultClause(static_cast<DefaultKind
>(Argument
),
16441 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16443 case OMPC_proc_bind
:
16444 Res
= ActOnOpenMPProcBindClause(static_cast<ProcBindKind
>(Argument
),
16445 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16447 case OMPC_atomic_default_mem_order
:
16448 Res
= ActOnOpenMPAtomicDefaultMemOrderClause(
16449 static_cast<OpenMPAtomicDefaultMemOrderClauseKind
>(Argument
),
16450 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16453 Res
= ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind
>(Argument
),
16454 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16457 Res
= ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind
>(Argument
),
16458 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16461 Res
= ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind
>(Argument
),
16462 ArgumentLoc
, StartLoc
, LParenLoc
, EndLoc
);
16466 case OMPC_num_threads
:
16470 case OMPC_allocator
:
16471 case OMPC_collapse
:
16472 case OMPC_schedule
:
16474 case OMPC_firstprivate
:
16475 case OMPC_lastprivate
:
16477 case OMPC_reduction
:
16478 case OMPC_task_reduction
:
16479 case OMPC_in_reduction
:
16483 case OMPC_copyprivate
:
16487 case OMPC_mergeable
:
16488 case OMPC_threadprivate
:
16489 case OMPC_allocate
:
16506 case OMPC_num_teams
:
16507 case OMPC_thread_limit
:
16508 case OMPC_priority
:
16509 case OMPC_grainsize
:
16511 case OMPC_num_tasks
:
16513 case OMPC_dist_schedule
:
16514 case OMPC_defaultmap
:
16519 case OMPC_use_device_ptr
:
16520 case OMPC_use_device_addr
:
16521 case OMPC_is_device_ptr
:
16522 case OMPC_has_device_addr
:
16523 case OMPC_unified_address
:
16524 case OMPC_unified_shared_memory
:
16525 case OMPC_reverse_offload
:
16526 case OMPC_dynamic_allocators
:
16527 case OMPC_device_type
:
16529 case OMPC_nontemporal
:
16531 case OMPC_novariants
:
16532 case OMPC_nocontext
:
16534 case OMPC_inclusive
:
16535 case OMPC_exclusive
:
16536 case OMPC_uses_allocators
:
16537 case OMPC_affinity
:
16540 llvm_unreachable("Clause is not allowed.");
16546 getListOfPossibleValues(OpenMPClauseKind K
, unsigned First
, unsigned Last
,
16547 ArrayRef
<unsigned> Exclude
= llvm::None
) {
16548 SmallString
<256> Buffer
;
16549 llvm::raw_svector_ostream
Out(Buffer
);
16550 unsigned Skipped
= Exclude
.size();
16551 auto S
= Exclude
.begin(), E
= Exclude
.end();
16552 for (unsigned I
= First
; I
< Last
; ++I
) {
16553 if (std::find(S
, E
, I
) != E
) {
16557 Out
<< "'" << getOpenMPSimpleClauseTypeName(K
, I
) << "'";
16558 if (I
+ Skipped
+ 2 == Last
)
16560 else if (I
+ Skipped
+ 1 != Last
)
16563 return std::string(Out
.str());
16566 OMPClause
*Sema::ActOnOpenMPDefaultClause(DefaultKind Kind
,
16567 SourceLocation KindKwLoc
,
16568 SourceLocation StartLoc
,
16569 SourceLocation LParenLoc
,
16570 SourceLocation EndLoc
) {
16571 if (Kind
== OMP_DEFAULT_unknown
) {
16572 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16573 << getListOfPossibleValues(OMPC_default
, /*First=*/0,
16574 /*Last=*/unsigned(OMP_DEFAULT_unknown
))
16575 << getOpenMPClauseName(OMPC_default
);
16580 case OMP_DEFAULT_none
:
16581 DSAStack
->setDefaultDSANone(KindKwLoc
);
16583 case OMP_DEFAULT_shared
:
16584 DSAStack
->setDefaultDSAShared(KindKwLoc
);
16586 case OMP_DEFAULT_firstprivate
:
16587 DSAStack
->setDefaultDSAFirstPrivate(KindKwLoc
);
16589 case OMP_DEFAULT_private
:
16590 DSAStack
->setDefaultDSAPrivate(KindKwLoc
);
16593 llvm_unreachable("DSA unexpected in OpenMP default clause");
16596 return new (Context
)
16597 OMPDefaultClause(Kind
, KindKwLoc
, StartLoc
, LParenLoc
, EndLoc
);
16600 OMPClause
*Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind
,
16601 SourceLocation KindKwLoc
,
16602 SourceLocation StartLoc
,
16603 SourceLocation LParenLoc
,
16604 SourceLocation EndLoc
) {
16605 if (Kind
== OMP_PROC_BIND_unknown
) {
16606 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16607 << getListOfPossibleValues(OMPC_proc_bind
,
16608 /*First=*/unsigned(OMP_PROC_BIND_master
),
16610 unsigned(LangOpts
.OpenMP
> 50
16611 ? OMP_PROC_BIND_primary
16612 : OMP_PROC_BIND_spread
) +
16614 << getOpenMPClauseName(OMPC_proc_bind
);
16617 if (Kind
== OMP_PROC_BIND_primary
&& LangOpts
.OpenMP
< 51)
16618 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16619 << getListOfPossibleValues(OMPC_proc_bind
,
16620 /*First=*/unsigned(OMP_PROC_BIND_master
),
16622 unsigned(OMP_PROC_BIND_spread
) + 1)
16623 << getOpenMPClauseName(OMPC_proc_bind
);
16624 return new (Context
)
16625 OMPProcBindClause(Kind
, KindKwLoc
, StartLoc
, LParenLoc
, EndLoc
);
16628 OMPClause
*Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
16629 OpenMPAtomicDefaultMemOrderClauseKind Kind
, SourceLocation KindKwLoc
,
16630 SourceLocation StartLoc
, SourceLocation LParenLoc
, SourceLocation EndLoc
) {
16631 if (Kind
== OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
) {
16632 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16633 << getListOfPossibleValues(
16634 OMPC_atomic_default_mem_order
, /*First=*/0,
16635 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
)
16636 << getOpenMPClauseName(OMPC_atomic_default_mem_order
);
16639 return new (Context
) OMPAtomicDefaultMemOrderClause(Kind
, KindKwLoc
, StartLoc
,
16640 LParenLoc
, EndLoc
);
16643 OMPClause
*Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind
,
16644 SourceLocation KindKwLoc
,
16645 SourceLocation StartLoc
,
16646 SourceLocation LParenLoc
,
16647 SourceLocation EndLoc
) {
16648 if (Kind
== OMPC_ORDER_unknown
) {
16649 static_assert(OMPC_ORDER_unknown
> 0,
16650 "OMPC_ORDER_unknown not greater than 0");
16651 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16652 << getListOfPossibleValues(OMPC_order
, /*First=*/0,
16653 /*Last=*/OMPC_ORDER_unknown
)
16654 << getOpenMPClauseName(OMPC_order
);
16657 return new (Context
)
16658 OMPOrderClause(Kind
, KindKwLoc
, StartLoc
, LParenLoc
, EndLoc
);
16661 OMPClause
*Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind
,
16662 SourceLocation KindKwLoc
,
16663 SourceLocation StartLoc
,
16664 SourceLocation LParenLoc
,
16665 SourceLocation EndLoc
) {
16666 if (Kind
== OMPC_DEPEND_unknown
|| Kind
== OMPC_DEPEND_source
||
16667 Kind
== OMPC_DEPEND_sink
|| Kind
== OMPC_DEPEND_depobj
) {
16668 SmallVector
<unsigned> Except
= {
16669 OMPC_DEPEND_source
, OMPC_DEPEND_sink
, OMPC_DEPEND_depobj
,
16670 OMPC_DEPEND_outallmemory
, OMPC_DEPEND_inoutallmemory
};
16671 if (LangOpts
.OpenMP
< 51)
16672 Except
.push_back(OMPC_DEPEND_inoutset
);
16673 Diag(KindKwLoc
, diag::err_omp_unexpected_clause_value
)
16674 << getListOfPossibleValues(OMPC_depend
, /*First=*/0,
16675 /*Last=*/OMPC_DEPEND_unknown
, Except
)
16676 << getOpenMPClauseName(OMPC_update
);
16679 return OMPUpdateClause::Create(Context
, StartLoc
, LParenLoc
, KindKwLoc
, Kind
,
16683 OMPClause
*Sema::ActOnOpenMPSizesClause(ArrayRef
<Expr
*> SizeExprs
,
16684 SourceLocation StartLoc
,
16685 SourceLocation LParenLoc
,
16686 SourceLocation EndLoc
) {
16687 for (Expr
*SizeExpr
: SizeExprs
) {
16688 ExprResult NumForLoopsResult
= VerifyPositiveIntegerConstantInClause(
16689 SizeExpr
, OMPC_sizes
, /*StrictlyPositive=*/true);
16690 if (!NumForLoopsResult
.isUsable())
16694 DSAStack
->setAssociatedLoops(SizeExprs
.size());
16695 return OMPSizesClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
16699 OMPClause
*Sema::ActOnOpenMPFullClause(SourceLocation StartLoc
,
16700 SourceLocation EndLoc
) {
16701 return OMPFullClause::Create(Context
, StartLoc
, EndLoc
);
16704 OMPClause
*Sema::ActOnOpenMPPartialClause(Expr
*FactorExpr
,
16705 SourceLocation StartLoc
,
16706 SourceLocation LParenLoc
,
16707 SourceLocation EndLoc
) {
16709 // If an argument is specified, it must be a constant (or an unevaluated
16710 // template expression).
16711 ExprResult FactorResult
= VerifyPositiveIntegerConstantInClause(
16712 FactorExpr
, OMPC_partial
, /*StrictlyPositive=*/true);
16713 if (FactorResult
.isInvalid())
16715 FactorExpr
= FactorResult
.get();
16718 return OMPPartialClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
16722 OMPClause
*Sema::ActOnOpenMPAlignClause(Expr
*A
, SourceLocation StartLoc
,
16723 SourceLocation LParenLoc
,
16724 SourceLocation EndLoc
) {
16725 ExprResult AlignVal
;
16726 AlignVal
= VerifyPositiveIntegerConstantInClause(A
, OMPC_align
);
16727 if (AlignVal
.isInvalid())
16729 return OMPAlignClause::Create(Context
, AlignVal
.get(), StartLoc
, LParenLoc
,
16733 OMPClause
*Sema::ActOnOpenMPSingleExprWithArgClause(
16734 OpenMPClauseKind Kind
, ArrayRef
<unsigned> Argument
, Expr
*Expr
,
16735 SourceLocation StartLoc
, SourceLocation LParenLoc
,
16736 ArrayRef
<SourceLocation
> ArgumentLoc
, SourceLocation DelimLoc
,
16737 SourceLocation EndLoc
) {
16738 OMPClause
*Res
= nullptr;
16740 case OMPC_schedule
:
16741 enum { Modifier1
, Modifier2
, ScheduleKind
, NumberOfElements
};
16742 assert(Argument
.size() == NumberOfElements
&&
16743 ArgumentLoc
.size() == NumberOfElements
);
16744 Res
= ActOnOpenMPScheduleClause(
16745 static_cast<OpenMPScheduleClauseModifier
>(Argument
[Modifier1
]),
16746 static_cast<OpenMPScheduleClauseModifier
>(Argument
[Modifier2
]),
16747 static_cast<OpenMPScheduleClauseKind
>(Argument
[ScheduleKind
]), Expr
,
16748 StartLoc
, LParenLoc
, ArgumentLoc
[Modifier1
], ArgumentLoc
[Modifier2
],
16749 ArgumentLoc
[ScheduleKind
], DelimLoc
, EndLoc
);
16752 assert(Argument
.size() == 1 && ArgumentLoc
.size() == 1);
16753 Res
= ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind
>(Argument
.back()),
16754 Expr
, StartLoc
, LParenLoc
, ArgumentLoc
.back(),
16757 case OMPC_dist_schedule
:
16758 Res
= ActOnOpenMPDistScheduleClause(
16759 static_cast<OpenMPDistScheduleClauseKind
>(Argument
.back()), Expr
,
16760 StartLoc
, LParenLoc
, ArgumentLoc
.back(), DelimLoc
, EndLoc
);
16762 case OMPC_defaultmap
:
16763 enum { Modifier
, DefaultmapKind
};
16764 Res
= ActOnOpenMPDefaultmapClause(
16765 static_cast<OpenMPDefaultmapClauseModifier
>(Argument
[Modifier
]),
16766 static_cast<OpenMPDefaultmapClauseKind
>(Argument
[DefaultmapKind
]),
16767 StartLoc
, LParenLoc
, ArgumentLoc
[Modifier
], ArgumentLoc
[DefaultmapKind
],
16771 assert(Argument
.size() == 1 && ArgumentLoc
.size() == 1);
16772 Res
= ActOnOpenMPDeviceClause(
16773 static_cast<OpenMPDeviceClauseModifier
>(Argument
.back()), Expr
,
16774 StartLoc
, LParenLoc
, ArgumentLoc
.back(), EndLoc
);
16777 case OMPC_num_threads
:
16781 case OMPC_allocator
:
16782 case OMPC_collapse
:
16784 case OMPC_proc_bind
:
16786 case OMPC_firstprivate
:
16787 case OMPC_lastprivate
:
16789 case OMPC_reduction
:
16790 case OMPC_task_reduction
:
16791 case OMPC_in_reduction
:
16795 case OMPC_copyprivate
:
16799 case OMPC_mergeable
:
16800 case OMPC_threadprivate
:
16801 case OMPC_allocate
:
16818 case OMPC_num_teams
:
16819 case OMPC_thread_limit
:
16820 case OMPC_priority
:
16821 case OMPC_grainsize
:
16823 case OMPC_num_tasks
:
16829 case OMPC_use_device_ptr
:
16830 case OMPC_use_device_addr
:
16831 case OMPC_is_device_ptr
:
16832 case OMPC_has_device_addr
:
16833 case OMPC_unified_address
:
16834 case OMPC_unified_shared_memory
:
16835 case OMPC_reverse_offload
:
16836 case OMPC_dynamic_allocators
:
16837 case OMPC_atomic_default_mem_order
:
16838 case OMPC_device_type
:
16840 case OMPC_nontemporal
:
16843 case OMPC_novariants
:
16844 case OMPC_nocontext
:
16846 case OMPC_inclusive
:
16847 case OMPC_exclusive
:
16848 case OMPC_uses_allocators
:
16849 case OMPC_affinity
:
16853 llvm_unreachable("Clause is not allowed.");
16858 static bool checkScheduleModifiers(Sema
&S
, OpenMPScheduleClauseModifier M1
,
16859 OpenMPScheduleClauseModifier M2
,
16860 SourceLocation M1Loc
, SourceLocation M2Loc
) {
16861 if (M1
== OMPC_SCHEDULE_MODIFIER_unknown
&& M1Loc
.isValid()) {
16862 SmallVector
<unsigned, 2> Excluded
;
16863 if (M2
!= OMPC_SCHEDULE_MODIFIER_unknown
)
16864 Excluded
.push_back(M2
);
16865 if (M2
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
)
16866 Excluded
.push_back(OMPC_SCHEDULE_MODIFIER_monotonic
);
16867 if (M2
== OMPC_SCHEDULE_MODIFIER_monotonic
)
16868 Excluded
.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic
);
16869 S
.Diag(M1Loc
, diag::err_omp_unexpected_clause_value
)
16870 << getListOfPossibleValues(OMPC_schedule
,
16871 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown
+ 1,
16872 /*Last=*/OMPC_SCHEDULE_MODIFIER_last
,
16874 << getOpenMPClauseName(OMPC_schedule
);
16880 OMPClause
*Sema::ActOnOpenMPScheduleClause(
16881 OpenMPScheduleClauseModifier M1
, OpenMPScheduleClauseModifier M2
,
16882 OpenMPScheduleClauseKind Kind
, Expr
*ChunkSize
, SourceLocation StartLoc
,
16883 SourceLocation LParenLoc
, SourceLocation M1Loc
, SourceLocation M2Loc
,
16884 SourceLocation KindLoc
, SourceLocation CommaLoc
, SourceLocation EndLoc
) {
16885 if (checkScheduleModifiers(*this, M1
, M2
, M1Loc
, M2Loc
) ||
16886 checkScheduleModifiers(*this, M2
, M1
, M2Loc
, M1Loc
))
16888 // OpenMP, 2.7.1, Loop Construct, Restrictions
16889 // Either the monotonic modifier or the nonmonotonic modifier can be specified
16891 if ((M1
== M2
&& M1
!= OMPC_SCHEDULE_MODIFIER_unknown
) ||
16892 (M1
== OMPC_SCHEDULE_MODIFIER_monotonic
&&
16893 M2
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
) ||
16894 (M1
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
&&
16895 M2
== OMPC_SCHEDULE_MODIFIER_monotonic
)) {
16896 Diag(M2Loc
, diag::err_omp_unexpected_schedule_modifier
)
16897 << getOpenMPSimpleClauseTypeName(OMPC_schedule
, M2
)
16898 << getOpenMPSimpleClauseTypeName(OMPC_schedule
, M1
);
16901 if (Kind
== OMPC_SCHEDULE_unknown
) {
16902 std::string Values
;
16903 if (M1Loc
.isInvalid() && M2Loc
.isInvalid()) {
16904 unsigned Exclude
[] = {OMPC_SCHEDULE_unknown
};
16905 Values
= getListOfPossibleValues(OMPC_schedule
, /*First=*/0,
16906 /*Last=*/OMPC_SCHEDULE_MODIFIER_last
,
16909 Values
= getListOfPossibleValues(OMPC_schedule
, /*First=*/0,
16910 /*Last=*/OMPC_SCHEDULE_unknown
);
16912 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
16913 << Values
<< getOpenMPClauseName(OMPC_schedule
);
16916 // OpenMP, 2.7.1, Loop Construct, Restrictions
16917 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16918 // schedule(guided).
16919 // OpenMP 5.0 does not have this restriction.
16920 if (LangOpts
.OpenMP
< 50 &&
16921 (M1
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
||
16922 M2
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
) &&
16923 Kind
!= OMPC_SCHEDULE_dynamic
&& Kind
!= OMPC_SCHEDULE_guided
) {
16924 Diag(M1
== OMPC_SCHEDULE_MODIFIER_nonmonotonic
? M1Loc
: M2Loc
,
16925 diag::err_omp_schedule_nonmonotonic_static
);
16928 Expr
*ValExpr
= ChunkSize
;
16929 Stmt
*HelperValStmt
= nullptr;
16931 if (!ChunkSize
->isValueDependent() && !ChunkSize
->isTypeDependent() &&
16932 !ChunkSize
->isInstantiationDependent() &&
16933 !ChunkSize
->containsUnexpandedParameterPack()) {
16934 SourceLocation ChunkSizeLoc
= ChunkSize
->getBeginLoc();
16936 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc
, ChunkSize
);
16937 if (Val
.isInvalid())
16940 ValExpr
= Val
.get();
16942 // OpenMP [2.7.1, Restrictions]
16943 // chunk_size must be a loop invariant integer expression with a positive
16945 if (Optional
<llvm::APSInt
> Result
=
16946 ValExpr
->getIntegerConstantExpr(Context
)) {
16947 if (Result
->isSigned() && !Result
->isStrictlyPositive()) {
16948 Diag(ChunkSizeLoc
, diag::err_omp_negative_expression_in_clause
)
16949 << "schedule" << 1 << ChunkSize
->getSourceRange();
16952 } else if (getOpenMPCaptureRegionForClause(
16953 DSAStack
->getCurrentDirective(), OMPC_schedule
,
16954 LangOpts
.OpenMP
) != OMPD_unknown
&&
16955 !CurContext
->isDependentContext()) {
16956 ValExpr
= MakeFullExpr(ValExpr
).get();
16957 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
16958 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
16959 HelperValStmt
= buildPreInits(Context
, Captures
);
16964 return new (Context
)
16965 OMPScheduleClause(StartLoc
, LParenLoc
, KindLoc
, CommaLoc
, EndLoc
, Kind
,
16966 ValExpr
, HelperValStmt
, M1
, M1Loc
, M2
, M2Loc
);
16969 OMPClause
*Sema::ActOnOpenMPClause(OpenMPClauseKind Kind
,
16970 SourceLocation StartLoc
,
16971 SourceLocation EndLoc
) {
16972 OMPClause
*Res
= nullptr;
16975 Res
= ActOnOpenMPOrderedClause(StartLoc
, EndLoc
);
16978 Res
= ActOnOpenMPNowaitClause(StartLoc
, EndLoc
);
16981 Res
= ActOnOpenMPUntiedClause(StartLoc
, EndLoc
);
16983 case OMPC_mergeable
:
16984 Res
= ActOnOpenMPMergeableClause(StartLoc
, EndLoc
);
16987 Res
= ActOnOpenMPReadClause(StartLoc
, EndLoc
);
16990 Res
= ActOnOpenMPWriteClause(StartLoc
, EndLoc
);
16993 Res
= ActOnOpenMPUpdateClause(StartLoc
, EndLoc
);
16996 Res
= ActOnOpenMPCaptureClause(StartLoc
, EndLoc
);
16999 Res
= ActOnOpenMPCompareClause(StartLoc
, EndLoc
);
17002 Res
= ActOnOpenMPSeqCstClause(StartLoc
, EndLoc
);
17005 Res
= ActOnOpenMPAcqRelClause(StartLoc
, EndLoc
);
17008 Res
= ActOnOpenMPAcquireClause(StartLoc
, EndLoc
);
17011 Res
= ActOnOpenMPReleaseClause(StartLoc
, EndLoc
);
17014 Res
= ActOnOpenMPRelaxedClause(StartLoc
, EndLoc
);
17017 Res
= ActOnOpenMPThreadsClause(StartLoc
, EndLoc
);
17020 Res
= ActOnOpenMPSIMDClause(StartLoc
, EndLoc
);
17023 Res
= ActOnOpenMPNogroupClause(StartLoc
, EndLoc
);
17025 case OMPC_unified_address
:
17026 Res
= ActOnOpenMPUnifiedAddressClause(StartLoc
, EndLoc
);
17028 case OMPC_unified_shared_memory
:
17029 Res
= ActOnOpenMPUnifiedSharedMemoryClause(StartLoc
, EndLoc
);
17031 case OMPC_reverse_offload
:
17032 Res
= ActOnOpenMPReverseOffloadClause(StartLoc
, EndLoc
);
17034 case OMPC_dynamic_allocators
:
17035 Res
= ActOnOpenMPDynamicAllocatorsClause(StartLoc
, EndLoc
);
17038 Res
= ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc
,
17039 /*LParenLoc=*/SourceLocation(),
17040 /*VarLoc=*/SourceLocation(), EndLoc
);
17043 Res
= ActOnOpenMPFullClause(StartLoc
, EndLoc
);
17046 Res
= ActOnOpenMPPartialClause(nullptr, StartLoc
, /*LParenLoc=*/{}, EndLoc
);
17050 case OMPC_num_threads
:
17054 case OMPC_allocator
:
17055 case OMPC_collapse
:
17056 case OMPC_schedule
:
17058 case OMPC_firstprivate
:
17059 case OMPC_lastprivate
:
17061 case OMPC_reduction
:
17062 case OMPC_task_reduction
:
17063 case OMPC_in_reduction
:
17067 case OMPC_copyprivate
:
17069 case OMPC_proc_bind
:
17070 case OMPC_threadprivate
:
17071 case OMPC_allocate
:
17077 case OMPC_num_teams
:
17078 case OMPC_thread_limit
:
17079 case OMPC_priority
:
17080 case OMPC_grainsize
:
17081 case OMPC_num_tasks
:
17083 case OMPC_dist_schedule
:
17084 case OMPC_defaultmap
:
17089 case OMPC_use_device_ptr
:
17090 case OMPC_use_device_addr
:
17091 case OMPC_is_device_ptr
:
17092 case OMPC_has_device_addr
:
17093 case OMPC_atomic_default_mem_order
:
17094 case OMPC_device_type
:
17096 case OMPC_nontemporal
:
17098 case OMPC_novariants
:
17099 case OMPC_nocontext
:
17101 case OMPC_inclusive
:
17102 case OMPC_exclusive
:
17103 case OMPC_uses_allocators
:
17104 case OMPC_affinity
:
17107 llvm_unreachable("Clause is not allowed.");
17112 OMPClause
*Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc
,
17113 SourceLocation EndLoc
) {
17114 DSAStack
->setNowaitRegion();
17115 return new (Context
) OMPNowaitClause(StartLoc
, EndLoc
);
17118 OMPClause
*Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc
,
17119 SourceLocation EndLoc
) {
17120 DSAStack
->setUntiedRegion();
17121 return new (Context
) OMPUntiedClause(StartLoc
, EndLoc
);
17124 OMPClause
*Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc
,
17125 SourceLocation EndLoc
) {
17126 return new (Context
) OMPMergeableClause(StartLoc
, EndLoc
);
17129 OMPClause
*Sema::ActOnOpenMPReadClause(SourceLocation StartLoc
,
17130 SourceLocation EndLoc
) {
17131 return new (Context
) OMPReadClause(StartLoc
, EndLoc
);
17134 OMPClause
*Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc
,
17135 SourceLocation EndLoc
) {
17136 return new (Context
) OMPWriteClause(StartLoc
, EndLoc
);
17139 OMPClause
*Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc
,
17140 SourceLocation EndLoc
) {
17141 return OMPUpdateClause::Create(Context
, StartLoc
, EndLoc
);
17144 OMPClause
*Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc
,
17145 SourceLocation EndLoc
) {
17146 return new (Context
) OMPCaptureClause(StartLoc
, EndLoc
);
17149 OMPClause
*Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc
,
17150 SourceLocation EndLoc
) {
17151 return new (Context
) OMPCompareClause(StartLoc
, EndLoc
);
17154 OMPClause
*Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc
,
17155 SourceLocation EndLoc
) {
17156 return new (Context
) OMPSeqCstClause(StartLoc
, EndLoc
);
17159 OMPClause
*Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc
,
17160 SourceLocation EndLoc
) {
17161 return new (Context
) OMPAcqRelClause(StartLoc
, EndLoc
);
17164 OMPClause
*Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc
,
17165 SourceLocation EndLoc
) {
17166 return new (Context
) OMPAcquireClause(StartLoc
, EndLoc
);
17169 OMPClause
*Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc
,
17170 SourceLocation EndLoc
) {
17171 return new (Context
) OMPReleaseClause(StartLoc
, EndLoc
);
17174 OMPClause
*Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc
,
17175 SourceLocation EndLoc
) {
17176 return new (Context
) OMPRelaxedClause(StartLoc
, EndLoc
);
17179 OMPClause
*Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc
,
17180 SourceLocation EndLoc
) {
17181 return new (Context
) OMPThreadsClause(StartLoc
, EndLoc
);
17184 OMPClause
*Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc
,
17185 SourceLocation EndLoc
) {
17186 return new (Context
) OMPSIMDClause(StartLoc
, EndLoc
);
17189 OMPClause
*Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc
,
17190 SourceLocation EndLoc
) {
17191 return new (Context
) OMPNogroupClause(StartLoc
, EndLoc
);
17194 OMPClause
*Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc
,
17195 SourceLocation EndLoc
) {
17196 return new (Context
) OMPUnifiedAddressClause(StartLoc
, EndLoc
);
17199 OMPClause
*Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc
,
17200 SourceLocation EndLoc
) {
17201 return new (Context
) OMPUnifiedSharedMemoryClause(StartLoc
, EndLoc
);
17204 OMPClause
*Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc
,
17205 SourceLocation EndLoc
) {
17206 return new (Context
) OMPReverseOffloadClause(StartLoc
, EndLoc
);
17209 OMPClause
*Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc
,
17210 SourceLocation EndLoc
) {
17211 return new (Context
) OMPDynamicAllocatorsClause(StartLoc
, EndLoc
);
17214 StmtResult
Sema::ActOnOpenMPInteropDirective(ArrayRef
<OMPClause
*> Clauses
,
17215 SourceLocation StartLoc
,
17216 SourceLocation EndLoc
) {
17218 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17219 // At least one action-clause must appear on a directive.
17220 if (!hasClauses(Clauses
, OMPC_init
, OMPC_use
, OMPC_destroy
, OMPC_nowait
)) {
17221 StringRef Expected
= "'init', 'use', 'destroy', or 'nowait'";
17222 Diag(StartLoc
, diag::err_omp_no_clause_for_directive
)
17223 << Expected
<< getOpenMPDirectiveName(OMPD_interop
);
17224 return StmtError();
17227 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17228 // A depend clause can only appear on the directive if a targetsync
17229 // interop-type is present or the interop-var was initialized with
17230 // the targetsync interop-type.
17232 // If there is any 'init' clause diagnose if there is no 'init' clause with
17233 // interop-type of 'targetsync'. Cases involving other directives cannot be
17235 const OMPDependClause
*DependClause
= nullptr;
17236 bool HasInitClause
= false;
17237 bool IsTargetSync
= false;
17238 for (const OMPClause
*C
: Clauses
) {
17241 if (const auto *InitClause
= dyn_cast
<OMPInitClause
>(C
)) {
17242 HasInitClause
= true;
17243 if (InitClause
->getIsTargetSync())
17244 IsTargetSync
= true;
17245 } else if (const auto *DC
= dyn_cast
<OMPDependClause
>(C
)) {
17249 if (DependClause
&& HasInitClause
&& !IsTargetSync
) {
17250 Diag(DependClause
->getBeginLoc(), diag::err_omp_interop_bad_depend_clause
);
17251 return StmtError();
17254 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17255 // Each interop-var may be specified for at most one action-clause of each
17256 // interop construct.
17257 llvm::SmallPtrSet
<const ValueDecl
*, 4> InteropVars
;
17258 for (OMPClause
*C
: Clauses
) {
17259 OpenMPClauseKind ClauseKind
= C
->getClauseKind();
17260 std::pair
<ValueDecl
*, bool> DeclResult
;
17261 SourceLocation ELoc
;
17262 SourceRange ERange
;
17264 if (ClauseKind
== OMPC_init
) {
17265 auto *E
= cast
<OMPInitClause
>(C
)->getInteropVar();
17266 DeclResult
= getPrivateItem(*this, E
, ELoc
, ERange
);
17267 } else if (ClauseKind
== OMPC_use
) {
17268 auto *E
= cast
<OMPUseClause
>(C
)->getInteropVar();
17269 DeclResult
= getPrivateItem(*this, E
, ELoc
, ERange
);
17270 } else if (ClauseKind
== OMPC_destroy
) {
17271 auto *E
= cast
<OMPDestroyClause
>(C
)->getInteropVar();
17272 DeclResult
= getPrivateItem(*this, E
, ELoc
, ERange
);
17275 if (DeclResult
.first
) {
17276 if (!InteropVars
.insert(DeclResult
.first
).second
) {
17277 Diag(ELoc
, diag::err_omp_interop_var_multiple_actions
)
17278 << DeclResult
.first
;
17279 return StmtError();
17284 return OMPInteropDirective::Create(Context
, StartLoc
, EndLoc
, Clauses
);
17287 static bool isValidInteropVariable(Sema
&SemaRef
, Expr
*InteropVarExpr
,
17288 SourceLocation VarLoc
,
17289 OpenMPClauseKind Kind
) {
17290 SourceLocation ELoc
;
17291 SourceRange ERange
;
17292 Expr
*RefExpr
= InteropVarExpr
;
17294 getPrivateItem(SemaRef
, RefExpr
, ELoc
, ERange
,
17295 /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17298 // It will be analyzed later.
17305 // Interop variable should be of type omp_interop_t.
17306 bool HasError
= false;
17307 QualType InteropType
;
17308 LookupResult
Result(SemaRef
, &SemaRef
.Context
.Idents
.get("omp_interop_t"),
17309 VarLoc
, Sema::LookupOrdinaryName
);
17310 if (SemaRef
.LookupName(Result
, SemaRef
.getCurScope())) {
17311 NamedDecl
*ND
= Result
.getFoundDecl();
17312 if (const auto *TD
= dyn_cast
<TypeDecl
>(ND
)) {
17313 InteropType
= QualType(TD
->getTypeForDecl(), 0);
17322 SemaRef
.Diag(VarLoc
, diag::err_omp_implied_type_not_found
)
17323 << "omp_interop_t";
17327 QualType VarType
= InteropVarExpr
->getType().getUnqualifiedType();
17328 if (!SemaRef
.Context
.hasSameType(InteropType
, VarType
)) {
17329 SemaRef
.Diag(VarLoc
, diag::err_omp_interop_variable_wrong_type
);
17333 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17334 // The interop-var passed to init or destroy must be non-const.
17335 if ((Kind
== OMPC_init
|| Kind
== OMPC_destroy
) &&
17336 isConstNotMutableType(SemaRef
, InteropVarExpr
->getType())) {
17337 SemaRef
.Diag(VarLoc
, diag::err_omp_interop_variable_expected
)
17338 << /*non-const*/ 1;
17345 Sema::ActOnOpenMPInitClause(Expr
*InteropVar
, OMPInteropInfo
&InteropInfo
,
17346 SourceLocation StartLoc
, SourceLocation LParenLoc
,
17347 SourceLocation VarLoc
, SourceLocation EndLoc
) {
17349 if (!isValidInteropVariable(*this, InteropVar
, VarLoc
, OMPC_init
))
17352 // Check prefer_type values. These foreign-runtime-id values are either
17353 // string literals or constant integral expressions.
17354 for (const Expr
*E
: InteropInfo
.PreferTypes
) {
17355 if (E
->isValueDependent() || E
->isTypeDependent() ||
17356 E
->isInstantiationDependent() || E
->containsUnexpandedParameterPack())
17358 if (E
->isIntegerConstantExpr(Context
))
17360 if (isa
<StringLiteral
>(E
))
17362 Diag(E
->getExprLoc(), diag::err_omp_interop_prefer_type
);
17366 return OMPInitClause::Create(Context
, InteropVar
, InteropInfo
, StartLoc
,
17367 LParenLoc
, VarLoc
, EndLoc
);
17370 OMPClause
*Sema::ActOnOpenMPUseClause(Expr
*InteropVar
, SourceLocation StartLoc
,
17371 SourceLocation LParenLoc
,
17372 SourceLocation VarLoc
,
17373 SourceLocation EndLoc
) {
17375 if (!isValidInteropVariable(*this, InteropVar
, VarLoc
, OMPC_use
))
17378 return new (Context
)
17379 OMPUseClause(InteropVar
, StartLoc
, LParenLoc
, VarLoc
, EndLoc
);
17382 OMPClause
*Sema::ActOnOpenMPDestroyClause(Expr
*InteropVar
,
17383 SourceLocation StartLoc
,
17384 SourceLocation LParenLoc
,
17385 SourceLocation VarLoc
,
17386 SourceLocation EndLoc
) {
17388 !isValidInteropVariable(*this, InteropVar
, VarLoc
, OMPC_destroy
))
17391 return new (Context
)
17392 OMPDestroyClause(InteropVar
, StartLoc
, LParenLoc
, VarLoc
, EndLoc
);
17395 OMPClause
*Sema::ActOnOpenMPNovariantsClause(Expr
*Condition
,
17396 SourceLocation StartLoc
,
17397 SourceLocation LParenLoc
,
17398 SourceLocation EndLoc
) {
17399 Expr
*ValExpr
= Condition
;
17400 Stmt
*HelperValStmt
= nullptr;
17401 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
17402 if (!Condition
->isValueDependent() && !Condition
->isTypeDependent() &&
17403 !Condition
->isInstantiationDependent() &&
17404 !Condition
->containsUnexpandedParameterPack()) {
17405 ExprResult Val
= CheckBooleanCondition(StartLoc
, Condition
);
17406 if (Val
.isInvalid())
17409 ValExpr
= MakeFullExpr(Val
.get()).get();
17411 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
17412 CaptureRegion
= getOpenMPCaptureRegionForClause(DKind
, OMPC_novariants
,
17414 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
17415 ValExpr
= MakeFullExpr(ValExpr
).get();
17416 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
17417 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
17418 HelperValStmt
= buildPreInits(Context
, Captures
);
17422 return new (Context
) OMPNovariantsClause(
17423 ValExpr
, HelperValStmt
, CaptureRegion
, StartLoc
, LParenLoc
, EndLoc
);
17426 OMPClause
*Sema::ActOnOpenMPNocontextClause(Expr
*Condition
,
17427 SourceLocation StartLoc
,
17428 SourceLocation LParenLoc
,
17429 SourceLocation EndLoc
) {
17430 Expr
*ValExpr
= Condition
;
17431 Stmt
*HelperValStmt
= nullptr;
17432 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
17433 if (!Condition
->isValueDependent() && !Condition
->isTypeDependent() &&
17434 !Condition
->isInstantiationDependent() &&
17435 !Condition
->containsUnexpandedParameterPack()) {
17436 ExprResult Val
= CheckBooleanCondition(StartLoc
, Condition
);
17437 if (Val
.isInvalid())
17440 ValExpr
= MakeFullExpr(Val
.get()).get();
17442 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
17444 getOpenMPCaptureRegionForClause(DKind
, OMPC_nocontext
, LangOpts
.OpenMP
);
17445 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
17446 ValExpr
= MakeFullExpr(ValExpr
).get();
17447 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
17448 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
17449 HelperValStmt
= buildPreInits(Context
, Captures
);
17453 return new (Context
) OMPNocontextClause(ValExpr
, HelperValStmt
, CaptureRegion
,
17454 StartLoc
, LParenLoc
, EndLoc
);
17457 OMPClause
*Sema::ActOnOpenMPFilterClause(Expr
*ThreadID
,
17458 SourceLocation StartLoc
,
17459 SourceLocation LParenLoc
,
17460 SourceLocation EndLoc
) {
17461 Expr
*ValExpr
= ThreadID
;
17462 Stmt
*HelperValStmt
= nullptr;
17464 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
17465 OpenMPDirectiveKind CaptureRegion
=
17466 getOpenMPCaptureRegionForClause(DKind
, OMPC_filter
, LangOpts
.OpenMP
);
17467 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
17468 ValExpr
= MakeFullExpr(ValExpr
).get();
17469 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
17470 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
17471 HelperValStmt
= buildPreInits(Context
, Captures
);
17474 return new (Context
) OMPFilterClause(ValExpr
, HelperValStmt
, CaptureRegion
,
17475 StartLoc
, LParenLoc
, EndLoc
);
17478 OMPClause
*Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind
,
17479 ArrayRef
<Expr
*> VarList
,
17480 const OMPVarListLocTy
&Locs
,
17481 OpenMPVarListDataTy
&Data
) {
17482 SourceLocation StartLoc
= Locs
.StartLoc
;
17483 SourceLocation LParenLoc
= Locs
.LParenLoc
;
17484 SourceLocation EndLoc
= Locs
.EndLoc
;
17485 OMPClause
*Res
= nullptr;
17486 int ExtraModifier
= Data
.ExtraModifier
;
17487 SourceLocation ExtraModifierLoc
= Data
.ExtraModifierLoc
;
17488 SourceLocation ColonLoc
= Data
.ColonLoc
;
17491 Res
= ActOnOpenMPPrivateClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17493 case OMPC_firstprivate
:
17494 Res
= ActOnOpenMPFirstprivateClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17496 case OMPC_lastprivate
:
17497 assert(0 <= ExtraModifier
&& ExtraModifier
<= OMPC_LASTPRIVATE_unknown
&&
17498 "Unexpected lastprivate modifier.");
17499 Res
= ActOnOpenMPLastprivateClause(
17500 VarList
, static_cast<OpenMPLastprivateModifier
>(ExtraModifier
),
17501 ExtraModifierLoc
, ColonLoc
, StartLoc
, LParenLoc
, EndLoc
);
17504 Res
= ActOnOpenMPSharedClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17506 case OMPC_reduction
:
17507 assert(0 <= ExtraModifier
&& ExtraModifier
<= OMPC_REDUCTION_unknown
&&
17508 "Unexpected lastprivate modifier.");
17509 Res
= ActOnOpenMPReductionClause(
17510 VarList
, static_cast<OpenMPReductionClauseModifier
>(ExtraModifier
),
17511 StartLoc
, LParenLoc
, ExtraModifierLoc
, ColonLoc
, EndLoc
,
17512 Data
.ReductionOrMapperIdScopeSpec
, Data
.ReductionOrMapperId
);
17514 case OMPC_task_reduction
:
17515 Res
= ActOnOpenMPTaskReductionClause(
17516 VarList
, StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
17517 Data
.ReductionOrMapperIdScopeSpec
, Data
.ReductionOrMapperId
);
17519 case OMPC_in_reduction
:
17520 Res
= ActOnOpenMPInReductionClause(
17521 VarList
, StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
17522 Data
.ReductionOrMapperIdScopeSpec
, Data
.ReductionOrMapperId
);
17525 assert(0 <= ExtraModifier
&& ExtraModifier
<= OMPC_LINEAR_unknown
&&
17526 "Unexpected linear modifier.");
17527 Res
= ActOnOpenMPLinearClause(
17528 VarList
, Data
.DepModOrTailExpr
, StartLoc
, LParenLoc
,
17529 static_cast<OpenMPLinearClauseKind
>(ExtraModifier
), ExtraModifierLoc
,
17533 Res
= ActOnOpenMPAlignedClause(VarList
, Data
.DepModOrTailExpr
, StartLoc
,
17534 LParenLoc
, ColonLoc
, EndLoc
);
17537 Res
= ActOnOpenMPCopyinClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17539 case OMPC_copyprivate
:
17540 Res
= ActOnOpenMPCopyprivateClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17543 Res
= ActOnOpenMPFlushClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17546 assert(0 <= ExtraModifier
&& ExtraModifier
<= OMPC_DEPEND_unknown
&&
17547 "Unexpected depend modifier.");
17548 Res
= ActOnOpenMPDependClause(
17549 {static_cast<OpenMPDependClauseKind
>(ExtraModifier
), ExtraModifierLoc
,
17550 ColonLoc
, Data
.OmpAllMemoryLoc
},
17551 Data
.DepModOrTailExpr
, VarList
, StartLoc
, LParenLoc
, EndLoc
);
17554 assert(0 <= ExtraModifier
&& ExtraModifier
<= OMPC_MAP_unknown
&&
17555 "Unexpected map modifier.");
17556 Res
= ActOnOpenMPMapClause(
17557 Data
.MapTypeModifiers
, Data
.MapTypeModifiersLoc
,
17558 Data
.ReductionOrMapperIdScopeSpec
, Data
.ReductionOrMapperId
,
17559 static_cast<OpenMPMapClauseKind
>(ExtraModifier
), Data
.IsMapTypeImplicit
,
17560 ExtraModifierLoc
, ColonLoc
, VarList
, Locs
);
17564 ActOnOpenMPToClause(Data
.MotionModifiers
, Data
.MotionModifiersLoc
,
17565 Data
.ReductionOrMapperIdScopeSpec
,
17566 Data
.ReductionOrMapperId
, ColonLoc
, VarList
, Locs
);
17569 Res
= ActOnOpenMPFromClause(Data
.MotionModifiers
, Data
.MotionModifiersLoc
,
17570 Data
.ReductionOrMapperIdScopeSpec
,
17571 Data
.ReductionOrMapperId
, ColonLoc
, VarList
,
17574 case OMPC_use_device_ptr
:
17575 Res
= ActOnOpenMPUseDevicePtrClause(VarList
, Locs
);
17577 case OMPC_use_device_addr
:
17578 Res
= ActOnOpenMPUseDeviceAddrClause(VarList
, Locs
);
17580 case OMPC_is_device_ptr
:
17581 Res
= ActOnOpenMPIsDevicePtrClause(VarList
, Locs
);
17583 case OMPC_has_device_addr
:
17584 Res
= ActOnOpenMPHasDeviceAddrClause(VarList
, Locs
);
17586 case OMPC_allocate
:
17587 Res
= ActOnOpenMPAllocateClause(Data
.DepModOrTailExpr
, VarList
, StartLoc
,
17588 LParenLoc
, ColonLoc
, EndLoc
);
17590 case OMPC_nontemporal
:
17591 Res
= ActOnOpenMPNontemporalClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17593 case OMPC_inclusive
:
17594 Res
= ActOnOpenMPInclusiveClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17596 case OMPC_exclusive
:
17597 Res
= ActOnOpenMPExclusiveClause(VarList
, StartLoc
, LParenLoc
, EndLoc
);
17599 case OMPC_affinity
:
17600 Res
= ActOnOpenMPAffinityClause(StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
17601 Data
.DepModOrTailExpr
, VarList
);
17606 case OMPC_num_threads
:
17610 case OMPC_allocator
:
17611 case OMPC_collapse
:
17613 case OMPC_proc_bind
:
17614 case OMPC_schedule
:
17618 case OMPC_mergeable
:
17619 case OMPC_threadprivate
:
17633 case OMPC_num_teams
:
17634 case OMPC_thread_limit
:
17635 case OMPC_priority
:
17636 case OMPC_grainsize
:
17638 case OMPC_num_tasks
:
17640 case OMPC_dist_schedule
:
17641 case OMPC_defaultmap
:
17644 case OMPC_unified_address
:
17645 case OMPC_unified_shared_memory
:
17646 case OMPC_reverse_offload
:
17647 case OMPC_dynamic_allocators
:
17648 case OMPC_atomic_default_mem_order
:
17649 case OMPC_device_type
:
17653 case OMPC_novariants
:
17654 case OMPC_nocontext
:
17656 case OMPC_uses_allocators
:
17660 llvm_unreachable("Clause is not allowed.");
17665 ExprResult
Sema::getOpenMPCapturedExpr(VarDecl
*Capture
, ExprValueKind VK
,
17666 ExprObjectKind OK
, SourceLocation Loc
) {
17667 ExprResult Res
= BuildDeclRefExpr(
17668 Capture
, Capture
->getType().getNonReferenceType(), VK_LValue
, Loc
);
17669 if (!Res
.isUsable())
17670 return ExprError();
17671 if (OK
== OK_Ordinary
&& !getLangOpts().CPlusPlus
) {
17672 Res
= CreateBuiltinUnaryOp(Loc
, UO_Deref
, Res
.get());
17673 if (!Res
.isUsable())
17674 return ExprError();
17676 if (VK
!= VK_LValue
&& Res
.get()->isGLValue()) {
17677 Res
= DefaultLvalueConversion(Res
.get());
17678 if (!Res
.isUsable())
17679 return ExprError();
17684 OMPClause
*Sema::ActOnOpenMPPrivateClause(ArrayRef
<Expr
*> VarList
,
17685 SourceLocation StartLoc
,
17686 SourceLocation LParenLoc
,
17687 SourceLocation EndLoc
) {
17688 SmallVector
<Expr
*, 8> Vars
;
17689 SmallVector
<Expr
*, 8> PrivateCopies
;
17690 bool IsImplicitClause
=
17691 StartLoc
.isInvalid() && LParenLoc
.isInvalid() && EndLoc
.isInvalid();
17692 for (Expr
*RefExpr
: VarList
) {
17693 assert(RefExpr
&& "NULL expr in OpenMP private clause.");
17694 SourceLocation ELoc
;
17695 SourceRange ERange
;
17696 Expr
*SimpleRefExpr
= RefExpr
;
17697 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
17699 // It will be analyzed later.
17700 Vars
.push_back(RefExpr
);
17701 PrivateCopies
.push_back(nullptr);
17703 ValueDecl
*D
= Res
.first
;
17707 QualType Type
= D
->getType();
17708 auto *VD
= dyn_cast
<VarDecl
>(D
);
17710 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17711 // A variable that appears in a private clause must not have an incomplete
17712 // type or a reference type.
17713 if (RequireCompleteType(ELoc
, Type
, diag::err_omp_private_incomplete_type
))
17715 Type
= Type
.getNonReferenceType();
17717 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17718 // A variable that is privatized must not have a const-qualified type
17719 // unless it is of class type with a mutable member. This restriction does
17720 // not apply to the firstprivate clause.
17722 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17723 // A variable that appears in a private clause must not have a
17724 // const-qualified type unless it is of class type with a mutable member.
17725 if (rejectConstNotMutableType(*this, D
, Type
, OMPC_private
, ELoc
))
17728 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17730 // Variables with the predetermined data-sharing attributes may not be
17731 // listed in data-sharing attributes clauses, except for the cases
17732 // listed below. For these exceptions only, listing a predetermined
17733 // variable in a data-sharing attribute clause is allowed and overrides
17734 // the variable's predetermined data-sharing attributes.
17735 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
17736 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_private
) {
17737 Diag(ELoc
, diag::err_omp_wrong_dsa
) << getOpenMPClauseName(DVar
.CKind
)
17738 << getOpenMPClauseName(OMPC_private
);
17739 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17743 OpenMPDirectiveKind CurrDir
= DSAStack
->getCurrentDirective();
17744 // Variably modified types are not supported for tasks.
17745 if (!Type
->isAnyPointerType() && Type
->isVariablyModifiedType() &&
17746 isOpenMPTaskingDirective(CurrDir
)) {
17747 Diag(ELoc
, diag::err_omp_variably_modified_type_not_supported
)
17748 << getOpenMPClauseName(OMPC_private
) << Type
17749 << getOpenMPDirectiveName(CurrDir
);
17750 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
17751 VarDecl::DeclarationOnly
;
17752 Diag(D
->getLocation(),
17753 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
17758 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17759 // A list item cannot appear in both a map clause and a data-sharing
17760 // attribute clause on the same construct
17762 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17763 // A list item cannot appear in both a map clause and a data-sharing
17764 // attribute clause on the same construct unless the construct is a
17765 // combined construct.
17766 if ((LangOpts
.OpenMP
<= 45 && isOpenMPTargetExecutionDirective(CurrDir
)) ||
17767 CurrDir
== OMPD_target
) {
17768 OpenMPClauseKind ConflictKind
;
17769 if (DSAStack
->checkMappableExprComponentListsForDecl(
17770 VD
, /*CurrentRegionOnly=*/true,
17771 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
,
17772 OpenMPClauseKind WhereFoundClauseKind
) -> bool {
17773 ConflictKind
= WhereFoundClauseKind
;
17776 Diag(ELoc
, diag::err_omp_variable_in_given_clause_and_dsa
)
17777 << getOpenMPClauseName(OMPC_private
)
17778 << getOpenMPClauseName(ConflictKind
)
17779 << getOpenMPDirectiveName(CurrDir
);
17780 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17785 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17786 // A variable of class type (or array thereof) that appears in a private
17787 // clause requires an accessible, unambiguous default constructor for the
17789 // Generate helper private variable and initialize it with the default
17790 // value. The address of the original variable is replaced by the address of
17791 // the new private variable in CodeGen. This new variable is not added to
17792 // IdResolver, so the code in the OpenMP region uses original variable for
17793 // proper diagnostics.
17794 Type
= Type
.getUnqualifiedType();
17795 VarDecl
*VDPrivate
=
17796 buildVarDecl(*this, ELoc
, Type
, D
->getName(),
17797 D
->hasAttrs() ? &D
->getAttrs() : nullptr,
17798 VD
? cast
<DeclRefExpr
>(SimpleRefExpr
) : nullptr);
17799 ActOnUninitializedDecl(VDPrivate
);
17800 if (VDPrivate
->isInvalidDecl())
17802 DeclRefExpr
*VDPrivateRefExpr
= buildDeclRefExpr(
17803 *this, VDPrivate
, RefExpr
->getType().getUnqualifiedType(), ELoc
);
17805 DeclRefExpr
*Ref
= nullptr;
17806 if (!VD
&& !CurContext
->isDependentContext()) {
17807 auto *FD
= dyn_cast
<FieldDecl
>(D
);
17808 VarDecl
*VD
= FD
? DSAStack
->getImplicitFDCapExprDecl(FD
) : nullptr;
17810 Ref
= buildDeclRefExpr(*this, VD
, VD
->getType().getNonReferenceType(),
17811 RefExpr
->getExprLoc());
17813 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/false);
17815 if (!IsImplicitClause
)
17816 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_private
, Ref
);
17817 Vars
.push_back((VD
|| CurContext
->isDependentContext())
17818 ? RefExpr
->IgnoreParens()
17820 PrivateCopies
.push_back(VDPrivateRefExpr
);
17826 return OMPPrivateClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Vars
,
17830 OMPClause
*Sema::ActOnOpenMPFirstprivateClause(ArrayRef
<Expr
*> VarList
,
17831 SourceLocation StartLoc
,
17832 SourceLocation LParenLoc
,
17833 SourceLocation EndLoc
) {
17834 SmallVector
<Expr
*, 8> Vars
;
17835 SmallVector
<Expr
*, 8> PrivateCopies
;
17836 SmallVector
<Expr
*, 8> Inits
;
17837 SmallVector
<Decl
*, 4> ExprCaptures
;
17838 bool IsImplicitClause
=
17839 StartLoc
.isInvalid() && LParenLoc
.isInvalid() && EndLoc
.isInvalid();
17840 SourceLocation ImplicitClauseLoc
= DSAStack
->getConstructLoc();
17842 for (Expr
*RefExpr
: VarList
) {
17843 assert(RefExpr
&& "NULL expr in OpenMP firstprivate clause.");
17844 SourceLocation ELoc
;
17845 SourceRange ERange
;
17846 Expr
*SimpleRefExpr
= RefExpr
;
17847 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
17849 // It will be analyzed later.
17850 Vars
.push_back(RefExpr
);
17851 PrivateCopies
.push_back(nullptr);
17852 Inits
.push_back(nullptr);
17854 ValueDecl
*D
= Res
.first
;
17858 ELoc
= IsImplicitClause
? ImplicitClauseLoc
: ELoc
;
17859 QualType Type
= D
->getType();
17860 auto *VD
= dyn_cast
<VarDecl
>(D
);
17862 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17863 // A variable that appears in a private clause must not have an incomplete
17864 // type or a reference type.
17865 if (RequireCompleteType(ELoc
, Type
,
17866 diag::err_omp_firstprivate_incomplete_type
))
17868 Type
= Type
.getNonReferenceType();
17870 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
17871 // A variable of class type (or array thereof) that appears in a private
17872 // clause requires an accessible, unambiguous copy constructor for the
17874 QualType ElemType
= Context
.getBaseElementType(Type
).getNonReferenceType();
17876 // If an implicit firstprivate variable found it was checked already.
17877 DSAStackTy::DSAVarData TopDVar
;
17878 if (!IsImplicitClause
) {
17879 DSAStackTy::DSAVarData DVar
=
17880 DSAStack
->getTopDSA(D
, /*FromParent=*/false);
17882 OpenMPDirectiveKind CurrDir
= DSAStack
->getCurrentDirective();
17883 bool IsConstant
= ElemType
.isConstant(Context
);
17884 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17885 // A list item that specifies a given variable may not appear in more
17886 // than one clause on the same directive, except that a variable may be
17887 // specified in both firstprivate and lastprivate clauses.
17888 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17889 // A list item may appear in a firstprivate or lastprivate clause but not
17891 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_firstprivate
&&
17892 (isOpenMPDistributeDirective(CurrDir
) ||
17893 DVar
.CKind
!= OMPC_lastprivate
) &&
17895 Diag(ELoc
, diag::err_omp_wrong_dsa
)
17896 << getOpenMPClauseName(DVar
.CKind
)
17897 << getOpenMPClauseName(OMPC_firstprivate
);
17898 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17902 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17904 // Variables with the predetermined data-sharing attributes may not be
17905 // listed in data-sharing attributes clauses, except for the cases
17906 // listed below. For these exceptions only, listing a predetermined
17907 // variable in a data-sharing attribute clause is allowed and overrides
17908 // the variable's predetermined data-sharing attributes.
17909 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17910 // in a Construct, C/C++, p.2]
17911 // Variables with const-qualified type having no mutable member may be
17912 // listed in a firstprivate clause, even if they are static data members.
17913 if (!(IsConstant
|| (VD
&& VD
->isStaticDataMember())) && !DVar
.RefExpr
&&
17914 DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_shared
) {
17915 Diag(ELoc
, diag::err_omp_wrong_dsa
)
17916 << getOpenMPClauseName(DVar
.CKind
)
17917 << getOpenMPClauseName(OMPC_firstprivate
);
17918 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17922 // OpenMP [2.9.3.4, Restrictions, p.2]
17923 // A list item that is private within a parallel region must not appear
17924 // in a firstprivate clause on a worksharing construct if any of the
17925 // worksharing regions arising from the worksharing construct ever bind
17926 // to any of the parallel regions arising from the parallel construct.
17927 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17928 // A list item that is private within a teams region must not appear in a
17929 // firstprivate clause on a distribute construct if any of the distribute
17930 // regions arising from the distribute construct ever bind to any of the
17931 // teams regions arising from the teams construct.
17932 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17933 // A list item that appears in a reduction clause of a teams construct
17934 // must not appear in a firstprivate clause on a distribute construct if
17935 // any of the distribute regions arising from the distribute construct
17936 // ever bind to any of the teams regions arising from the teams construct.
17937 if ((isOpenMPWorksharingDirective(CurrDir
) ||
17938 isOpenMPDistributeDirective(CurrDir
)) &&
17939 !isOpenMPParallelDirective(CurrDir
) &&
17940 !isOpenMPTeamsDirective(CurrDir
)) {
17941 DVar
= DSAStack
->getImplicitDSA(D
, true);
17942 if (DVar
.CKind
!= OMPC_shared
&&
17943 (isOpenMPParallelDirective(DVar
.DKind
) ||
17944 isOpenMPTeamsDirective(DVar
.DKind
) ||
17945 DVar
.DKind
== OMPD_unknown
)) {
17946 Diag(ELoc
, diag::err_omp_required_access
)
17947 << getOpenMPClauseName(OMPC_firstprivate
)
17948 << getOpenMPClauseName(OMPC_shared
);
17949 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17953 // OpenMP [2.9.3.4, Restrictions, p.3]
17954 // A list item that appears in a reduction clause of a parallel construct
17955 // must not appear in a firstprivate clause on a worksharing or task
17956 // construct if any of the worksharing or task regions arising from the
17957 // worksharing or task construct ever bind to any of the parallel regions
17958 // arising from the parallel construct.
17959 // OpenMP [2.9.3.4, Restrictions, p.4]
17960 // A list item that appears in a reduction clause in worksharing
17961 // construct must not appear in a firstprivate clause in a task construct
17962 // encountered during execution of any of the worksharing regions arising
17963 // from the worksharing construct.
17964 if (isOpenMPTaskingDirective(CurrDir
)) {
17965 DVar
= DSAStack
->hasInnermostDSA(
17967 [](OpenMPClauseKind C
, bool AppliedToPointee
) {
17968 return C
== OMPC_reduction
&& !AppliedToPointee
;
17970 [](OpenMPDirectiveKind K
) {
17971 return isOpenMPParallelDirective(K
) ||
17972 isOpenMPWorksharingDirective(K
) ||
17973 isOpenMPTeamsDirective(K
);
17975 /*FromParent=*/true);
17976 if (DVar
.CKind
== OMPC_reduction
&&
17977 (isOpenMPParallelDirective(DVar
.DKind
) ||
17978 isOpenMPWorksharingDirective(DVar
.DKind
) ||
17979 isOpenMPTeamsDirective(DVar
.DKind
))) {
17980 Diag(ELoc
, diag::err_omp_parallel_reduction_in_task_firstprivate
)
17981 << getOpenMPDirectiveName(DVar
.DKind
);
17982 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
17987 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17988 // A list item cannot appear in both a map clause and a data-sharing
17989 // attribute clause on the same construct
17991 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17992 // A list item cannot appear in both a map clause and a data-sharing
17993 // attribute clause on the same construct unless the construct is a
17994 // combined construct.
17995 if ((LangOpts
.OpenMP
<= 45 &&
17996 isOpenMPTargetExecutionDirective(CurrDir
)) ||
17997 CurrDir
== OMPD_target
) {
17998 OpenMPClauseKind ConflictKind
;
17999 if (DSAStack
->checkMappableExprComponentListsForDecl(
18000 VD
, /*CurrentRegionOnly=*/true,
18002 OMPClauseMappableExprCommon::MappableExprComponentListRef
,
18003 OpenMPClauseKind WhereFoundClauseKind
) {
18004 ConflictKind
= WhereFoundClauseKind
;
18007 Diag(ELoc
, diag::err_omp_variable_in_given_clause_and_dsa
)
18008 << getOpenMPClauseName(OMPC_firstprivate
)
18009 << getOpenMPClauseName(ConflictKind
)
18010 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
18011 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
18017 // Variably modified types are not supported for tasks.
18018 if (!Type
->isAnyPointerType() && Type
->isVariablyModifiedType() &&
18019 isOpenMPTaskingDirective(DSAStack
->getCurrentDirective())) {
18020 Diag(ELoc
, diag::err_omp_variably_modified_type_not_supported
)
18021 << getOpenMPClauseName(OMPC_firstprivate
) << Type
18022 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
18023 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
18024 VarDecl::DeclarationOnly
;
18025 Diag(D
->getLocation(),
18026 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
18031 Type
= Type
.getUnqualifiedType();
18032 VarDecl
*VDPrivate
=
18033 buildVarDecl(*this, ELoc
, Type
, D
->getName(),
18034 D
->hasAttrs() ? &D
->getAttrs() : nullptr,
18035 VD
? cast
<DeclRefExpr
>(SimpleRefExpr
) : nullptr);
18036 // Generate helper private variable and initialize it with the value of the
18037 // original variable. The address of the original variable is replaced by
18038 // the address of the new private variable in the CodeGen. This new variable
18039 // is not added to IdResolver, so the code in the OpenMP region uses
18040 // original variable for proper diagnostics and variable capturing.
18041 Expr
*VDInitRefExpr
= nullptr;
18042 // For arrays generate initializer for single element and replace it by the
18043 // original array element in CodeGen.
18044 if (Type
->isArrayType()) {
18046 buildVarDecl(*this, RefExpr
->getExprLoc(), ElemType
, D
->getName());
18047 VDInitRefExpr
= buildDeclRefExpr(*this, VDInit
, ElemType
, ELoc
);
18048 Expr
*Init
= DefaultLvalueConversion(VDInitRefExpr
).get();
18049 ElemType
= ElemType
.getUnqualifiedType();
18050 VarDecl
*VDInitTemp
= buildVarDecl(*this, RefExpr
->getExprLoc(), ElemType
,
18051 ".firstprivate.temp");
18052 InitializedEntity Entity
=
18053 InitializedEntity::InitializeVariable(VDInitTemp
);
18054 InitializationKind Kind
= InitializationKind::CreateCopy(ELoc
, ELoc
);
18056 InitializationSequence
InitSeq(*this, Entity
, Kind
, Init
);
18057 ExprResult Result
= InitSeq
.Perform(*this, Entity
, Kind
, Init
);
18058 if (Result
.isInvalid())
18059 VDPrivate
->setInvalidDecl();
18061 VDPrivate
->setInit(Result
.getAs
<Expr
>());
18062 // Remove temp variable declaration.
18063 Context
.Deallocate(VDInitTemp
);
18065 VarDecl
*VDInit
= buildVarDecl(*this, RefExpr
->getExprLoc(), Type
,
18066 ".firstprivate.temp");
18067 VDInitRefExpr
= buildDeclRefExpr(*this, VDInit
, RefExpr
->getType(),
18068 RefExpr
->getExprLoc());
18069 AddInitializerToDecl(VDPrivate
,
18070 DefaultLvalueConversion(VDInitRefExpr
).get(),
18071 /*DirectInit=*/false);
18073 if (VDPrivate
->isInvalidDecl()) {
18074 if (IsImplicitClause
) {
18075 Diag(RefExpr
->getExprLoc(),
18076 diag::note_omp_task_predetermined_firstprivate_here
);
18080 CurContext
->addDecl(VDPrivate
);
18081 DeclRefExpr
*VDPrivateRefExpr
= buildDeclRefExpr(
18082 *this, VDPrivate
, RefExpr
->getType().getUnqualifiedType(),
18083 RefExpr
->getExprLoc());
18084 DeclRefExpr
*Ref
= nullptr;
18085 if (!VD
&& !CurContext
->isDependentContext()) {
18086 if (TopDVar
.CKind
== OMPC_lastprivate
) {
18087 Ref
= TopDVar
.PrivateCopy
;
18089 auto *FD
= dyn_cast
<FieldDecl
>(D
);
18090 VarDecl
*VD
= FD
? DSAStack
->getImplicitFDCapExprDecl(FD
) : nullptr;
18092 Ref
= buildDeclRefExpr(*this, VD
, VD
->getType().getNonReferenceType(),
18093 RefExpr
->getExprLoc());
18095 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
18096 if (VD
|| !isOpenMPCapturedDecl(D
))
18097 ExprCaptures
.push_back(Ref
->getDecl());
18100 if (!IsImplicitClause
)
18101 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_firstprivate
, Ref
);
18102 Vars
.push_back((VD
|| CurContext
->isDependentContext())
18103 ? RefExpr
->IgnoreParens()
18105 PrivateCopies
.push_back(VDPrivateRefExpr
);
18106 Inits
.push_back(VDInitRefExpr
);
18112 return OMPFirstprivateClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
18113 Vars
, PrivateCopies
, Inits
,
18114 buildPreInits(Context
, ExprCaptures
));
18117 OMPClause
*Sema::ActOnOpenMPLastprivateClause(
18118 ArrayRef
<Expr
*> VarList
, OpenMPLastprivateModifier LPKind
,
18119 SourceLocation LPKindLoc
, SourceLocation ColonLoc
, SourceLocation StartLoc
,
18120 SourceLocation LParenLoc
, SourceLocation EndLoc
) {
18121 if (LPKind
== OMPC_LASTPRIVATE_unknown
&& LPKindLoc
.isValid()) {
18122 assert(ColonLoc
.isValid() && "Colon location must be valid.");
18123 Diag(LPKindLoc
, diag::err_omp_unexpected_clause_value
)
18124 << getListOfPossibleValues(OMPC_lastprivate
, /*First=*/0,
18125 /*Last=*/OMPC_LASTPRIVATE_unknown
)
18126 << getOpenMPClauseName(OMPC_lastprivate
);
18130 SmallVector
<Expr
*, 8> Vars
;
18131 SmallVector
<Expr
*, 8> SrcExprs
;
18132 SmallVector
<Expr
*, 8> DstExprs
;
18133 SmallVector
<Expr
*, 8> AssignmentOps
;
18134 SmallVector
<Decl
*, 4> ExprCaptures
;
18135 SmallVector
<Expr
*, 4> ExprPostUpdates
;
18136 for (Expr
*RefExpr
: VarList
) {
18137 assert(RefExpr
&& "NULL expr in OpenMP lastprivate clause.");
18138 SourceLocation ELoc
;
18139 SourceRange ERange
;
18140 Expr
*SimpleRefExpr
= RefExpr
;
18141 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
18143 // It will be analyzed later.
18144 Vars
.push_back(RefExpr
);
18145 SrcExprs
.push_back(nullptr);
18146 DstExprs
.push_back(nullptr);
18147 AssignmentOps
.push_back(nullptr);
18149 ValueDecl
*D
= Res
.first
;
18153 QualType Type
= D
->getType();
18154 auto *VD
= dyn_cast
<VarDecl
>(D
);
18156 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18157 // A variable that appears in a lastprivate clause must not have an
18158 // incomplete type or a reference type.
18159 if (RequireCompleteType(ELoc
, Type
,
18160 diag::err_omp_lastprivate_incomplete_type
))
18162 Type
= Type
.getNonReferenceType();
18164 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18165 // A variable that is privatized must not have a const-qualified type
18166 // unless it is of class type with a mutable member. This restriction does
18167 // not apply to the firstprivate clause.
18169 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18170 // A variable that appears in a lastprivate clause must not have a
18171 // const-qualified type unless it is of class type with a mutable member.
18172 if (rejectConstNotMutableType(*this, D
, Type
, OMPC_lastprivate
, ELoc
))
18175 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18176 // A list item that appears in a lastprivate clause with the conditional
18177 // modifier must be a scalar variable.
18178 if (LPKind
== OMPC_LASTPRIVATE_conditional
&& !Type
->isScalarType()) {
18179 Diag(ELoc
, diag::err_omp_lastprivate_conditional_non_scalar
);
18180 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
18181 VarDecl::DeclarationOnly
;
18182 Diag(D
->getLocation(),
18183 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
18188 OpenMPDirectiveKind CurrDir
= DSAStack
->getCurrentDirective();
18189 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18191 // Variables with the predetermined data-sharing attributes may not be
18192 // listed in data-sharing attributes clauses, except for the cases
18194 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18195 // A list item may appear in a firstprivate or lastprivate clause but not
18197 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
18198 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_lastprivate
&&
18199 (isOpenMPDistributeDirective(CurrDir
) ||
18200 DVar
.CKind
!= OMPC_firstprivate
) &&
18201 (DVar
.CKind
!= OMPC_private
|| DVar
.RefExpr
!= nullptr)) {
18202 Diag(ELoc
, diag::err_omp_wrong_dsa
)
18203 << getOpenMPClauseName(DVar
.CKind
)
18204 << getOpenMPClauseName(OMPC_lastprivate
);
18205 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
18209 // OpenMP [2.14.3.5, Restrictions, p.2]
18210 // A list item that is private within a parallel region, or that appears in
18211 // the reduction clause of a parallel construct, must not appear in a
18212 // lastprivate clause on a worksharing construct if any of the corresponding
18213 // worksharing regions ever binds to any of the corresponding parallel
18215 DSAStackTy::DSAVarData TopDVar
= DVar
;
18216 if (isOpenMPWorksharingDirective(CurrDir
) &&
18217 !isOpenMPParallelDirective(CurrDir
) &&
18218 !isOpenMPTeamsDirective(CurrDir
)) {
18219 DVar
= DSAStack
->getImplicitDSA(D
, true);
18220 if (DVar
.CKind
!= OMPC_shared
) {
18221 Diag(ELoc
, diag::err_omp_required_access
)
18222 << getOpenMPClauseName(OMPC_lastprivate
)
18223 << getOpenMPClauseName(OMPC_shared
);
18224 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
18229 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18230 // A variable of class type (or array thereof) that appears in a
18231 // lastprivate clause requires an accessible, unambiguous default
18232 // constructor for the class type, unless the list item is also specified
18233 // in a firstprivate clause.
18234 // A variable of class type (or array thereof) that appears in a
18235 // lastprivate clause requires an accessible, unambiguous copy assignment
18236 // operator for the class type.
18237 Type
= Context
.getBaseElementType(Type
).getNonReferenceType();
18238 VarDecl
*SrcVD
= buildVarDecl(*this, ERange
.getBegin(),
18239 Type
.getUnqualifiedType(), ".lastprivate.src",
18240 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
18241 DeclRefExpr
*PseudoSrcExpr
=
18242 buildDeclRefExpr(*this, SrcVD
, Type
.getUnqualifiedType(), ELoc
);
18244 buildVarDecl(*this, ERange
.getBegin(), Type
, ".lastprivate.dst",
18245 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
18246 DeclRefExpr
*PseudoDstExpr
= buildDeclRefExpr(*this, DstVD
, Type
, ELoc
);
18247 // For arrays generate assignment operation for single element and replace
18248 // it by the original array element in CodeGen.
18249 ExprResult AssignmentOp
= BuildBinOp(/*S=*/nullptr, ELoc
, BO_Assign
,
18250 PseudoDstExpr
, PseudoSrcExpr
);
18251 if (AssignmentOp
.isInvalid())
18254 ActOnFinishFullExpr(AssignmentOp
.get(), ELoc
, /*DiscardedValue*/ false);
18255 if (AssignmentOp
.isInvalid())
18258 DeclRefExpr
*Ref
= nullptr;
18259 if (!VD
&& !CurContext
->isDependentContext()) {
18260 if (TopDVar
.CKind
== OMPC_firstprivate
) {
18261 Ref
= TopDVar
.PrivateCopy
;
18263 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/false);
18264 if (!isOpenMPCapturedDecl(D
))
18265 ExprCaptures
.push_back(Ref
->getDecl());
18267 if ((TopDVar
.CKind
== OMPC_firstprivate
&& !TopDVar
.PrivateCopy
) ||
18268 (!isOpenMPCapturedDecl(D
) &&
18269 Ref
->getDecl()->hasAttr
<OMPCaptureNoInitAttr
>())) {
18270 ExprResult RefRes
= DefaultLvalueConversion(Ref
);
18271 if (!RefRes
.isUsable())
18273 ExprResult PostUpdateRes
=
18274 BuildBinOp(DSAStack
->getCurScope(), ELoc
, BO_Assign
, SimpleRefExpr
,
18276 if (!PostUpdateRes
.isUsable())
18278 ExprPostUpdates
.push_back(
18279 IgnoredValueConversions(PostUpdateRes
.get()).get());
18282 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_lastprivate
, Ref
);
18283 Vars
.push_back((VD
|| CurContext
->isDependentContext())
18284 ? RefExpr
->IgnoreParens()
18286 SrcExprs
.push_back(PseudoSrcExpr
);
18287 DstExprs
.push_back(PseudoDstExpr
);
18288 AssignmentOps
.push_back(AssignmentOp
.get());
18294 return OMPLastprivateClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
18295 Vars
, SrcExprs
, DstExprs
, AssignmentOps
,
18296 LPKind
, LPKindLoc
, ColonLoc
,
18297 buildPreInits(Context
, ExprCaptures
),
18298 buildPostUpdate(*this, ExprPostUpdates
));
18301 OMPClause
*Sema::ActOnOpenMPSharedClause(ArrayRef
<Expr
*> VarList
,
18302 SourceLocation StartLoc
,
18303 SourceLocation LParenLoc
,
18304 SourceLocation EndLoc
) {
18305 SmallVector
<Expr
*, 8> Vars
;
18306 for (Expr
*RefExpr
: VarList
) {
18307 assert(RefExpr
&& "NULL expr in OpenMP lastprivate clause.");
18308 SourceLocation ELoc
;
18309 SourceRange ERange
;
18310 Expr
*SimpleRefExpr
= RefExpr
;
18311 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
18313 // It will be analyzed later.
18314 Vars
.push_back(RefExpr
);
18316 ValueDecl
*D
= Res
.first
;
18320 auto *VD
= dyn_cast
<VarDecl
>(D
);
18321 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18323 // Variables with the predetermined data-sharing attributes may not be
18324 // listed in data-sharing attributes clauses, except for the cases
18325 // listed below. For these exceptions only, listing a predetermined
18326 // variable in a data-sharing attribute clause is allowed and overrides
18327 // the variable's predetermined data-sharing attributes.
18328 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
18329 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_shared
&&
18331 Diag(ELoc
, diag::err_omp_wrong_dsa
) << getOpenMPClauseName(DVar
.CKind
)
18332 << getOpenMPClauseName(OMPC_shared
);
18333 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
18337 DeclRefExpr
*Ref
= nullptr;
18338 if (!VD
&& isOpenMPCapturedDecl(D
) && !CurContext
->isDependentContext())
18339 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
18340 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_shared
, Ref
);
18341 Vars
.push_back((VD
|| !Ref
|| CurContext
->isDependentContext())
18342 ? RefExpr
->IgnoreParens()
18349 return OMPSharedClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Vars
);
18353 class DSARefChecker
: public StmtVisitor
<DSARefChecker
, bool> {
18357 bool VisitDeclRefExpr(DeclRefExpr
*E
) {
18358 if (auto *VD
= dyn_cast
<VarDecl
>(E
->getDecl())) {
18359 DSAStackTy::DSAVarData DVar
= Stack
->getTopDSA(VD
, /*FromParent=*/false);
18360 if (DVar
.CKind
== OMPC_shared
&& !DVar
.RefExpr
)
18362 if (DVar
.CKind
!= OMPC_unknown
)
18364 DSAStackTy::DSAVarData DVarPrivate
= Stack
->hasDSA(
18366 [](OpenMPClauseKind C
, bool AppliedToPointee
, bool) {
18367 return isOpenMPPrivate(C
) && !AppliedToPointee
;
18369 [](OpenMPDirectiveKind
) { return true; },
18370 /*FromParent=*/true);
18371 return DVarPrivate
.CKind
!= OMPC_unknown
;
18375 bool VisitStmt(Stmt
*S
) {
18376 for (Stmt
*Child
: S
->children()) {
18377 if (Child
&& Visit(Child
))
18382 explicit DSARefChecker(DSAStackTy
*S
) : Stack(S
) {}
18387 // Transform MemberExpression for specified FieldDecl of current class to
18388 // DeclRefExpr to specified OMPCapturedExprDecl.
18389 class TransformExprToCaptures
: public TreeTransform
<TransformExprToCaptures
> {
18390 typedef TreeTransform
<TransformExprToCaptures
> BaseTransform
;
18391 ValueDecl
*Field
= nullptr;
18392 DeclRefExpr
*CapturedExpr
= nullptr;
18395 TransformExprToCaptures(Sema
&SemaRef
, ValueDecl
*FieldDecl
)
18396 : BaseTransform(SemaRef
), Field(FieldDecl
), CapturedExpr(nullptr) {}
18398 ExprResult
TransformMemberExpr(MemberExpr
*E
) {
18399 if (isa
<CXXThisExpr
>(E
->getBase()->IgnoreParenImpCasts()) &&
18400 E
->getMemberDecl() == Field
) {
18401 CapturedExpr
= buildCapture(SemaRef
, Field
, E
, /*WithInit=*/false);
18402 return CapturedExpr
;
18404 return BaseTransform::TransformMemberExpr(E
);
18406 DeclRefExpr
*getCapturedExpr() { return CapturedExpr
; }
18410 template <typename T
, typename U
>
18411 static T
filterLookupForUDReductionAndMapper(
18412 SmallVectorImpl
<U
> &Lookups
, const llvm::function_ref
<T(ValueDecl
*)> Gen
) {
18413 for (U
&Set
: Lookups
) {
18414 for (auto *D
: Set
) {
18415 if (T Res
= Gen(cast
<ValueDecl
>(D
)))
18422 static NamedDecl
*findAcceptableDecl(Sema
&SemaRef
, NamedDecl
*D
) {
18423 assert(!LookupResult::isVisible(SemaRef
, D
) && "not in slow case");
18425 for (auto *RD
: D
->redecls()) {
18426 // Don't bother with extra checks if we already know this one isn't visible.
18430 auto ND
= cast
<NamedDecl
>(RD
);
18431 if (LookupResult::isVisible(SemaRef
, ND
))
18439 argumentDependentLookup(Sema
&SemaRef
, const DeclarationNameInfo
&Id
,
18440 SourceLocation Loc
, QualType Ty
,
18441 SmallVectorImpl
<UnresolvedSet
<8>> &Lookups
) {
18442 // Find all of the associated namespaces and classes based on the
18443 // arguments we have.
18444 Sema::AssociatedNamespaceSet AssociatedNamespaces
;
18445 Sema::AssociatedClassSet AssociatedClasses
;
18446 OpaqueValueExpr
OVE(Loc
, Ty
, VK_LValue
);
18447 SemaRef
.FindAssociatedClassesAndNamespaces(Loc
, &OVE
, AssociatedNamespaces
,
18448 AssociatedClasses
);
18450 // C++ [basic.lookup.argdep]p3:
18451 // Let X be the lookup set produced by unqualified lookup (3.4.1)
18452 // and let Y be the lookup set produced by argument dependent
18453 // lookup (defined as follows). If X contains [...] then Y is
18454 // empty. Otherwise Y is the set of declarations found in the
18455 // namespaces associated with the argument types as described
18456 // below. The set of declarations found by the lookup of the name
18457 // is the union of X and Y.
18459 // Here, we compute Y and add its members to the overloaded
18461 for (auto *NS
: AssociatedNamespaces
) {
18462 // When considering an associated namespace, the lookup is the
18463 // same as the lookup performed when the associated namespace is
18464 // used as a qualifier (3.4.3.2) except that:
18466 // -- Any using-directives in the associated namespace are
18469 // -- Any namespace-scope friend functions declared in
18470 // associated classes are visible within their respective
18471 // namespaces even if they are not visible during an ordinary
18473 DeclContext::lookup_result R
= NS
->lookup(Id
.getName());
18474 for (auto *D
: R
) {
18475 auto *Underlying
= D
;
18476 if (auto *USD
= dyn_cast
<UsingShadowDecl
>(D
))
18477 Underlying
= USD
->getTargetDecl();
18479 if (!isa
<OMPDeclareReductionDecl
>(Underlying
) &&
18480 !isa
<OMPDeclareMapperDecl
>(Underlying
))
18483 if (!SemaRef
.isVisible(D
)) {
18484 D
= findAcceptableDecl(SemaRef
, D
);
18487 if (auto *USD
= dyn_cast
<UsingShadowDecl
>(D
))
18488 Underlying
= USD
->getTargetDecl();
18490 Lookups
.emplace_back();
18491 Lookups
.back().addDecl(Underlying
);
18497 buildDeclareReductionRef(Sema
&SemaRef
, SourceLocation Loc
, SourceRange Range
,
18498 Scope
*S
, CXXScopeSpec
&ReductionIdScopeSpec
,
18499 const DeclarationNameInfo
&ReductionId
, QualType Ty
,
18500 CXXCastPath
&BasePath
, Expr
*UnresolvedReduction
) {
18501 if (ReductionIdScopeSpec
.isInvalid())
18502 return ExprError();
18503 SmallVector
<UnresolvedSet
<8>, 4> Lookups
;
18505 LookupResult
Lookup(SemaRef
, ReductionId
, Sema::LookupOMPReductionName
);
18506 Lookup
.suppressDiagnostics();
18507 while (S
&& SemaRef
.LookupParsedName(Lookup
, S
, &ReductionIdScopeSpec
)) {
18508 NamedDecl
*D
= Lookup
.getRepresentativeDecl();
18510 S
= S
->getParent();
18511 } while (S
&& !S
->isDeclScope(D
));
18513 S
= S
->getParent();
18514 Lookups
.emplace_back();
18515 Lookups
.back().append(Lookup
.begin(), Lookup
.end());
18518 } else if (auto *ULE
=
18519 cast_or_null
<UnresolvedLookupExpr
>(UnresolvedReduction
)) {
18520 Lookups
.push_back(UnresolvedSet
<8>());
18521 Decl
*PrevD
= nullptr;
18522 for (NamedDecl
*D
: ULE
->decls()) {
18524 Lookups
.push_back(UnresolvedSet
<8>());
18525 else if (auto *DRD
= dyn_cast
<OMPDeclareReductionDecl
>(D
))
18526 Lookups
.back().addDecl(DRD
);
18530 if (SemaRef
.CurContext
->isDependentContext() || Ty
->isDependentType() ||
18531 Ty
->isInstantiationDependentType() ||
18532 Ty
->containsUnexpandedParameterPack() ||
18533 filterLookupForUDReductionAndMapper
<bool>(Lookups
, [](ValueDecl
*D
) {
18534 return !D
->isInvalidDecl() &&
18535 (D
->getType()->isDependentType() ||
18536 D
->getType()->isInstantiationDependentType() ||
18537 D
->getType()->containsUnexpandedParameterPack());
18539 UnresolvedSet
<8> ResSet
;
18540 for (const UnresolvedSet
<8> &Set
: Lookups
) {
18543 ResSet
.append(Set
.begin(), Set
.end());
18544 // The last item marks the end of all declarations at the specified scope.
18545 ResSet
.addDecl(Set
[Set
.size() - 1]);
18547 return UnresolvedLookupExpr::Create(
18548 SemaRef
.Context
, /*NamingClass=*/nullptr,
18549 ReductionIdScopeSpec
.getWithLocInContext(SemaRef
.Context
), ReductionId
,
18550 /*ADL=*/true, /*Overloaded=*/true, ResSet
.begin(), ResSet
.end());
18552 // Lookup inside the classes.
18553 // C++ [over.match.oper]p3:
18554 // For a unary operator @ with an operand of a type whose
18555 // cv-unqualified version is T1, and for a binary operator @ with
18556 // a left operand of a type whose cv-unqualified version is T1 and
18557 // a right operand of a type whose cv-unqualified version is T2,
18558 // three sets of candidate functions, designated member
18559 // candidates, non-member candidates and built-in candidates, are
18560 // constructed as follows:
18561 // -- If T1 is a complete class type or a class currently being
18562 // defined, the set of member candidates is the result of the
18563 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18564 // the set of member candidates is empty.
18565 LookupResult
Lookup(SemaRef
, ReductionId
, Sema::LookupOMPReductionName
);
18566 Lookup
.suppressDiagnostics();
18567 if (const auto *TyRec
= Ty
->getAs
<RecordType
>()) {
18568 // Complete the type if it can be completed.
18569 // If the type is neither complete nor being defined, bail out now.
18570 if (SemaRef
.isCompleteType(Loc
, Ty
) || TyRec
->isBeingDefined() ||
18571 TyRec
->getDecl()->getDefinition()) {
18573 SemaRef
.LookupQualifiedName(Lookup
, TyRec
->getDecl());
18574 if (Lookup
.empty()) {
18575 Lookups
.emplace_back();
18576 Lookups
.back().append(Lookup
.begin(), Lookup
.end());
18581 if (SemaRef
.getLangOpts().CPlusPlus
)
18582 argumentDependentLookup(SemaRef
, ReductionId
, Loc
, Ty
, Lookups
);
18583 if (auto *VD
= filterLookupForUDReductionAndMapper
<ValueDecl
*>(
18584 Lookups
, [&SemaRef
, Ty
](ValueDecl
*D
) -> ValueDecl
* {
18585 if (!D
->isInvalidDecl() &&
18586 SemaRef
.Context
.hasSameType(D
->getType(), Ty
))
18590 return SemaRef
.BuildDeclRefExpr(VD
, VD
->getType().getNonReferenceType(),
18592 if (SemaRef
.getLangOpts().CPlusPlus
) {
18593 if (auto *VD
= filterLookupForUDReductionAndMapper
<ValueDecl
*>(
18594 Lookups
, [&SemaRef
, Ty
, Loc
](ValueDecl
*D
) -> ValueDecl
* {
18595 if (!D
->isInvalidDecl() &&
18596 SemaRef
.IsDerivedFrom(Loc
, Ty
, D
->getType()) &&
18597 !Ty
.isMoreQualifiedThan(D
->getType()))
18601 CXXBasePaths
Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18602 /*DetectVirtual=*/false);
18603 if (SemaRef
.IsDerivedFrom(Loc
, Ty
, VD
->getType(), Paths
)) {
18604 if (!Paths
.isAmbiguous(SemaRef
.Context
.getCanonicalType(
18605 VD
->getType().getUnqualifiedType()))) {
18606 if (SemaRef
.CheckBaseClassAccess(
18607 Loc
, VD
->getType(), Ty
, Paths
.front(),
18608 /*DiagID=*/0) != Sema::AR_inaccessible
) {
18609 SemaRef
.BuildBasePathArray(Paths
, BasePath
);
18610 return SemaRef
.BuildDeclRefExpr(
18611 VD
, VD
->getType().getNonReferenceType(), VK_LValue
, Loc
);
18617 if (ReductionIdScopeSpec
.isSet()) {
18618 SemaRef
.Diag(Loc
, diag::err_omp_not_resolved_reduction_identifier
)
18620 return ExprError();
18622 return ExprEmpty();
18626 /// Data for the reduction-based clauses.
18627 struct ReductionData
{
18628 /// List of original reduction items.
18629 SmallVector
<Expr
*, 8> Vars
;
18630 /// List of private copies of the reduction items.
18631 SmallVector
<Expr
*, 8> Privates
;
18632 /// LHS expressions for the reduction_op expressions.
18633 SmallVector
<Expr
*, 8> LHSs
;
18634 /// RHS expressions for the reduction_op expressions.
18635 SmallVector
<Expr
*, 8> RHSs
;
18636 /// Reduction operation expression.
18637 SmallVector
<Expr
*, 8> ReductionOps
;
18638 /// inscan copy operation expressions.
18639 SmallVector
<Expr
*, 8> InscanCopyOps
;
18640 /// inscan copy temp array expressions for prefix sums.
18641 SmallVector
<Expr
*, 8> InscanCopyArrayTemps
;
18642 /// inscan copy temp array element expressions for prefix sums.
18643 SmallVector
<Expr
*, 8> InscanCopyArrayElems
;
18644 /// Taskgroup descriptors for the corresponding reduction items in
18645 /// in_reduction clauses.
18646 SmallVector
<Expr
*, 8> TaskgroupDescriptors
;
18647 /// List of captures for clause.
18648 SmallVector
<Decl
*, 4> ExprCaptures
;
18649 /// List of postupdate expressions.
18650 SmallVector
<Expr
*, 4> ExprPostUpdates
;
18651 /// Reduction modifier.
18652 unsigned RedModifier
= 0;
18653 ReductionData() = delete;
18654 /// Reserves required memory for the reduction data.
18655 ReductionData(unsigned Size
, unsigned Modifier
= 0) : RedModifier(Modifier
) {
18656 Vars
.reserve(Size
);
18657 Privates
.reserve(Size
);
18658 LHSs
.reserve(Size
);
18659 RHSs
.reserve(Size
);
18660 ReductionOps
.reserve(Size
);
18661 if (RedModifier
== OMPC_REDUCTION_inscan
) {
18662 InscanCopyOps
.reserve(Size
);
18663 InscanCopyArrayTemps
.reserve(Size
);
18664 InscanCopyArrayElems
.reserve(Size
);
18666 TaskgroupDescriptors
.reserve(Size
);
18667 ExprCaptures
.reserve(Size
);
18668 ExprPostUpdates
.reserve(Size
);
18670 /// Stores reduction item and reduction operation only (required for dependent
18671 /// reduction item).
18672 void push(Expr
*Item
, Expr
*ReductionOp
) {
18673 Vars
.emplace_back(Item
);
18674 Privates
.emplace_back(nullptr);
18675 LHSs
.emplace_back(nullptr);
18676 RHSs
.emplace_back(nullptr);
18677 ReductionOps
.emplace_back(ReductionOp
);
18678 TaskgroupDescriptors
.emplace_back(nullptr);
18679 if (RedModifier
== OMPC_REDUCTION_inscan
) {
18680 InscanCopyOps
.push_back(nullptr);
18681 InscanCopyArrayTemps
.push_back(nullptr);
18682 InscanCopyArrayElems
.push_back(nullptr);
18685 /// Stores reduction data.
18686 void push(Expr
*Item
, Expr
*Private
, Expr
*LHS
, Expr
*RHS
, Expr
*ReductionOp
,
18687 Expr
*TaskgroupDescriptor
, Expr
*CopyOp
, Expr
*CopyArrayTemp
,
18688 Expr
*CopyArrayElem
) {
18689 Vars
.emplace_back(Item
);
18690 Privates
.emplace_back(Private
);
18691 LHSs
.emplace_back(LHS
);
18692 RHSs
.emplace_back(RHS
);
18693 ReductionOps
.emplace_back(ReductionOp
);
18694 TaskgroupDescriptors
.emplace_back(TaskgroupDescriptor
);
18695 if (RedModifier
== OMPC_REDUCTION_inscan
) {
18696 InscanCopyOps
.push_back(CopyOp
);
18697 InscanCopyArrayTemps
.push_back(CopyArrayTemp
);
18698 InscanCopyArrayElems
.push_back(CopyArrayElem
);
18700 assert(CopyOp
== nullptr && CopyArrayTemp
== nullptr &&
18701 CopyArrayElem
== nullptr &&
18702 "Copy operation must be used for inscan reductions only.");
18708 static bool checkOMPArraySectionConstantForReduction(
18709 ASTContext
&Context
, const OMPArraySectionExpr
*OASE
, bool &SingleElement
,
18710 SmallVectorImpl
<llvm::APSInt
> &ArraySizes
) {
18711 const Expr
*Length
= OASE
->getLength();
18712 if (Length
== nullptr) {
18713 // For array sections of the form [1:] or [:], we would need to analyze
18714 // the lower bound...
18715 if (OASE
->getColonLocFirst().isValid())
18718 // This is an array subscript which has implicit length 1!
18719 SingleElement
= true;
18720 ArraySizes
.push_back(llvm::APSInt::get(1));
18722 Expr::EvalResult Result
;
18723 if (!Length
->EvaluateAsInt(Result
, Context
))
18726 llvm::APSInt ConstantLengthValue
= Result
.Val
.getInt();
18727 SingleElement
= (ConstantLengthValue
.getSExtValue() == 1);
18728 ArraySizes
.push_back(ConstantLengthValue
);
18731 // Get the base of this array section and walk up from there.
18732 const Expr
*Base
= OASE
->getBase()->IgnoreParenImpCasts();
18734 // We require length = 1 for all array sections except the right-most to
18735 // guarantee that the memory region is contiguous and has no holes in it.
18736 while (const auto *TempOASE
= dyn_cast
<OMPArraySectionExpr
>(Base
)) {
18737 Length
= TempOASE
->getLength();
18738 if (Length
== nullptr) {
18739 // For array sections of the form [1:] or [:], we would need to analyze
18740 // the lower bound...
18741 if (OASE
->getColonLocFirst().isValid())
18744 // This is an array subscript which has implicit length 1!
18745 ArraySizes
.push_back(llvm::APSInt::get(1));
18747 Expr::EvalResult Result
;
18748 if (!Length
->EvaluateAsInt(Result
, Context
))
18751 llvm::APSInt ConstantLengthValue
= Result
.Val
.getInt();
18752 if (ConstantLengthValue
.getSExtValue() != 1)
18755 ArraySizes
.push_back(ConstantLengthValue
);
18757 Base
= TempOASE
->getBase()->IgnoreParenImpCasts();
18760 // If we have a single element, we don't need to add the implicit lengths.
18761 if (!SingleElement
) {
18762 while (const auto *TempASE
= dyn_cast
<ArraySubscriptExpr
>(Base
)) {
18763 // Has implicit length 1!
18764 ArraySizes
.push_back(llvm::APSInt::get(1));
18765 Base
= TempASE
->getBase()->IgnoreParenImpCasts();
18769 // This array section can be privatized as a single value or as a constant
18774 static BinaryOperatorKind
18775 getRelatedCompoundReductionOp(BinaryOperatorKind BOK
) {
18777 return BO_AddAssign
;
18779 return BO_MulAssign
;
18781 return BO_AndAssign
;
18783 return BO_OrAssign
;
18785 return BO_XorAssign
;
18789 static bool actOnOMPReductionKindClause(
18790 Sema
&S
, DSAStackTy
*Stack
, OpenMPClauseKind ClauseKind
,
18791 ArrayRef
<Expr
*> VarList
, SourceLocation StartLoc
, SourceLocation LParenLoc
,
18792 SourceLocation ColonLoc
, SourceLocation EndLoc
,
18793 CXXScopeSpec
&ReductionIdScopeSpec
, const DeclarationNameInfo
&ReductionId
,
18794 ArrayRef
<Expr
*> UnresolvedReductions
, ReductionData
&RD
) {
18795 DeclarationName DN
= ReductionId
.getName();
18796 OverloadedOperatorKind OOK
= DN
.getCXXOverloadedOperator();
18797 BinaryOperatorKind BOK
= BO_Comma
;
18799 ASTContext
&Context
= S
.Context
;
18800 // OpenMP [2.14.3.6, reduction clause]
18802 // reduction-identifier is either an identifier or one of the following
18803 // operators: +, -, *, &, |, ^, && and ||
18805 // reduction-identifier is either an id-expression or one of the following
18806 // operators: +, -, *, &, |, ^, && and ||
18833 case OO_Array_Delete
:
18842 case OO_GreaterEqual
:
18844 case OO_MinusEqual
:
18846 case OO_SlashEqual
:
18847 case OO_PercentEqual
:
18848 case OO_CaretEqual
:
18852 case OO_GreaterGreater
:
18853 case OO_LessLessEqual
:
18854 case OO_GreaterGreaterEqual
:
18855 case OO_EqualEqual
:
18856 case OO_ExclaimEqual
:
18859 case OO_MinusMinus
:
18865 case OO_Conditional
:
18867 case NUM_OVERLOADED_OPERATORS
:
18868 llvm_unreachable("Unexpected reduction identifier");
18870 if (IdentifierInfo
*II
= DN
.getAsIdentifierInfo()) {
18871 if (II
->isStr("max"))
18873 else if (II
->isStr("min"))
18878 SourceRange ReductionIdRange
;
18879 if (ReductionIdScopeSpec
.isValid())
18880 ReductionIdRange
.setBegin(ReductionIdScopeSpec
.getBeginLoc());
18882 ReductionIdRange
.setBegin(ReductionId
.getBeginLoc());
18883 ReductionIdRange
.setEnd(ReductionId
.getEndLoc());
18885 auto IR
= UnresolvedReductions
.begin(), ER
= UnresolvedReductions
.end();
18886 bool FirstIter
= true;
18887 for (Expr
*RefExpr
: VarList
) {
18888 assert(RefExpr
&& "nullptr expr in OpenMP reduction clause.");
18889 // OpenMP [2.1, C/C++]
18890 // A list item is a variable or array section, subject to the restrictions
18891 // specified in Section 2.4 on page 42 and in each of the sections
18892 // describing clauses and directives for which a list appears.
18893 // OpenMP [2.14.3.3, Restrictions, p.1]
18894 // A variable that is part of another variable (as an array or
18895 // structure element) cannot appear in a private clause.
18896 if (!FirstIter
&& IR
!= ER
)
18899 SourceLocation ELoc
;
18900 SourceRange ERange
;
18901 Expr
*SimpleRefExpr
= RefExpr
;
18902 auto Res
= getPrivateItem(S
, SimpleRefExpr
, ELoc
, ERange
,
18903 /*AllowArraySection=*/true);
18905 // Try to find 'declare reduction' corresponding construct before using
18906 // builtin/overloaded operators.
18907 QualType Type
= Context
.DependentTy
;
18908 CXXCastPath BasePath
;
18909 ExprResult DeclareReductionRef
= buildDeclareReductionRef(
18910 S
, ELoc
, ERange
, Stack
->getCurScope(), ReductionIdScopeSpec
,
18911 ReductionId
, Type
, BasePath
, IR
== ER
? nullptr : *IR
);
18912 Expr
*ReductionOp
= nullptr;
18913 if (S
.CurContext
->isDependentContext() &&
18914 (DeclareReductionRef
.isUnset() ||
18915 isa
<UnresolvedLookupExpr
>(DeclareReductionRef
.get())))
18916 ReductionOp
= DeclareReductionRef
.get();
18917 // It will be analyzed later.
18918 RD
.push(RefExpr
, ReductionOp
);
18920 ValueDecl
*D
= Res
.first
;
18924 Expr
*TaskgroupDescriptor
= nullptr;
18926 auto *ASE
= dyn_cast
<ArraySubscriptExpr
>(RefExpr
->IgnoreParens());
18927 auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(RefExpr
->IgnoreParens());
18929 Type
= ASE
->getType().getNonReferenceType();
18931 QualType BaseType
=
18932 OMPArraySectionExpr::getBaseOriginalType(OASE
->getBase());
18933 if (const auto *ATy
= BaseType
->getAsArrayTypeUnsafe())
18934 Type
= ATy
->getElementType();
18936 Type
= BaseType
->getPointeeType();
18937 Type
= Type
.getNonReferenceType();
18939 Type
= Context
.getBaseElementType(D
->getType().getNonReferenceType());
18941 auto *VD
= dyn_cast
<VarDecl
>(D
);
18943 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18944 // A variable that appears in a private clause must not have an incomplete
18945 // type or a reference type.
18946 if (S
.RequireCompleteType(ELoc
, D
->getType(),
18947 diag::err_omp_reduction_incomplete_type
))
18949 // OpenMP [2.14.3.6, reduction clause, Restrictions]
18950 // A list item that appears in a reduction clause must not be
18951 // const-qualified.
18952 if (rejectConstNotMutableType(S
, D
, Type
, ClauseKind
, ELoc
,
18953 /*AcceptIfMutable*/ false, ASE
|| OASE
))
18956 OpenMPDirectiveKind CurrDir
= Stack
->getCurrentDirective();
18957 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18958 // If a list-item is a reference type then it must bind to the same object
18959 // for all threads of the team.
18960 if (!ASE
&& !OASE
) {
18962 VarDecl
*VDDef
= VD
->getDefinition();
18963 if (VD
->getType()->isReferenceType() && VDDef
&& VDDef
->hasInit()) {
18964 DSARefChecker
Check(Stack
);
18965 if (Check
.Visit(VDDef
->getInit())) {
18966 S
.Diag(ELoc
, diag::err_omp_reduction_ref_type_arg
)
18967 << getOpenMPClauseName(ClauseKind
) << ERange
;
18968 S
.Diag(VDDef
->getLocation(), diag::note_defined_here
) << VDDef
;
18974 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18976 // Variables with the predetermined data-sharing attributes may not be
18977 // listed in data-sharing attributes clauses, except for the cases
18978 // listed below. For these exceptions only, listing a predetermined
18979 // variable in a data-sharing attribute clause is allowed and overrides
18980 // the variable's predetermined data-sharing attributes.
18981 // OpenMP [2.14.3.6, Restrictions, p.3]
18982 // Any number of reduction clauses can be specified on the directive,
18983 // but a list item can appear only once in the reduction clauses for that
18985 DSAStackTy::DSAVarData DVar
= Stack
->getTopDSA(D
, /*FromParent=*/false);
18986 if (DVar
.CKind
== OMPC_reduction
) {
18987 S
.Diag(ELoc
, diag::err_omp_once_referenced
)
18988 << getOpenMPClauseName(ClauseKind
);
18990 S
.Diag(DVar
.RefExpr
->getExprLoc(), diag::note_omp_referenced
);
18993 if (DVar
.CKind
!= OMPC_unknown
) {
18994 S
.Diag(ELoc
, diag::err_omp_wrong_dsa
)
18995 << getOpenMPClauseName(DVar
.CKind
)
18996 << getOpenMPClauseName(OMPC_reduction
);
18997 reportOriginalDsa(S
, Stack
, D
, DVar
);
19001 // OpenMP [2.14.3.6, Restrictions, p.1]
19002 // A list item that appears in a reduction clause of a worksharing
19003 // construct must be shared in the parallel regions to which any of the
19004 // worksharing regions arising from the worksharing construct bind.
19005 if (isOpenMPWorksharingDirective(CurrDir
) &&
19006 !isOpenMPParallelDirective(CurrDir
) &&
19007 !isOpenMPTeamsDirective(CurrDir
)) {
19008 DVar
= Stack
->getImplicitDSA(D
, true);
19009 if (DVar
.CKind
!= OMPC_shared
) {
19010 S
.Diag(ELoc
, diag::err_omp_required_access
)
19011 << getOpenMPClauseName(OMPC_reduction
)
19012 << getOpenMPClauseName(OMPC_shared
);
19013 reportOriginalDsa(S
, Stack
, D
, DVar
);
19018 // Threadprivates cannot be shared between threads, so dignose if the base
19019 // is a threadprivate variable.
19020 DSAStackTy::DSAVarData DVar
= Stack
->getTopDSA(D
, /*FromParent=*/false);
19021 if (DVar
.CKind
== OMPC_threadprivate
) {
19022 S
.Diag(ELoc
, diag::err_omp_wrong_dsa
)
19023 << getOpenMPClauseName(DVar
.CKind
)
19024 << getOpenMPClauseName(OMPC_reduction
);
19025 reportOriginalDsa(S
, Stack
, D
, DVar
);
19030 // Try to find 'declare reduction' corresponding construct before using
19031 // builtin/overloaded operators.
19032 CXXCastPath BasePath
;
19033 ExprResult DeclareReductionRef
= buildDeclareReductionRef(
19034 S
, ELoc
, ERange
, Stack
->getCurScope(), ReductionIdScopeSpec
,
19035 ReductionId
, Type
, BasePath
, IR
== ER
? nullptr : *IR
);
19036 if (DeclareReductionRef
.isInvalid())
19038 if (S
.CurContext
->isDependentContext() &&
19039 (DeclareReductionRef
.isUnset() ||
19040 isa
<UnresolvedLookupExpr
>(DeclareReductionRef
.get()))) {
19041 RD
.push(RefExpr
, DeclareReductionRef
.get());
19044 if (BOK
== BO_Comma
&& DeclareReductionRef
.isUnset()) {
19045 // Not allowed reduction identifier is found.
19046 S
.Diag(ReductionId
.getBeginLoc(),
19047 diag::err_omp_unknown_reduction_identifier
)
19048 << Type
<< ReductionIdRange
;
19052 // OpenMP [2.14.3.6, reduction clause, Restrictions]
19053 // The type of a list item that appears in a reduction clause must be valid
19054 // for the reduction-identifier. For a max or min reduction in C, the type
19055 // of the list item must be an allowed arithmetic data type: char, int,
19056 // float, double, or _Bool, possibly modified with long, short, signed, or
19057 // unsigned. For a max or min reduction in C++, the type of the list item
19058 // must be an allowed arithmetic data type: char, wchar_t, int, float,
19059 // double, or bool, possibly modified with long, short, signed, or unsigned.
19060 if (DeclareReductionRef
.isUnset()) {
19061 if ((BOK
== BO_GT
|| BOK
== BO_LT
) &&
19062 !(Type
->isScalarType() ||
19063 (S
.getLangOpts().CPlusPlus
&& Type
->isArithmeticType()))) {
19064 S
.Diag(ELoc
, diag::err_omp_clause_not_arithmetic_type_arg
)
19065 << getOpenMPClauseName(ClauseKind
) << S
.getLangOpts().CPlusPlus
;
19066 if (!ASE
&& !OASE
) {
19067 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
19068 VarDecl::DeclarationOnly
;
19069 S
.Diag(D
->getLocation(),
19070 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
19075 if ((BOK
== BO_OrAssign
|| BOK
== BO_AndAssign
|| BOK
== BO_XorAssign
) &&
19076 !S
.getLangOpts().CPlusPlus
&& Type
->isFloatingType()) {
19077 S
.Diag(ELoc
, diag::err_omp_clause_floating_type_arg
)
19078 << getOpenMPClauseName(ClauseKind
);
19079 if (!ASE
&& !OASE
) {
19080 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
19081 VarDecl::DeclarationOnly
;
19082 S
.Diag(D
->getLocation(),
19083 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
19090 Type
= Type
.getNonLValueExprType(Context
).getUnqualifiedType();
19091 VarDecl
*LHSVD
= buildVarDecl(S
, ELoc
, Type
, ".reduction.lhs",
19092 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
19093 VarDecl
*RHSVD
= buildVarDecl(S
, ELoc
, Type
, D
->getName(),
19094 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
19095 QualType PrivateTy
= Type
;
19097 // Try if we can determine constant lengths for all array sections and avoid
19099 bool ConstantLengthOASE
= false;
19101 bool SingleElement
;
19102 llvm::SmallVector
<llvm::APSInt
, 4> ArraySizes
;
19103 ConstantLengthOASE
= checkOMPArraySectionConstantForReduction(
19104 Context
, OASE
, SingleElement
, ArraySizes
);
19106 // If we don't have a single element, we must emit a constant array type.
19107 if (ConstantLengthOASE
&& !SingleElement
) {
19108 for (llvm::APSInt
&Size
: ArraySizes
)
19109 PrivateTy
= Context
.getConstantArrayType(PrivateTy
, Size
, nullptr,
19111 /*IndexTypeQuals=*/0);
19115 if ((OASE
&& !ConstantLengthOASE
) ||
19117 D
->getType().getNonReferenceType()->isVariablyModifiedType())) {
19118 if (!Context
.getTargetInfo().isVLASupported()) {
19119 if (isOpenMPTargetExecutionDirective(Stack
->getCurrentDirective())) {
19120 S
.Diag(ELoc
, diag::err_omp_reduction_vla_unsupported
) << !!OASE
;
19121 S
.Diag(ELoc
, diag::note_vla_unsupported
);
19124 S
.targetDiag(ELoc
, diag::err_omp_reduction_vla_unsupported
) << !!OASE
;
19125 S
.targetDiag(ELoc
, diag::note_vla_unsupported
);
19128 // For arrays/array sections only:
19129 // Create pseudo array type for private copy. The size for this array will
19130 // be generated during codegen.
19131 // For array subscripts or single variables Private Ty is the same as Type
19132 // (type of the variable or single array element).
19133 PrivateTy
= Context
.getVariableArrayType(
19136 OpaqueValueExpr(ELoc
, Context
.getSizeType(), VK_PRValue
),
19137 ArrayType::Normal
, /*IndexTypeQuals=*/0, SourceRange());
19138 } else if (!ASE
&& !OASE
&&
19139 Context
.getAsArrayType(D
->getType().getNonReferenceType())) {
19140 PrivateTy
= D
->getType().getNonReferenceType();
19143 VarDecl
*PrivateVD
=
19144 buildVarDecl(S
, ELoc
, PrivateTy
, D
->getName(),
19145 D
->hasAttrs() ? &D
->getAttrs() : nullptr,
19146 VD
? cast
<DeclRefExpr
>(SimpleRefExpr
) : nullptr);
19147 // Add initializer for private variable.
19148 Expr
*Init
= nullptr;
19149 DeclRefExpr
*LHSDRE
= buildDeclRefExpr(S
, LHSVD
, Type
, ELoc
);
19150 DeclRefExpr
*RHSDRE
= buildDeclRefExpr(S
, RHSVD
, Type
, ELoc
);
19151 if (DeclareReductionRef
.isUsable()) {
19152 auto *DRDRef
= DeclareReductionRef
.getAs
<DeclRefExpr
>();
19153 auto *DRD
= cast
<OMPDeclareReductionDecl
>(DRDRef
->getDecl());
19154 if (DRD
->getInitializer()) {
19156 RHSVD
->setInit(DRDRef
);
19157 RHSVD
->setInitStyle(VarDecl::CallInit
);
19165 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19166 if (Type
->isScalarType() || Type
->isAnyComplexType())
19167 Init
= S
.ActOnIntegerConstant(ELoc
, /*Val=*/0).get();
19171 if (Type
->isScalarType() || Type
->isAnyComplexType()) {
19172 // '*' and '&&' reduction ops - initializer is '1'.
19173 Init
= S
.ActOnIntegerConstant(ELoc
, /*Val=*/1).get();
19177 // '&' reduction op - initializer is '~0'.
19178 QualType OrigType
= Type
;
19179 if (auto *ComplexTy
= OrigType
->getAs
<ComplexType
>())
19180 Type
= ComplexTy
->getElementType();
19181 if (Type
->isRealFloatingType()) {
19182 llvm::APFloat InitValue
= llvm::APFloat::getAllOnesValue(
19183 Context
.getFloatTypeSemantics(Type
));
19184 Init
= FloatingLiteral::Create(Context
, InitValue
, /*isexact=*/true,
19186 } else if (Type
->isScalarType()) {
19187 uint64_t Size
= Context
.getTypeSize(Type
);
19188 QualType IntTy
= Context
.getIntTypeForBitwidth(Size
, /*Signed=*/0);
19189 llvm::APInt InitValue
= llvm::APInt::getAllOnes(Size
);
19190 Init
= IntegerLiteral::Create(Context
, InitValue
, IntTy
, ELoc
);
19192 if (Init
&& OrigType
->isAnyComplexType()) {
19193 // Init = 0xFFFF + 0xFFFFi;
19194 auto *Im
= new (Context
) ImaginaryLiteral(Init
, OrigType
);
19195 Init
= S
.CreateBuiltinBinOp(ELoc
, BO_Add
, Init
, Im
).get();
19202 // 'min' reduction op - initializer is 'Largest representable number in
19203 // the reduction list item type'.
19204 // 'max' reduction op - initializer is 'Least representable number in
19205 // the reduction list item type'.
19206 if (Type
->isIntegerType() || Type
->isPointerType()) {
19207 bool IsSigned
= Type
->hasSignedIntegerRepresentation();
19208 uint64_t Size
= Context
.getTypeSize(Type
);
19210 Context
.getIntTypeForBitwidth(Size
, /*Signed=*/IsSigned
);
19211 llvm::APInt InitValue
=
19212 (BOK
!= BO_LT
) ? IsSigned
? llvm::APInt::getSignedMinValue(Size
)
19213 : llvm::APInt::getMinValue(Size
)
19214 : IsSigned
? llvm::APInt::getSignedMaxValue(Size
)
19215 : llvm::APInt::getMaxValue(Size
);
19216 Init
= IntegerLiteral::Create(Context
, InitValue
, IntTy
, ELoc
);
19217 if (Type
->isPointerType()) {
19218 // Cast to pointer type.
19219 ExprResult CastExpr
= S
.BuildCStyleCastExpr(
19220 ELoc
, Context
.getTrivialTypeSourceInfo(Type
, ELoc
), ELoc
, Init
);
19221 if (CastExpr
.isInvalid())
19223 Init
= CastExpr
.get();
19225 } else if (Type
->isRealFloatingType()) {
19226 llvm::APFloat InitValue
= llvm::APFloat::getLargest(
19227 Context
.getFloatTypeSemantics(Type
), BOK
!= BO_LT
);
19228 Init
= FloatingLiteral::Create(Context
, InitValue
, /*isexact=*/true,
19257 llvm_unreachable("Unexpected reduction operation");
19260 if (Init
&& DeclareReductionRef
.isUnset()) {
19261 S
.AddInitializerToDecl(RHSVD
, Init
, /*DirectInit=*/false);
19262 // Store initializer for single element in private copy. Will be used
19264 PrivateVD
->setInit(RHSVD
->getInit());
19265 PrivateVD
->setInitStyle(RHSVD
->getInitStyle());
19266 } else if (!Init
) {
19267 S
.ActOnUninitializedDecl(RHSVD
);
19268 // Store initializer for single element in private copy. Will be used
19270 PrivateVD
->setInit(RHSVD
->getInit());
19271 PrivateVD
->setInitStyle(RHSVD
->getInitStyle());
19273 if (RHSVD
->isInvalidDecl())
19275 if (!RHSVD
->hasInit() && DeclareReductionRef
.isUnset()) {
19276 S
.Diag(ELoc
, diag::err_omp_reduction_id_not_compatible
)
19277 << Type
<< ReductionIdRange
;
19278 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
19279 VarDecl::DeclarationOnly
;
19280 S
.Diag(D
->getLocation(),
19281 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
19285 DeclRefExpr
*PrivateDRE
= buildDeclRefExpr(S
, PrivateVD
, PrivateTy
, ELoc
);
19286 ExprResult ReductionOp
;
19287 if (DeclareReductionRef
.isUsable()) {
19288 QualType RedTy
= DeclareReductionRef
.get()->getType();
19289 QualType PtrRedTy
= Context
.getPointerType(RedTy
);
19290 ExprResult LHS
= S
.CreateBuiltinUnaryOp(ELoc
, UO_AddrOf
, LHSDRE
);
19291 ExprResult RHS
= S
.CreateBuiltinUnaryOp(ELoc
, UO_AddrOf
, RHSDRE
);
19292 if (!BasePath
.empty()) {
19293 LHS
= S
.DefaultLvalueConversion(LHS
.get());
19294 RHS
= S
.DefaultLvalueConversion(RHS
.get());
19295 LHS
= ImplicitCastExpr::Create(
19296 Context
, PtrRedTy
, CK_UncheckedDerivedToBase
, LHS
.get(), &BasePath
,
19297 LHS
.get()->getValueKind(), FPOptionsOverride());
19298 RHS
= ImplicitCastExpr::Create(
19299 Context
, PtrRedTy
, CK_UncheckedDerivedToBase
, RHS
.get(), &BasePath
,
19300 RHS
.get()->getValueKind(), FPOptionsOverride());
19302 FunctionProtoType::ExtProtoInfo EPI
;
19303 QualType Params
[] = {PtrRedTy
, PtrRedTy
};
19304 QualType FnTy
= Context
.getFunctionType(Context
.VoidTy
, Params
, EPI
);
19305 auto *OVE
= new (Context
) OpaqueValueExpr(
19306 ELoc
, Context
.getPointerType(FnTy
), VK_PRValue
, OK_Ordinary
,
19307 S
.DefaultLvalueConversion(DeclareReductionRef
.get()).get());
19308 Expr
*Args
[] = {LHS
.get(), RHS
.get()};
19310 CallExpr::Create(Context
, OVE
, Args
, Context
.VoidTy
, VK_PRValue
, ELoc
,
19311 S
.CurFPFeatureOverrides());
19313 BinaryOperatorKind CombBOK
= getRelatedCompoundReductionOp(BOK
);
19314 if (Type
->isRecordType() && CombBOK
!= BOK
) {
19315 Sema::TentativeAnalysisScope
Trap(S
);
19317 S
.BuildBinOp(Stack
->getCurScope(), ReductionId
.getBeginLoc(),
19318 CombBOK
, LHSDRE
, RHSDRE
);
19320 if (!ReductionOp
.isUsable()) {
19322 S
.BuildBinOp(Stack
->getCurScope(), ReductionId
.getBeginLoc(), BOK
,
19324 if (ReductionOp
.isUsable()) {
19325 if (BOK
!= BO_LT
&& BOK
!= BO_GT
) {
19327 S
.BuildBinOp(Stack
->getCurScope(), ReductionId
.getBeginLoc(),
19328 BO_Assign
, LHSDRE
, ReductionOp
.get());
19330 auto *ConditionalOp
= new (Context
)
19331 ConditionalOperator(ReductionOp
.get(), ELoc
, LHSDRE
, ELoc
,
19332 RHSDRE
, Type
, VK_LValue
, OK_Ordinary
);
19334 S
.BuildBinOp(Stack
->getCurScope(), ReductionId
.getBeginLoc(),
19335 BO_Assign
, LHSDRE
, ConditionalOp
);
19339 if (ReductionOp
.isUsable())
19340 ReductionOp
= S
.ActOnFinishFullExpr(ReductionOp
.get(),
19341 /*DiscardedValue*/ false);
19342 if (!ReductionOp
.isUsable())
19346 // Add copy operations for inscan reductions.
19348 ExprResult CopyOpRes
, TempArrayRes
, TempArrayElem
;
19349 if (ClauseKind
== OMPC_reduction
&&
19350 RD
.RedModifier
== OMPC_REDUCTION_inscan
) {
19351 ExprResult RHS
= S
.DefaultLvalueConversion(RHSDRE
);
19352 CopyOpRes
= S
.BuildBinOp(Stack
->getCurScope(), ELoc
, BO_Assign
, LHSDRE
,
19354 if (!CopyOpRes
.isUsable())
19357 S
.ActOnFinishFullExpr(CopyOpRes
.get(), /*DiscardedValue=*/true);
19358 if (!CopyOpRes
.isUsable())
19360 // For simd directive and simd-based directives in simd mode no need to
19361 // construct temp array, need just a single temp element.
19362 if (Stack
->getCurrentDirective() == OMPD_simd
||
19363 (S
.getLangOpts().OpenMPSimd
&&
19364 isOpenMPSimdDirective(Stack
->getCurrentDirective()))) {
19365 VarDecl
*TempArrayVD
=
19366 buildVarDecl(S
, ELoc
, PrivateTy
, D
->getName(),
19367 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
19368 // Add a constructor to the temp decl.
19369 S
.ActOnUninitializedDecl(TempArrayVD
);
19370 TempArrayRes
= buildDeclRefExpr(S
, TempArrayVD
, PrivateTy
, ELoc
);
19372 // Build temp array for prefix sum.
19373 auto *Dim
= new (S
.Context
)
19374 OpaqueValueExpr(ELoc
, S
.Context
.getSizeType(), VK_PRValue
);
19376 S
.Context
.getVariableArrayType(PrivateTy
, Dim
, ArrayType::Normal
,
19377 /*IndexTypeQuals=*/0, {ELoc
, ELoc
});
19378 VarDecl
*TempArrayVD
=
19379 buildVarDecl(S
, ELoc
, ArrayTy
, D
->getName(),
19380 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
19381 // Add a constructor to the temp decl.
19382 S
.ActOnUninitializedDecl(TempArrayVD
);
19383 TempArrayRes
= buildDeclRefExpr(S
, TempArrayVD
, ArrayTy
, ELoc
);
19385 S
.DefaultFunctionArrayLvalueConversion(TempArrayRes
.get());
19386 auto *Idx
= new (S
.Context
)
19387 OpaqueValueExpr(ELoc
, S
.Context
.getSizeType(), VK_PRValue
);
19388 TempArrayElem
= S
.CreateBuiltinArraySubscriptExpr(TempArrayElem
.get(),
19393 // OpenMP [2.15.4.6, Restrictions, p.2]
19394 // A list item that appears in an in_reduction clause of a task construct
19395 // must appear in a task_reduction clause of a construct associated with a
19396 // taskgroup region that includes the participating task in its taskgroup
19397 // set. The construct associated with the innermost region that meets this
19398 // condition must specify the same reduction-identifier as the in_reduction
19400 if (ClauseKind
== OMPC_in_reduction
) {
19401 SourceRange ParentSR
;
19402 BinaryOperatorKind ParentBOK
;
19403 const Expr
*ParentReductionOp
= nullptr;
19404 Expr
*ParentBOKTD
= nullptr, *ParentReductionOpTD
= nullptr;
19405 DSAStackTy::DSAVarData ParentBOKDSA
=
19406 Stack
->getTopMostTaskgroupReductionData(D
, ParentSR
, ParentBOK
,
19408 DSAStackTy::DSAVarData ParentReductionOpDSA
=
19409 Stack
->getTopMostTaskgroupReductionData(
19410 D
, ParentSR
, ParentReductionOp
, ParentReductionOpTD
);
19411 bool IsParentBOK
= ParentBOKDSA
.DKind
!= OMPD_unknown
;
19412 bool IsParentReductionOp
= ParentReductionOpDSA
.DKind
!= OMPD_unknown
;
19413 if ((DeclareReductionRef
.isUnset() && IsParentReductionOp
) ||
19414 (DeclareReductionRef
.isUsable() && IsParentBOK
) ||
19415 (IsParentBOK
&& BOK
!= ParentBOK
) || IsParentReductionOp
) {
19416 bool EmitError
= true;
19417 if (IsParentReductionOp
&& DeclareReductionRef
.isUsable()) {
19418 llvm::FoldingSetNodeID RedId
, ParentRedId
;
19419 ParentReductionOp
->Profile(ParentRedId
, Context
, /*Canonical=*/true);
19420 DeclareReductionRef
.get()->Profile(RedId
, Context
,
19421 /*Canonical=*/true);
19422 EmitError
= RedId
!= ParentRedId
;
19425 S
.Diag(ReductionId
.getBeginLoc(),
19426 diag::err_omp_reduction_identifier_mismatch
)
19427 << ReductionIdRange
<< RefExpr
->getSourceRange();
19428 S
.Diag(ParentSR
.getBegin(),
19429 diag::note_omp_previous_reduction_identifier
)
19431 << (IsParentBOK
? ParentBOKDSA
.RefExpr
19432 : ParentReductionOpDSA
.RefExpr
)
19433 ->getSourceRange();
19437 TaskgroupDescriptor
= IsParentBOK
? ParentBOKTD
: ParentReductionOpTD
;
19440 DeclRefExpr
*Ref
= nullptr;
19441 Expr
*VarsExpr
= RefExpr
->IgnoreParens();
19442 if (!VD
&& !S
.CurContext
->isDependentContext()) {
19444 TransformExprToCaptures
RebuildToCapture(S
, D
);
19446 RebuildToCapture
.TransformExpr(RefExpr
->IgnoreParens()).get();
19447 Ref
= RebuildToCapture
.getCapturedExpr();
19449 VarsExpr
= Ref
= buildCapture(S
, D
, SimpleRefExpr
, /*WithInit=*/false);
19451 if (!S
.isOpenMPCapturedDecl(D
)) {
19452 RD
.ExprCaptures
.emplace_back(Ref
->getDecl());
19453 if (Ref
->getDecl()->hasAttr
<OMPCaptureNoInitAttr
>()) {
19454 ExprResult RefRes
= S
.DefaultLvalueConversion(Ref
);
19455 if (!RefRes
.isUsable())
19457 ExprResult PostUpdateRes
=
19458 S
.BuildBinOp(Stack
->getCurScope(), ELoc
, BO_Assign
, SimpleRefExpr
,
19460 if (!PostUpdateRes
.isUsable())
19462 if (isOpenMPTaskingDirective(Stack
->getCurrentDirective()) ||
19463 Stack
->getCurrentDirective() == OMPD_taskgroup
) {
19464 S
.Diag(RefExpr
->getExprLoc(),
19465 diag::err_omp_reduction_non_addressable_expression
)
19466 << RefExpr
->getSourceRange();
19469 RD
.ExprPostUpdates
.emplace_back(
19470 S
.IgnoredValueConversions(PostUpdateRes
.get()).get());
19474 // All reduction items are still marked as reduction (to do not increase
19475 // code base size).
19476 unsigned Modifier
= RD
.RedModifier
;
19477 // Consider task_reductions as reductions with task modifier. Required for
19478 // correct analysis of in_reduction clauses.
19479 if (CurrDir
== OMPD_taskgroup
&& ClauseKind
== OMPC_task_reduction
)
19480 Modifier
= OMPC_REDUCTION_task
;
19481 Stack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_reduction
, Ref
, Modifier
,
19483 if (Modifier
== OMPC_REDUCTION_task
&&
19484 (CurrDir
== OMPD_taskgroup
||
19485 ((isOpenMPParallelDirective(CurrDir
) ||
19486 isOpenMPWorksharingDirective(CurrDir
)) &&
19487 !isOpenMPSimdDirective(CurrDir
)))) {
19488 if (DeclareReductionRef
.isUsable())
19489 Stack
->addTaskgroupReductionData(D
, ReductionIdRange
,
19490 DeclareReductionRef
.get());
19492 Stack
->addTaskgroupReductionData(D
, ReductionIdRange
, BOK
);
19494 RD
.push(VarsExpr
, PrivateDRE
, LHSDRE
, RHSDRE
, ReductionOp
.get(),
19495 TaskgroupDescriptor
, CopyOpRes
.get(), TempArrayRes
.get(),
19496 TempArrayElem
.get());
19498 return RD
.Vars
.empty();
19501 OMPClause
*Sema::ActOnOpenMPReductionClause(
19502 ArrayRef
<Expr
*> VarList
, OpenMPReductionClauseModifier Modifier
,
19503 SourceLocation StartLoc
, SourceLocation LParenLoc
,
19504 SourceLocation ModifierLoc
, SourceLocation ColonLoc
, SourceLocation EndLoc
,
19505 CXXScopeSpec
&ReductionIdScopeSpec
, const DeclarationNameInfo
&ReductionId
,
19506 ArrayRef
<Expr
*> UnresolvedReductions
) {
19507 if (ModifierLoc
.isValid() && Modifier
== OMPC_REDUCTION_unknown
) {
19508 Diag(LParenLoc
, diag::err_omp_unexpected_clause_value
)
19509 << getListOfPossibleValues(OMPC_reduction
, /*First=*/0,
19510 /*Last=*/OMPC_REDUCTION_unknown
)
19511 << getOpenMPClauseName(OMPC_reduction
);
19514 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19515 // A reduction clause with the inscan reduction-modifier may only appear on a
19516 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19517 // construct, a parallel worksharing-loop construct or a parallel
19518 // worksharing-loop SIMD construct.
19519 if (Modifier
== OMPC_REDUCTION_inscan
&&
19520 (DSAStack
->getCurrentDirective() != OMPD_for
&&
19521 DSAStack
->getCurrentDirective() != OMPD_for_simd
&&
19522 DSAStack
->getCurrentDirective() != OMPD_simd
&&
19523 DSAStack
->getCurrentDirective() != OMPD_parallel_for
&&
19524 DSAStack
->getCurrentDirective() != OMPD_parallel_for_simd
)) {
19525 Diag(ModifierLoc
, diag::err_omp_wrong_inscan_reduction
);
19529 ReductionData
RD(VarList
.size(), Modifier
);
19530 if (actOnOMPReductionKindClause(*this, DSAStack
, OMPC_reduction
, VarList
,
19531 StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
19532 ReductionIdScopeSpec
, ReductionId
,
19533 UnresolvedReductions
, RD
))
19536 return OMPReductionClause::Create(
19537 Context
, StartLoc
, LParenLoc
, ModifierLoc
, ColonLoc
, EndLoc
, Modifier
,
19538 RD
.Vars
, ReductionIdScopeSpec
.getWithLocInContext(Context
), ReductionId
,
19539 RD
.Privates
, RD
.LHSs
, RD
.RHSs
, RD
.ReductionOps
, RD
.InscanCopyOps
,
19540 RD
.InscanCopyArrayTemps
, RD
.InscanCopyArrayElems
,
19541 buildPreInits(Context
, RD
.ExprCaptures
),
19542 buildPostUpdate(*this, RD
.ExprPostUpdates
));
19545 OMPClause
*Sema::ActOnOpenMPTaskReductionClause(
19546 ArrayRef
<Expr
*> VarList
, SourceLocation StartLoc
, SourceLocation LParenLoc
,
19547 SourceLocation ColonLoc
, SourceLocation EndLoc
,
19548 CXXScopeSpec
&ReductionIdScopeSpec
, const DeclarationNameInfo
&ReductionId
,
19549 ArrayRef
<Expr
*> UnresolvedReductions
) {
19550 ReductionData
RD(VarList
.size());
19551 if (actOnOMPReductionKindClause(*this, DSAStack
, OMPC_task_reduction
, VarList
,
19552 StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
19553 ReductionIdScopeSpec
, ReductionId
,
19554 UnresolvedReductions
, RD
))
19557 return OMPTaskReductionClause::Create(
19558 Context
, StartLoc
, LParenLoc
, ColonLoc
, EndLoc
, RD
.Vars
,
19559 ReductionIdScopeSpec
.getWithLocInContext(Context
), ReductionId
,
19560 RD
.Privates
, RD
.LHSs
, RD
.RHSs
, RD
.ReductionOps
,
19561 buildPreInits(Context
, RD
.ExprCaptures
),
19562 buildPostUpdate(*this, RD
.ExprPostUpdates
));
19565 OMPClause
*Sema::ActOnOpenMPInReductionClause(
19566 ArrayRef
<Expr
*> VarList
, SourceLocation StartLoc
, SourceLocation LParenLoc
,
19567 SourceLocation ColonLoc
, SourceLocation EndLoc
,
19568 CXXScopeSpec
&ReductionIdScopeSpec
, const DeclarationNameInfo
&ReductionId
,
19569 ArrayRef
<Expr
*> UnresolvedReductions
) {
19570 ReductionData
RD(VarList
.size());
19571 if (actOnOMPReductionKindClause(*this, DSAStack
, OMPC_in_reduction
, VarList
,
19572 StartLoc
, LParenLoc
, ColonLoc
, EndLoc
,
19573 ReductionIdScopeSpec
, ReductionId
,
19574 UnresolvedReductions
, RD
))
19577 return OMPInReductionClause::Create(
19578 Context
, StartLoc
, LParenLoc
, ColonLoc
, EndLoc
, RD
.Vars
,
19579 ReductionIdScopeSpec
.getWithLocInContext(Context
), ReductionId
,
19580 RD
.Privates
, RD
.LHSs
, RD
.RHSs
, RD
.ReductionOps
, RD
.TaskgroupDescriptors
,
19581 buildPreInits(Context
, RD
.ExprCaptures
),
19582 buildPostUpdate(*this, RD
.ExprPostUpdates
));
19585 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind
,
19586 SourceLocation LinLoc
) {
19587 if ((!LangOpts
.CPlusPlus
&& LinKind
!= OMPC_LINEAR_val
) ||
19588 LinKind
== OMPC_LINEAR_unknown
) {
19589 Diag(LinLoc
, diag::err_omp_wrong_linear_modifier
) << LangOpts
.CPlusPlus
;
19595 bool Sema::CheckOpenMPLinearDecl(const ValueDecl
*D
, SourceLocation ELoc
,
19596 OpenMPLinearClauseKind LinKind
, QualType Type
,
19597 bool IsDeclareSimd
) {
19598 const auto *VD
= dyn_cast_or_null
<VarDecl
>(D
);
19599 // A variable must not have an incomplete type or a reference type.
19600 if (RequireCompleteType(ELoc
, Type
, diag::err_omp_linear_incomplete_type
))
19602 if ((LinKind
== OMPC_LINEAR_uval
|| LinKind
== OMPC_LINEAR_ref
) &&
19603 !Type
->isReferenceType()) {
19604 Diag(ELoc
, diag::err_omp_wrong_linear_modifier_non_reference
)
19605 << Type
<< getOpenMPSimpleClauseTypeName(OMPC_linear
, LinKind
);
19608 Type
= Type
.getNonReferenceType();
19610 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19611 // A variable that is privatized must not have a const-qualified type
19612 // unless it is of class type with a mutable member. This restriction does
19613 // not apply to the firstprivate clause, nor to the linear clause on
19614 // declarative directives (like declare simd).
19615 if (!IsDeclareSimd
&&
19616 rejectConstNotMutableType(*this, D
, Type
, OMPC_linear
, ELoc
))
19619 // A list item must be of integral or pointer type.
19620 Type
= Type
.getUnqualifiedType().getCanonicalType();
19621 const auto *Ty
= Type
.getTypePtrOrNull();
19622 if (!Ty
|| (LinKind
!= OMPC_LINEAR_ref
&& !Ty
->isDependentType() &&
19623 !Ty
->isIntegralType(Context
) && !Ty
->isPointerType())) {
19624 Diag(ELoc
, diag::err_omp_linear_expected_int_or_ptr
) << Type
;
19626 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
19627 VarDecl::DeclarationOnly
;
19628 Diag(D
->getLocation(),
19629 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
19637 OMPClause
*Sema::ActOnOpenMPLinearClause(
19638 ArrayRef
<Expr
*> VarList
, Expr
*Step
, SourceLocation StartLoc
,
19639 SourceLocation LParenLoc
, OpenMPLinearClauseKind LinKind
,
19640 SourceLocation LinLoc
, SourceLocation ColonLoc
, SourceLocation EndLoc
) {
19641 SmallVector
<Expr
*, 8> Vars
;
19642 SmallVector
<Expr
*, 8> Privates
;
19643 SmallVector
<Expr
*, 8> Inits
;
19644 SmallVector
<Decl
*, 4> ExprCaptures
;
19645 SmallVector
<Expr
*, 4> ExprPostUpdates
;
19646 if (CheckOpenMPLinearModifier(LinKind
, LinLoc
))
19647 LinKind
= OMPC_LINEAR_val
;
19648 for (Expr
*RefExpr
: VarList
) {
19649 assert(RefExpr
&& "NULL expr in OpenMP linear clause.");
19650 SourceLocation ELoc
;
19651 SourceRange ERange
;
19652 Expr
*SimpleRefExpr
= RefExpr
;
19653 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
19655 // It will be analyzed later.
19656 Vars
.push_back(RefExpr
);
19657 Privates
.push_back(nullptr);
19658 Inits
.push_back(nullptr);
19660 ValueDecl
*D
= Res
.first
;
19664 QualType Type
= D
->getType();
19665 auto *VD
= dyn_cast
<VarDecl
>(D
);
19667 // OpenMP [2.14.3.7, linear clause]
19668 // A list-item cannot appear in more than one linear clause.
19669 // A list-item that appears in a linear clause cannot appear in any
19670 // other data-sharing attribute clause.
19671 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
19672 if (DVar
.RefExpr
) {
19673 Diag(ELoc
, diag::err_omp_wrong_dsa
) << getOpenMPClauseName(DVar
.CKind
)
19674 << getOpenMPClauseName(OMPC_linear
);
19675 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
19679 if (CheckOpenMPLinearDecl(D
, ELoc
, LinKind
, Type
))
19681 Type
= Type
.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19683 // Build private copy of original var.
19685 buildVarDecl(*this, ELoc
, Type
, D
->getName(),
19686 D
->hasAttrs() ? &D
->getAttrs() : nullptr,
19687 VD
? cast
<DeclRefExpr
>(SimpleRefExpr
) : nullptr);
19688 DeclRefExpr
*PrivateRef
= buildDeclRefExpr(*this, Private
, Type
, ELoc
);
19689 // Build var to save initial value.
19690 VarDecl
*Init
= buildVarDecl(*this, ELoc
, Type
, ".linear.start");
19692 DeclRefExpr
*Ref
= nullptr;
19693 if (!VD
&& !CurContext
->isDependentContext()) {
19694 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/false);
19695 if (!isOpenMPCapturedDecl(D
)) {
19696 ExprCaptures
.push_back(Ref
->getDecl());
19697 if (Ref
->getDecl()->hasAttr
<OMPCaptureNoInitAttr
>()) {
19698 ExprResult RefRes
= DefaultLvalueConversion(Ref
);
19699 if (!RefRes
.isUsable())
19701 ExprResult PostUpdateRes
=
19702 BuildBinOp(DSAStack
->getCurScope(), ELoc
, BO_Assign
,
19703 SimpleRefExpr
, RefRes
.get());
19704 if (!PostUpdateRes
.isUsable())
19706 ExprPostUpdates
.push_back(
19707 IgnoredValueConversions(PostUpdateRes
.get()).get());
19711 if (LinKind
== OMPC_LINEAR_uval
)
19712 InitExpr
= VD
? VD
->getInit() : SimpleRefExpr
;
19714 InitExpr
= VD
? SimpleRefExpr
: Ref
;
19715 AddInitializerToDecl(Init
, DefaultLvalueConversion(InitExpr
).get(),
19716 /*DirectInit=*/false);
19717 DeclRefExpr
*InitRef
= buildDeclRefExpr(*this, Init
, Type
, ELoc
);
19719 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_linear
, Ref
);
19720 Vars
.push_back((VD
|| CurContext
->isDependentContext())
19721 ? RefExpr
->IgnoreParens()
19723 Privates
.push_back(PrivateRef
);
19724 Inits
.push_back(InitRef
);
19730 Expr
*StepExpr
= Step
;
19731 Expr
*CalcStepExpr
= nullptr;
19732 if (Step
&& !Step
->isValueDependent() && !Step
->isTypeDependent() &&
19733 !Step
->isInstantiationDependent() &&
19734 !Step
->containsUnexpandedParameterPack()) {
19735 SourceLocation StepLoc
= Step
->getBeginLoc();
19736 ExprResult Val
= PerformOpenMPImplicitIntegerConversion(StepLoc
, Step
);
19737 if (Val
.isInvalid())
19739 StepExpr
= Val
.get();
19741 // Build var to save the step value.
19743 buildVarDecl(*this, StepLoc
, StepExpr
->getType(), ".linear.step");
19744 ExprResult SaveRef
=
19745 buildDeclRefExpr(*this, SaveVar
, StepExpr
->getType(), StepLoc
);
19746 ExprResult CalcStep
=
19747 BuildBinOp(CurScope
, StepLoc
, BO_Assign
, SaveRef
.get(), StepExpr
);
19748 CalcStep
= ActOnFinishFullExpr(CalcStep
.get(), /*DiscardedValue*/ false);
19750 // Warn about zero linear step (it would be probably better specified as
19751 // making corresponding variables 'const').
19752 if (Optional
<llvm::APSInt
> Result
=
19753 StepExpr
->getIntegerConstantExpr(Context
)) {
19754 if (!Result
->isNegative() && !Result
->isStrictlyPositive())
19755 Diag(StepLoc
, diag::warn_omp_linear_step_zero
)
19756 << Vars
[0] << (Vars
.size() > 1);
19757 } else if (CalcStep
.isUsable()) {
19758 // Calculate the step beforehand instead of doing this on each iteration.
19759 // (This is not used if the number of iterations may be kfold-ed).
19760 CalcStepExpr
= CalcStep
.get();
19764 return OMPLinearClause::Create(Context
, StartLoc
, LParenLoc
, LinKind
, LinLoc
,
19765 ColonLoc
, EndLoc
, Vars
, Privates
, Inits
,
19766 StepExpr
, CalcStepExpr
,
19767 buildPreInits(Context
, ExprCaptures
),
19768 buildPostUpdate(*this, ExprPostUpdates
));
19771 static bool FinishOpenMPLinearClause(OMPLinearClause
&Clause
, DeclRefExpr
*IV
,
19772 Expr
*NumIterations
, Sema
&SemaRef
,
19773 Scope
*S
, DSAStackTy
*Stack
) {
19774 // Walk the vars and build update/final expressions for the CodeGen.
19775 SmallVector
<Expr
*, 8> Updates
;
19776 SmallVector
<Expr
*, 8> Finals
;
19777 SmallVector
<Expr
*, 8> UsedExprs
;
19778 Expr
*Step
= Clause
.getStep();
19779 Expr
*CalcStep
= Clause
.getCalcStep();
19780 // OpenMP [2.14.3.7, linear clause]
19781 // If linear-step is not specified it is assumed to be 1.
19783 Step
= SemaRef
.ActOnIntegerConstant(SourceLocation(), 1).get();
19785 Step
= cast
<BinaryOperator
>(CalcStep
)->getLHS();
19786 bool HasErrors
= false;
19787 auto CurInit
= Clause
.inits().begin();
19788 auto CurPrivate
= Clause
.privates().begin();
19789 OpenMPLinearClauseKind LinKind
= Clause
.getModifier();
19790 for (Expr
*RefExpr
: Clause
.varlists()) {
19791 SourceLocation ELoc
;
19792 SourceRange ERange
;
19793 Expr
*SimpleRefExpr
= RefExpr
;
19794 auto Res
= getPrivateItem(SemaRef
, SimpleRefExpr
, ELoc
, ERange
);
19795 ValueDecl
*D
= Res
.first
;
19796 if (Res
.second
|| !D
) {
19797 Updates
.push_back(nullptr);
19798 Finals
.push_back(nullptr);
19802 auto &&Info
= Stack
->isLoopControlVariable(D
);
19803 // OpenMP [2.15.11, distribute simd Construct]
19804 // A list item may not appear in a linear clause, unless it is the loop
19805 // iteration variable.
19806 if (isOpenMPDistributeDirective(Stack
->getCurrentDirective()) &&
19807 isOpenMPSimdDirective(Stack
->getCurrentDirective()) && !Info
.first
) {
19809 diag::err_omp_linear_distribute_var_non_loop_iteration
);
19810 Updates
.push_back(nullptr);
19811 Finals
.push_back(nullptr);
19815 Expr
*InitExpr
= *CurInit
;
19817 // Build privatized reference to the current linear var.
19818 auto *DE
= cast
<DeclRefExpr
>(SimpleRefExpr
);
19820 if (LinKind
== OMPC_LINEAR_uval
)
19821 CapturedRef
= cast
<VarDecl
>(DE
->getDecl())->getInit();
19824 buildDeclRefExpr(SemaRef
, cast
<VarDecl
>(DE
->getDecl()),
19825 DE
->getType().getUnqualifiedType(), DE
->getExprLoc(),
19826 /*RefersToCapture=*/true);
19828 // Build update: Var = InitExpr + IV * Step
19831 Update
= buildCounterUpdate(
19832 SemaRef
, S
, RefExpr
->getExprLoc(), *CurPrivate
, InitExpr
, IV
, Step
,
19833 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
19835 Update
= *CurPrivate
;
19836 Update
= SemaRef
.ActOnFinishFullExpr(Update
.get(), DE
->getBeginLoc(),
19837 /*DiscardedValue*/ false);
19839 // Build final: Var = PrivCopy;
19842 Final
= SemaRef
.BuildBinOp(
19843 S
, RefExpr
->getExprLoc(), BO_Assign
, CapturedRef
,
19844 SemaRef
.DefaultLvalueConversion(*CurPrivate
).get());
19846 Final
= *CurPrivate
;
19847 Final
= SemaRef
.ActOnFinishFullExpr(Final
.get(), DE
->getBeginLoc(),
19848 /*DiscardedValue*/ false);
19850 if (!Update
.isUsable() || !Final
.isUsable()) {
19851 Updates
.push_back(nullptr);
19852 Finals
.push_back(nullptr);
19853 UsedExprs
.push_back(nullptr);
19856 Updates
.push_back(Update
.get());
19857 Finals
.push_back(Final
.get());
19859 UsedExprs
.push_back(SimpleRefExpr
);
19864 if (Expr
*S
= Clause
.getStep())
19865 UsedExprs
.push_back(S
);
19866 // Fill the remaining part with the nullptr.
19867 UsedExprs
.append(Clause
.varlist_size() + 1 - UsedExprs
.size(), nullptr);
19868 Clause
.setUpdates(Updates
);
19869 Clause
.setFinals(Finals
);
19870 Clause
.setUsedExprs(UsedExprs
);
19874 OMPClause
*Sema::ActOnOpenMPAlignedClause(
19875 ArrayRef
<Expr
*> VarList
, Expr
*Alignment
, SourceLocation StartLoc
,
19876 SourceLocation LParenLoc
, SourceLocation ColonLoc
, SourceLocation EndLoc
) {
19877 SmallVector
<Expr
*, 8> Vars
;
19878 for (Expr
*RefExpr
: VarList
) {
19879 assert(RefExpr
&& "NULL expr in OpenMP linear clause.");
19880 SourceLocation ELoc
;
19881 SourceRange ERange
;
19882 Expr
*SimpleRefExpr
= RefExpr
;
19883 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
19885 // It will be analyzed later.
19886 Vars
.push_back(RefExpr
);
19888 ValueDecl
*D
= Res
.first
;
19892 QualType QType
= D
->getType();
19893 auto *VD
= dyn_cast
<VarDecl
>(D
);
19895 // OpenMP [2.8.1, simd construct, Restrictions]
19896 // The type of list items appearing in the aligned clause must be
19897 // array, pointer, reference to array, or reference to pointer.
19898 QType
= QType
.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19899 const Type
*Ty
= QType
.getTypePtrOrNull();
19900 if (!Ty
|| (!Ty
->isArrayType() && !Ty
->isPointerType())) {
19901 Diag(ELoc
, diag::err_omp_aligned_expected_array_or_ptr
)
19902 << QType
<< getLangOpts().CPlusPlus
<< ERange
;
19903 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
19904 VarDecl::DeclarationOnly
;
19905 Diag(D
->getLocation(),
19906 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
19911 // OpenMP [2.8.1, simd construct, Restrictions]
19912 // A list-item cannot appear in more than one aligned clause.
19913 if (const Expr
*PrevRef
= DSAStack
->addUniqueAligned(D
, SimpleRefExpr
)) {
19914 Diag(ELoc
, diag::err_omp_used_in_clause_twice
)
19915 << 0 << getOpenMPClauseName(OMPC_aligned
) << ERange
;
19916 Diag(PrevRef
->getExprLoc(), diag::note_omp_explicit_dsa
)
19917 << getOpenMPClauseName(OMPC_aligned
);
19921 DeclRefExpr
*Ref
= nullptr;
19922 if (!VD
&& isOpenMPCapturedDecl(D
))
19923 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
19924 Vars
.push_back(DefaultFunctionArrayConversion(
19925 (VD
|| !Ref
) ? RefExpr
->IgnoreParens() : Ref
)
19929 // OpenMP [2.8.1, simd construct, Description]
19930 // The parameter of the aligned clause, alignment, must be a constant
19931 // positive integer expression.
19932 // If no optional parameter is specified, implementation-defined default
19933 // alignments for SIMD instructions on the target platforms are assumed.
19934 if (Alignment
!= nullptr) {
19935 ExprResult AlignResult
=
19936 VerifyPositiveIntegerConstantInClause(Alignment
, OMPC_aligned
);
19937 if (AlignResult
.isInvalid())
19939 Alignment
= AlignResult
.get();
19944 return OMPAlignedClause::Create(Context
, StartLoc
, LParenLoc
, ColonLoc
,
19945 EndLoc
, Vars
, Alignment
);
19948 OMPClause
*Sema::ActOnOpenMPCopyinClause(ArrayRef
<Expr
*> VarList
,
19949 SourceLocation StartLoc
,
19950 SourceLocation LParenLoc
,
19951 SourceLocation EndLoc
) {
19952 SmallVector
<Expr
*, 8> Vars
;
19953 SmallVector
<Expr
*, 8> SrcExprs
;
19954 SmallVector
<Expr
*, 8> DstExprs
;
19955 SmallVector
<Expr
*, 8> AssignmentOps
;
19956 for (Expr
*RefExpr
: VarList
) {
19957 assert(RefExpr
&& "NULL expr in OpenMP copyin clause.");
19958 if (isa
<DependentScopeDeclRefExpr
>(RefExpr
)) {
19959 // It will be analyzed later.
19960 Vars
.push_back(RefExpr
);
19961 SrcExprs
.push_back(nullptr);
19962 DstExprs
.push_back(nullptr);
19963 AssignmentOps
.push_back(nullptr);
19967 SourceLocation ELoc
= RefExpr
->getExprLoc();
19968 // OpenMP [2.1, C/C++]
19969 // A list item is a variable name.
19970 // OpenMP [2.14.4.1, Restrictions, p.1]
19971 // A list item that appears in a copyin clause must be threadprivate.
19972 auto *DE
= dyn_cast
<DeclRefExpr
>(RefExpr
);
19973 if (!DE
|| !isa
<VarDecl
>(DE
->getDecl())) {
19974 Diag(ELoc
, diag::err_omp_expected_var_name_member_expr
)
19975 << 0 << RefExpr
->getSourceRange();
19979 Decl
*D
= DE
->getDecl();
19980 auto *VD
= cast
<VarDecl
>(D
);
19982 QualType Type
= VD
->getType();
19983 if (Type
->isDependentType() || Type
->isInstantiationDependentType()) {
19984 // It will be analyzed later.
19985 Vars
.push_back(DE
);
19986 SrcExprs
.push_back(nullptr);
19987 DstExprs
.push_back(nullptr);
19988 AssignmentOps
.push_back(nullptr);
19992 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19993 // A list item that appears in a copyin clause must be threadprivate.
19994 if (!DSAStack
->isThreadPrivate(VD
)) {
19995 Diag(ELoc
, diag::err_omp_required_access
)
19996 << getOpenMPClauseName(OMPC_copyin
)
19997 << getOpenMPDirectiveName(OMPD_threadprivate
);
20001 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20002 // A variable of class type (or array thereof) that appears in a
20003 // copyin clause requires an accessible, unambiguous copy assignment
20004 // operator for the class type.
20005 QualType ElemType
= Context
.getBaseElementType(Type
).getNonReferenceType();
20007 buildVarDecl(*this, DE
->getBeginLoc(), ElemType
.getUnqualifiedType(),
20008 ".copyin.src", VD
->hasAttrs() ? &VD
->getAttrs() : nullptr);
20009 DeclRefExpr
*PseudoSrcExpr
= buildDeclRefExpr(
20010 *this, SrcVD
, ElemType
.getUnqualifiedType(), DE
->getExprLoc());
20012 buildVarDecl(*this, DE
->getBeginLoc(), ElemType
, ".copyin.dst",
20013 VD
->hasAttrs() ? &VD
->getAttrs() : nullptr);
20014 DeclRefExpr
*PseudoDstExpr
=
20015 buildDeclRefExpr(*this, DstVD
, ElemType
, DE
->getExprLoc());
20016 // For arrays generate assignment operation for single element and replace
20017 // it by the original array element in CodeGen.
20018 ExprResult AssignmentOp
=
20019 BuildBinOp(/*S=*/nullptr, DE
->getExprLoc(), BO_Assign
, PseudoDstExpr
,
20021 if (AssignmentOp
.isInvalid())
20023 AssignmentOp
= ActOnFinishFullExpr(AssignmentOp
.get(), DE
->getExprLoc(),
20024 /*DiscardedValue*/ false);
20025 if (AssignmentOp
.isInvalid())
20028 DSAStack
->addDSA(VD
, DE
, OMPC_copyin
);
20029 Vars
.push_back(DE
);
20030 SrcExprs
.push_back(PseudoSrcExpr
);
20031 DstExprs
.push_back(PseudoDstExpr
);
20032 AssignmentOps
.push_back(AssignmentOp
.get());
20038 return OMPCopyinClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Vars
,
20039 SrcExprs
, DstExprs
, AssignmentOps
);
20042 OMPClause
*Sema::ActOnOpenMPCopyprivateClause(ArrayRef
<Expr
*> VarList
,
20043 SourceLocation StartLoc
,
20044 SourceLocation LParenLoc
,
20045 SourceLocation EndLoc
) {
20046 SmallVector
<Expr
*, 8> Vars
;
20047 SmallVector
<Expr
*, 8> SrcExprs
;
20048 SmallVector
<Expr
*, 8> DstExprs
;
20049 SmallVector
<Expr
*, 8> AssignmentOps
;
20050 for (Expr
*RefExpr
: VarList
) {
20051 assert(RefExpr
&& "NULL expr in OpenMP linear clause.");
20052 SourceLocation ELoc
;
20053 SourceRange ERange
;
20054 Expr
*SimpleRefExpr
= RefExpr
;
20055 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
20057 // It will be analyzed later.
20058 Vars
.push_back(RefExpr
);
20059 SrcExprs
.push_back(nullptr);
20060 DstExprs
.push_back(nullptr);
20061 AssignmentOps
.push_back(nullptr);
20063 ValueDecl
*D
= Res
.first
;
20067 QualType Type
= D
->getType();
20068 auto *VD
= dyn_cast
<VarDecl
>(D
);
20070 // OpenMP [2.14.4.2, Restrictions, p.2]
20071 // A list item that appears in a copyprivate clause may not appear in a
20072 // private or firstprivate clause on the single construct.
20073 if (!VD
|| !DSAStack
->isThreadPrivate(VD
)) {
20074 DSAStackTy::DSAVarData DVar
=
20075 DSAStack
->getTopDSA(D
, /*FromParent=*/false);
20076 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_copyprivate
&&
20078 Diag(ELoc
, diag::err_omp_wrong_dsa
)
20079 << getOpenMPClauseName(DVar
.CKind
)
20080 << getOpenMPClauseName(OMPC_copyprivate
);
20081 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
20085 // OpenMP [2.11.4.2, Restrictions, p.1]
20086 // All list items that appear in a copyprivate clause must be either
20087 // threadprivate or private in the enclosing context.
20088 if (DVar
.CKind
== OMPC_unknown
) {
20089 DVar
= DSAStack
->getImplicitDSA(D
, false);
20090 if (DVar
.CKind
== OMPC_shared
) {
20091 Diag(ELoc
, diag::err_omp_required_access
)
20092 << getOpenMPClauseName(OMPC_copyprivate
)
20093 << "threadprivate or private in the enclosing context";
20094 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
20100 // Variably modified types are not supported.
20101 if (!Type
->isAnyPointerType() && Type
->isVariablyModifiedType()) {
20102 Diag(ELoc
, diag::err_omp_variably_modified_type_not_supported
)
20103 << getOpenMPClauseName(OMPC_copyprivate
) << Type
20104 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
20105 bool IsDecl
= !VD
|| VD
->isThisDeclarationADefinition(Context
) ==
20106 VarDecl::DeclarationOnly
;
20107 Diag(D
->getLocation(),
20108 IsDecl
? diag::note_previous_decl
: diag::note_defined_here
)
20113 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20114 // A variable of class type (or array thereof) that appears in a
20115 // copyin clause requires an accessible, unambiguous copy assignment
20116 // operator for the class type.
20117 Type
= Context
.getBaseElementType(Type
.getNonReferenceType())
20118 .getUnqualifiedType();
20120 buildVarDecl(*this, RefExpr
->getBeginLoc(), Type
, ".copyprivate.src",
20121 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
20122 DeclRefExpr
*PseudoSrcExpr
= buildDeclRefExpr(*this, SrcVD
, Type
, ELoc
);
20124 buildVarDecl(*this, RefExpr
->getBeginLoc(), Type
, ".copyprivate.dst",
20125 D
->hasAttrs() ? &D
->getAttrs() : nullptr);
20126 DeclRefExpr
*PseudoDstExpr
= buildDeclRefExpr(*this, DstVD
, Type
, ELoc
);
20127 ExprResult AssignmentOp
= BuildBinOp(
20128 DSAStack
->getCurScope(), ELoc
, BO_Assign
, PseudoDstExpr
, PseudoSrcExpr
);
20129 if (AssignmentOp
.isInvalid())
20132 ActOnFinishFullExpr(AssignmentOp
.get(), ELoc
, /*DiscardedValue*/ false);
20133 if (AssignmentOp
.isInvalid())
20136 // No need to mark vars as copyprivate, they are already threadprivate or
20137 // implicitly private.
20138 assert(VD
|| isOpenMPCapturedDecl(D
));
20140 VD
? RefExpr
->IgnoreParens()
20141 : buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/false));
20142 SrcExprs
.push_back(PseudoSrcExpr
);
20143 DstExprs
.push_back(PseudoDstExpr
);
20144 AssignmentOps
.push_back(AssignmentOp
.get());
20150 return OMPCopyprivateClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
20151 Vars
, SrcExprs
, DstExprs
, AssignmentOps
);
20154 OMPClause
*Sema::ActOnOpenMPFlushClause(ArrayRef
<Expr
*> VarList
,
20155 SourceLocation StartLoc
,
20156 SourceLocation LParenLoc
,
20157 SourceLocation EndLoc
) {
20158 if (VarList
.empty())
20161 return OMPFlushClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, VarList
);
20164 /// Tries to find omp_depend_t. type.
20165 static bool findOMPDependT(Sema
&S
, SourceLocation Loc
, DSAStackTy
*Stack
,
20166 bool Diagnose
= true) {
20167 QualType OMPDependT
= Stack
->getOMPDependT();
20168 if (!OMPDependT
.isNull())
20170 IdentifierInfo
*II
= &S
.PP
.getIdentifierTable().get("omp_depend_t");
20171 ParsedType PT
= S
.getTypeName(*II
, Loc
, S
.getCurScope());
20172 if (!PT
.getAsOpaquePtr() || PT
.get().isNull()) {
20174 S
.Diag(Loc
, diag::err_omp_implied_type_not_found
) << "omp_depend_t";
20177 Stack
->setOMPDependT(PT
.get());
20181 OMPClause
*Sema::ActOnOpenMPDepobjClause(Expr
*Depobj
, SourceLocation StartLoc
,
20182 SourceLocation LParenLoc
,
20183 SourceLocation EndLoc
) {
20187 bool OMPDependTFound
= findOMPDependT(*this, StartLoc
, DSAStack
);
20189 // OpenMP 5.0, 2.17.10.1 depobj Construct
20190 // depobj is an lvalue expression of type omp_depend_t.
20191 if (!Depobj
->isTypeDependent() && !Depobj
->isValueDependent() &&
20192 !Depobj
->isInstantiationDependent() &&
20193 !Depobj
->containsUnexpandedParameterPack() &&
20194 (OMPDependTFound
&&
20195 !Context
.typesAreCompatible(DSAStack
->getOMPDependT(), Depobj
->getType(),
20196 /*CompareUnqualified=*/true))) {
20197 Diag(Depobj
->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue
)
20198 << 0 << Depobj
->getType() << Depobj
->getSourceRange();
20201 if (!Depobj
->isLValue()) {
20202 Diag(Depobj
->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue
)
20203 << 1 << Depobj
->getSourceRange();
20206 return OMPDepobjClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Depobj
);
20210 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy
&Data
,
20211 Expr
*DepModifier
, ArrayRef
<Expr
*> VarList
,
20212 SourceLocation StartLoc
, SourceLocation LParenLoc
,
20213 SourceLocation EndLoc
) {
20214 OpenMPDependClauseKind DepKind
= Data
.DepKind
;
20215 SourceLocation DepLoc
= Data
.DepLoc
;
20216 if (DSAStack
->getCurrentDirective() == OMPD_ordered
&&
20217 DepKind
!= OMPC_DEPEND_source
&& DepKind
!= OMPC_DEPEND_sink
) {
20218 Diag(DepLoc
, diag::err_omp_unexpected_clause_value
)
20219 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend
);
20222 if (DSAStack
->getCurrentDirective() == OMPD_taskwait
&&
20223 DepKind
== OMPC_DEPEND_mutexinoutset
) {
20224 Diag(DepLoc
, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed
);
20227 if ((DSAStack
->getCurrentDirective() != OMPD_ordered
||
20228 DSAStack
->getCurrentDirective() == OMPD_depobj
) &&
20229 (DepKind
== OMPC_DEPEND_unknown
|| DepKind
== OMPC_DEPEND_source
||
20230 DepKind
== OMPC_DEPEND_sink
||
20231 ((LangOpts
.OpenMP
< 50 ||
20232 DSAStack
->getCurrentDirective() == OMPD_depobj
) &&
20233 DepKind
== OMPC_DEPEND_depobj
))) {
20234 SmallVector
<unsigned, 6> Except
= {OMPC_DEPEND_source
, OMPC_DEPEND_sink
,
20235 OMPC_DEPEND_outallmemory
,
20236 OMPC_DEPEND_inoutallmemory
};
20237 if (LangOpts
.OpenMP
< 50 || DSAStack
->getCurrentDirective() == OMPD_depobj
)
20238 Except
.push_back(OMPC_DEPEND_depobj
);
20239 if (LangOpts
.OpenMP
< 51)
20240 Except
.push_back(OMPC_DEPEND_inoutset
);
20241 std::string Expected
= (LangOpts
.OpenMP
>= 50 && !DepModifier
)
20242 ? "depend modifier(iterator) or "
20244 Diag(DepLoc
, diag::err_omp_unexpected_clause_value
)
20245 << Expected
+ getListOfPossibleValues(OMPC_depend
, /*First=*/0,
20246 /*Last=*/OMPC_DEPEND_unknown
,
20248 << getOpenMPClauseName(OMPC_depend
);
20252 (DepKind
== OMPC_DEPEND_source
|| DepKind
== OMPC_DEPEND_sink
)) {
20253 Diag(DepModifier
->getExprLoc(),
20254 diag::err_omp_depend_sink_source_with_modifier
);
20258 !DepModifier
->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator
))
20259 Diag(DepModifier
->getExprLoc(), diag::err_omp_depend_modifier_not_iterator
);
20261 SmallVector
<Expr
*, 8> Vars
;
20262 DSAStackTy::OperatorOffsetTy OpsOffs
;
20263 llvm::APSInt
DepCounter(/*BitWidth=*/32);
20264 llvm::APSInt
TotalDepCount(/*BitWidth=*/32);
20265 if (DepKind
== OMPC_DEPEND_sink
|| DepKind
== OMPC_DEPEND_source
) {
20266 if (const Expr
*OrderedCountExpr
=
20267 DSAStack
->getParentOrderedRegionParam().first
) {
20268 TotalDepCount
= OrderedCountExpr
->EvaluateKnownConstInt(Context
);
20269 TotalDepCount
.setIsUnsigned(/*Val=*/true);
20272 for (Expr
*RefExpr
: VarList
) {
20273 assert(RefExpr
&& "NULL expr in OpenMP shared clause.");
20274 if (isa
<DependentScopeDeclRefExpr
>(RefExpr
)) {
20275 // It will be analyzed later.
20276 Vars
.push_back(RefExpr
);
20280 SourceLocation ELoc
= RefExpr
->getExprLoc();
20281 Expr
*SimpleExpr
= RefExpr
->IgnoreParenCasts();
20282 if (DepKind
== OMPC_DEPEND_sink
) {
20283 if (DSAStack
->getParentOrderedRegionParam().first
&&
20284 DepCounter
>= TotalDepCount
) {
20285 Diag(ELoc
, diag::err_omp_depend_sink_unexpected_expr
);
20289 // OpenMP [2.13.9, Summary]
20290 // depend(dependence-type : vec), where dependence-type is:
20291 // 'sink' and where vec is the iteration vector, which has the form:
20292 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20293 // where n is the value specified by the ordered clause in the loop
20294 // directive, xi denotes the loop iteration variable of the i-th nested
20295 // loop associated with the loop directive, and di is a constant
20296 // non-negative integer.
20297 if (CurContext
->isDependentContext()) {
20298 // It will be analyzed later.
20299 Vars
.push_back(RefExpr
);
20302 SimpleExpr
= SimpleExpr
->IgnoreImplicit();
20303 OverloadedOperatorKind OOK
= OO_None
;
20304 SourceLocation OOLoc
;
20305 Expr
*LHS
= SimpleExpr
;
20306 Expr
*RHS
= nullptr;
20307 if (auto *BO
= dyn_cast
<BinaryOperator
>(SimpleExpr
)) {
20308 OOK
= BinaryOperator::getOverloadedOperator(BO
->getOpcode());
20309 OOLoc
= BO
->getOperatorLoc();
20310 LHS
= BO
->getLHS()->IgnoreParenImpCasts();
20311 RHS
= BO
->getRHS()->IgnoreParenImpCasts();
20312 } else if (auto *OCE
= dyn_cast
<CXXOperatorCallExpr
>(SimpleExpr
)) {
20313 OOK
= OCE
->getOperator();
20314 OOLoc
= OCE
->getOperatorLoc();
20315 LHS
= OCE
->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20316 RHS
= OCE
->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20317 } else if (auto *MCE
= dyn_cast
<CXXMemberCallExpr
>(SimpleExpr
)) {
20318 OOK
= MCE
->getMethodDecl()
20321 .getCXXOverloadedOperator();
20322 OOLoc
= MCE
->getCallee()->getExprLoc();
20323 LHS
= MCE
->getImplicitObjectArgument()->IgnoreParenImpCasts();
20324 RHS
= MCE
->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20326 SourceLocation ELoc
;
20327 SourceRange ERange
;
20328 auto Res
= getPrivateItem(*this, LHS
, ELoc
, ERange
);
20330 // It will be analyzed later.
20331 Vars
.push_back(RefExpr
);
20333 ValueDecl
*D
= Res
.first
;
20337 if (OOK
!= OO_Plus
&& OOK
!= OO_Minus
&& (RHS
|| OOK
!= OO_None
)) {
20338 Diag(OOLoc
, diag::err_omp_depend_sink_expected_plus_minus
);
20342 ExprResult RHSRes
= VerifyPositiveIntegerConstantInClause(
20343 RHS
, OMPC_depend
, /*StrictlyPositive=*/false);
20344 if (RHSRes
.isInvalid())
20347 if (!CurContext
->isDependentContext() &&
20348 DSAStack
->getParentOrderedRegionParam().first
&&
20349 DepCounter
!= DSAStack
->isParentLoopControlVariable(D
).first
) {
20350 const ValueDecl
*VD
=
20351 DSAStack
->getParentLoopControlVariable(DepCounter
.getZExtValue());
20353 Diag(ELoc
, diag::err_omp_depend_sink_expected_loop_iteration
)
20356 Diag(ELoc
, diag::err_omp_depend_sink_expected_loop_iteration
) << 0;
20359 OpsOffs
.emplace_back(RHS
, OOK
);
20361 bool OMPDependTFound
= LangOpts
.OpenMP
>= 50;
20362 if (OMPDependTFound
)
20363 OMPDependTFound
= findOMPDependT(*this, StartLoc
, DSAStack
,
20364 DepKind
== OMPC_DEPEND_depobj
);
20365 if (DepKind
== OMPC_DEPEND_depobj
) {
20366 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20367 // List items used in depend clauses with the depobj dependence type
20368 // must be expressions of the omp_depend_t type.
20369 if (!RefExpr
->isValueDependent() && !RefExpr
->isTypeDependent() &&
20370 !RefExpr
->isInstantiationDependent() &&
20371 !RefExpr
->containsUnexpandedParameterPack() &&
20372 (OMPDependTFound
&&
20373 !Context
.hasSameUnqualifiedType(DSAStack
->getOMPDependT(),
20374 RefExpr
->getType()))) {
20375 Diag(ELoc
, diag::err_omp_expected_omp_depend_t_lvalue
)
20376 << 0 << RefExpr
->getType() << RefExpr
->getSourceRange();
20379 if (!RefExpr
->isLValue()) {
20380 Diag(ELoc
, diag::err_omp_expected_omp_depend_t_lvalue
)
20381 << 1 << RefExpr
->getType() << RefExpr
->getSourceRange();
20385 // OpenMP 5.0 [2.17.11, Restrictions]
20386 // List items used in depend clauses cannot be zero-length array
20388 QualType ExprTy
= RefExpr
->getType().getNonReferenceType();
20389 const auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(SimpleExpr
);
20391 QualType BaseType
=
20392 OMPArraySectionExpr::getBaseOriginalType(OASE
->getBase());
20393 if (const auto *ATy
= BaseType
->getAsArrayTypeUnsafe())
20394 ExprTy
= ATy
->getElementType();
20396 ExprTy
= BaseType
->getPointeeType();
20397 ExprTy
= ExprTy
.getNonReferenceType();
20398 const Expr
*Length
= OASE
->getLength();
20399 Expr::EvalResult Result
;
20400 if (Length
&& !Length
->isValueDependent() &&
20401 Length
->EvaluateAsInt(Result
, Context
) &&
20402 Result
.Val
.getInt().isZero()) {
20404 diag::err_omp_depend_zero_length_array_section_not_allowed
)
20405 << SimpleExpr
->getSourceRange();
20410 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20411 // List items used in depend clauses with the in, out, inout,
20412 // inoutset, or mutexinoutset dependence types cannot be
20413 // expressions of the omp_depend_t type.
20414 if (!RefExpr
->isValueDependent() && !RefExpr
->isTypeDependent() &&
20415 !RefExpr
->isInstantiationDependent() &&
20416 !RefExpr
->containsUnexpandedParameterPack() &&
20417 (!RefExpr
->IgnoreParenImpCasts()->isLValue() ||
20418 (OMPDependTFound
&&
20419 DSAStack
->getOMPDependT().getTypePtr() == ExprTy
.getTypePtr()))) {
20420 Diag(ELoc
, diag::err_omp_expected_addressable_lvalue_or_array_item
)
20421 << (LangOpts
.OpenMP
>= 50 ? 1 : 0)
20422 << (LangOpts
.OpenMP
>= 50 ? 1 : 0) << RefExpr
->getSourceRange();
20426 auto *ASE
= dyn_cast
<ArraySubscriptExpr
>(SimpleExpr
);
20427 if (ASE
&& !ASE
->getBase()->isTypeDependent() &&
20428 !ASE
->getBase()->getType().getNonReferenceType()->isPointerType() &&
20429 !ASE
->getBase()->getType().getNonReferenceType()->isArrayType()) {
20430 Diag(ELoc
, diag::err_omp_expected_addressable_lvalue_or_array_item
)
20431 << (LangOpts
.OpenMP
>= 50 ? 1 : 0)
20432 << (LangOpts
.OpenMP
>= 50 ? 1 : 0) << RefExpr
->getSourceRange();
20438 Sema::TentativeAnalysisScope
Trap(*this);
20439 Res
= CreateBuiltinUnaryOp(ELoc
, UO_AddrOf
,
20440 RefExpr
->IgnoreParenImpCasts());
20442 if (!Res
.isUsable() && !isa
<OMPArraySectionExpr
>(SimpleExpr
) &&
20443 !isa
<OMPArrayShapingExpr
>(SimpleExpr
)) {
20444 Diag(ELoc
, diag::err_omp_expected_addressable_lvalue_or_array_item
)
20445 << (LangOpts
.OpenMP
>= 50 ? 1 : 0)
20446 << (LangOpts
.OpenMP
>= 50 ? 1 : 0) << RefExpr
->getSourceRange();
20451 Vars
.push_back(RefExpr
->IgnoreParenImpCasts());
20454 if (!CurContext
->isDependentContext() && DepKind
== OMPC_DEPEND_sink
&&
20455 TotalDepCount
> VarList
.size() &&
20456 DSAStack
->getParentOrderedRegionParam().first
&&
20457 DSAStack
->getParentLoopControlVariable(VarList
.size() + 1)) {
20458 Diag(EndLoc
, diag::err_omp_depend_sink_expected_loop_iteration
)
20459 << 1 << DSAStack
->getParentLoopControlVariable(VarList
.size() + 1);
20461 if (DepKind
!= OMPC_DEPEND_source
&& DepKind
!= OMPC_DEPEND_sink
&&
20462 DepKind
!= OMPC_DEPEND_outallmemory
&&
20463 DepKind
!= OMPC_DEPEND_inoutallmemory
&& Vars
.empty())
20466 auto *C
= OMPDependClause::Create(
20467 Context
, StartLoc
, LParenLoc
, EndLoc
,
20468 {DepKind
, DepLoc
, Data
.ColonLoc
, Data
.OmpAllMemoryLoc
}, DepModifier
, Vars
,
20469 TotalDepCount
.getZExtValue());
20470 if ((DepKind
== OMPC_DEPEND_sink
|| DepKind
== OMPC_DEPEND_source
) &&
20471 DSAStack
->isParentOrderedRegion())
20472 DSAStack
->addDoacrossDependClause(C
, OpsOffs
);
20476 OMPClause
*Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier
,
20477 Expr
*Device
, SourceLocation StartLoc
,
20478 SourceLocation LParenLoc
,
20479 SourceLocation ModifierLoc
,
20480 SourceLocation EndLoc
) {
20481 assert((ModifierLoc
.isInvalid() || LangOpts
.OpenMP
>= 50) &&
20482 "Unexpected device modifier in OpenMP < 50.");
20484 bool ErrorFound
= false;
20485 if (ModifierLoc
.isValid() && Modifier
== OMPC_DEVICE_unknown
) {
20486 std::string Values
=
20487 getListOfPossibleValues(OMPC_device
, /*First=*/0, OMPC_DEVICE_unknown
);
20488 Diag(ModifierLoc
, diag::err_omp_unexpected_clause_value
)
20489 << Values
<< getOpenMPClauseName(OMPC_device
);
20493 Expr
*ValExpr
= Device
;
20494 Stmt
*HelperValStmt
= nullptr;
20496 // OpenMP [2.9.1, Restrictions]
20497 // The device expression must evaluate to a non-negative integer value.
20498 ErrorFound
= !isNonNegativeIntegerValue(ValExpr
, *this, OMPC_device
,
20499 /*StrictlyPositive=*/false) ||
20504 // OpenMP 5.0 [2.12.5, Restrictions]
20505 // In case of ancestor device-modifier, a requires directive with
20506 // the reverse_offload clause must be specified.
20507 if (Modifier
== OMPC_DEVICE_ancestor
) {
20508 if (!DSAStack
->hasRequiresDeclWithClause
<OMPReverseOffloadClause
>()) {
20511 diag::err_omp_device_ancestor_without_requires_reverse_offload
);
20516 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
20517 OpenMPDirectiveKind CaptureRegion
=
20518 getOpenMPCaptureRegionForClause(DKind
, OMPC_device
, LangOpts
.OpenMP
);
20519 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
20520 ValExpr
= MakeFullExpr(ValExpr
).get();
20521 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
20522 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
20523 HelperValStmt
= buildPreInits(Context
, Captures
);
20526 return new (Context
)
20527 OMPDeviceClause(Modifier
, ValExpr
, HelperValStmt
, CaptureRegion
, StartLoc
,
20528 LParenLoc
, ModifierLoc
, EndLoc
);
20531 static bool checkTypeMappable(SourceLocation SL
, SourceRange SR
, Sema
&SemaRef
,
20532 DSAStackTy
*Stack
, QualType QTy
,
20533 bool FullCheck
= true) {
20534 if (SemaRef
.RequireCompleteType(SL
, QTy
, diag::err_incomplete_type
))
20536 if (FullCheck
&& !SemaRef
.CurContext
->isDependentContext() &&
20537 !QTy
.isTriviallyCopyableType(SemaRef
.Context
))
20538 SemaRef
.Diag(SL
, diag::warn_omp_non_trivial_type_mapped
) << QTy
<< SR
;
20542 /// Return true if it can be proven that the provided array expression
20543 /// (array section or array subscript) does NOT specify the whole size of the
20544 /// array whose base type is \a BaseQTy.
20545 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema
&SemaRef
,
20547 QualType BaseQTy
) {
20548 const auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(E
);
20550 // If this is an array subscript, it refers to the whole size if the size of
20551 // the dimension is constant and equals 1. Also, an array section assumes the
20552 // format of an array subscript if no colon is used.
20553 if (isa
<ArraySubscriptExpr
>(E
) ||
20554 (OASE
&& OASE
->getColonLocFirst().isInvalid())) {
20555 if (const auto *ATy
= dyn_cast
<ConstantArrayType
>(BaseQTy
.getTypePtr()))
20556 return ATy
->getSize().getSExtValue() != 1;
20557 // Size can't be evaluated statically.
20561 assert(OASE
&& "Expecting array section if not an array subscript.");
20562 const Expr
*LowerBound
= OASE
->getLowerBound();
20563 const Expr
*Length
= OASE
->getLength();
20565 // If there is a lower bound that does not evaluates to zero, we are not
20566 // covering the whole dimension.
20568 Expr::EvalResult Result
;
20569 if (!LowerBound
->EvaluateAsInt(Result
, SemaRef
.getASTContext()))
20570 return false; // Can't get the integer value as a constant.
20572 llvm::APSInt ConstLowerBound
= Result
.Val
.getInt();
20573 if (ConstLowerBound
.getSExtValue())
20577 // If we don't have a length we covering the whole dimension.
20581 // If the base is a pointer, we don't have a way to get the size of the
20583 if (BaseQTy
->isPointerType())
20586 // We can only check if the length is the same as the size of the dimension
20587 // if we have a constant array.
20588 const auto *CATy
= dyn_cast
<ConstantArrayType
>(BaseQTy
.getTypePtr());
20592 Expr::EvalResult Result
;
20593 if (!Length
->EvaluateAsInt(Result
, SemaRef
.getASTContext()))
20594 return false; // Can't get the integer value as a constant.
20596 llvm::APSInt ConstLength
= Result
.Val
.getInt();
20597 return CATy
->getSize().getSExtValue() != ConstLength
.getSExtValue();
20600 // Return true if it can be proven that the provided array expression (array
20601 // section or array subscript) does NOT specify a single element of the array
20602 // whose base type is \a BaseQTy.
20603 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema
&SemaRef
,
20605 QualType BaseQTy
) {
20606 const auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(E
);
20608 // An array subscript always refer to a single element. Also, an array section
20609 // assumes the format of an array subscript if no colon is used.
20610 if (isa
<ArraySubscriptExpr
>(E
) ||
20611 (OASE
&& OASE
->getColonLocFirst().isInvalid()))
20614 assert(OASE
&& "Expecting array section if not an array subscript.");
20615 const Expr
*Length
= OASE
->getLength();
20617 // If we don't have a length we have to check if the array has unitary size
20618 // for this dimension. Also, we should always expect a length if the base type
20621 if (const auto *ATy
= dyn_cast
<ConstantArrayType
>(BaseQTy
.getTypePtr()))
20622 return ATy
->getSize().getSExtValue() != 1;
20623 // We cannot assume anything.
20627 // Check if the length evaluates to 1.
20628 Expr::EvalResult Result
;
20629 if (!Length
->EvaluateAsInt(Result
, SemaRef
.getASTContext()))
20630 return false; // Can't get the integer value as a constant.
20632 llvm::APSInt ConstLength
= Result
.Val
.getInt();
20633 return ConstLength
.getSExtValue() != 1;
20636 // The base of elements of list in a map clause have to be either:
20637 // - a reference to variable or field.
20638 // - a member expression.
20639 // - an array expression.
20641 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20642 // reference to 'r'.
20649 // #pragma omp target map (S.Arr[:12]);
20653 // We want to retrieve the member expression 'this->S';
20655 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20656 // If a list item is an array section, it must specify contiguous storage.
20658 // For this restriction it is sufficient that we make sure only references
20659 // to variables or fields and array expressions, and that no array sections
20660 // exist except in the rightmost expression (unless they cover the whole
20661 // dimension of the array). E.g. these would be invalid:
20663 // r.ArrS[3:5].Arr[6:7]
20667 // but these would be valid:
20668 // r.ArrS[3].Arr[6:7]
20672 class MapBaseChecker final
: public StmtVisitor
<MapBaseChecker
, bool> {
20674 OpenMPClauseKind CKind
= OMPC_unknown
;
20675 OpenMPDirectiveKind DKind
= OMPD_unknown
;
20676 OMPClauseMappableExprCommon::MappableExprComponentList
&Components
;
20677 bool IsNonContiguous
= false;
20678 bool NoDiagnose
= false;
20679 const Expr
*RelevantExpr
= nullptr;
20680 bool AllowUnitySizeArraySection
= true;
20681 bool AllowWholeSizeArraySection
= true;
20682 bool AllowAnotherPtr
= true;
20683 SourceLocation ELoc
;
20684 SourceRange ERange
;
20686 void emitErrorMsg() {
20687 // If nothing else worked, this is not a valid map clause expression.
20688 if (SemaRef
.getLangOpts().OpenMP
< 50) {
20690 diag::err_omp_expected_named_var_member_or_array_expression
)
20693 SemaRef
.Diag(ELoc
, diag::err_omp_non_lvalue_in_map_or_motion_clauses
)
20694 << getOpenMPClauseName(CKind
) << ERange
;
20699 bool VisitDeclRefExpr(DeclRefExpr
*DRE
) {
20700 if (!isa
<VarDecl
>(DRE
->getDecl())) {
20704 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20705 RelevantExpr
= DRE
;
20706 // Record the component.
20707 Components
.emplace_back(DRE
, DRE
->getDecl(), IsNonContiguous
);
20711 bool VisitMemberExpr(MemberExpr
*ME
) {
20713 Expr
*BaseE
= ME
->getBase()->IgnoreParenCasts();
20715 if (isa
<CXXThisExpr
>(BaseE
)) {
20716 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20717 // We found a base expression: this->Val.
20723 if (!isa
<FieldDecl
>(ME
->getMemberDecl())) {
20725 SemaRef
.Diag(ELoc
, diag::err_omp_expected_access_to_data_field
)
20726 << ME
->getSourceRange();
20734 auto *FD
= cast
<FieldDecl
>(ME
->getMemberDecl());
20736 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20737 // A bit-field cannot appear in a map clause.
20739 if (FD
->isBitField()) {
20741 SemaRef
.Diag(ELoc
, diag::err_omp_bit_fields_forbidden_in_clause
)
20742 << ME
->getSourceRange() << getOpenMPClauseName(CKind
);
20750 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20751 // If the type of a list item is a reference to a type T then the type
20752 // will be considered to be T for all purposes of this clause.
20753 QualType CurType
= BaseE
->getType().getNonReferenceType();
20755 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20756 // A list item cannot be a variable that is a member of a structure with
20759 if (CurType
->isUnionType()) {
20761 SemaRef
.Diag(ELoc
, diag::err_omp_union_type_not_allowed
)
20762 << ME
->getSourceRange();
20765 return RelevantExpr
|| Visit(E
);
20768 // If we got a member expression, we should not expect any array section
20771 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20772 // If a list item is an element of a structure, only the rightmost symbol
20773 // of the variable reference can be an array section.
20775 AllowUnitySizeArraySection
= false;
20776 AllowWholeSizeArraySection
= false;
20778 // Record the component.
20779 Components
.emplace_back(ME
, FD
, IsNonContiguous
);
20780 return RelevantExpr
|| Visit(E
);
20783 bool VisitArraySubscriptExpr(ArraySubscriptExpr
*AE
) {
20784 Expr
*E
= AE
->getBase()->IgnoreParenImpCasts();
20786 if (!E
->getType()->isAnyPointerType() && !E
->getType()->isArrayType()) {
20788 SemaRef
.Diag(ELoc
, diag::err_omp_expected_base_var_name
)
20789 << 0 << AE
->getSourceRange();
20792 return RelevantExpr
|| Visit(E
);
20795 // If we got an array subscript that express the whole dimension we
20796 // can have any array expressions before. If it only expressing part of
20797 // the dimension, we can only have unitary-size array expressions.
20798 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef
, AE
, E
->getType()))
20799 AllowWholeSizeArraySection
= false;
20801 if (const auto *TE
= dyn_cast
<CXXThisExpr
>(E
->IgnoreParenCasts())) {
20802 Expr::EvalResult Result
;
20803 if (!AE
->getIdx()->isValueDependent() &&
20804 AE
->getIdx()->EvaluateAsInt(Result
, SemaRef
.getASTContext()) &&
20805 !Result
.Val
.getInt().isZero()) {
20806 SemaRef
.Diag(AE
->getIdx()->getExprLoc(),
20807 diag::err_omp_invalid_map_this_expr
);
20808 SemaRef
.Diag(AE
->getIdx()->getExprLoc(),
20809 diag::note_omp_invalid_subscript_on_this_ptr_map
);
20811 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20815 // Record the component - we don't have any declaration associated.
20816 Components
.emplace_back(AE
, nullptr, IsNonContiguous
);
20818 return RelevantExpr
|| Visit(E
);
20821 bool VisitOMPArraySectionExpr(OMPArraySectionExpr
*OASE
) {
20822 // After OMP 5.0 Array section in reduction clause will be implicitly
20824 assert(!(SemaRef
.getLangOpts().OpenMP
< 50 && NoDiagnose
) &&
20825 "Array sections cannot be implicitly mapped.");
20826 Expr
*E
= OASE
->getBase()->IgnoreParenImpCasts();
20828 OMPArraySectionExpr::getBaseOriginalType(E
).getCanonicalType();
20830 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20831 // If the type of a list item is a reference to a type T then the type
20832 // will be considered to be T for all purposes of this clause.
20833 if (CurType
->isReferenceType())
20834 CurType
= CurType
->getPointeeType();
20836 bool IsPointer
= CurType
->isAnyPointerType();
20838 if (!IsPointer
&& !CurType
->isArrayType()) {
20839 SemaRef
.Diag(ELoc
, diag::err_omp_expected_base_var_name
)
20840 << 0 << OASE
->getSourceRange();
20845 checkArrayExpressionDoesNotReferToWholeSize(SemaRef
, OASE
, CurType
);
20847 checkArrayExpressionDoesNotReferToUnitySize(SemaRef
, OASE
, CurType
);
20849 if (AllowWholeSizeArraySection
) {
20850 // Any array section is currently allowed. Allowing a whole size array
20851 // section implies allowing a unity array section as well.
20853 // If this array section refers to the whole dimension we can still
20854 // accept other array sections before this one, except if the base is a
20855 // pointer. Otherwise, only unitary sections are accepted.
20856 if (NotWhole
|| IsPointer
)
20857 AllowWholeSizeArraySection
= false;
20858 } else if (DKind
== OMPD_target_update
&&
20859 SemaRef
.getLangOpts().OpenMP
>= 50) {
20860 if (IsPointer
&& !AllowAnotherPtr
)
20861 SemaRef
.Diag(ELoc
, diag::err_omp_section_length_undefined
)
20862 << /*array of unknown bound */ 1;
20864 IsNonContiguous
= true;
20865 } else if (AllowUnitySizeArraySection
&& NotUnity
) {
20866 // A unity or whole array section is not allowed and that is not
20867 // compatible with the properties of the current array section.
20871 diag::err_array_section_does_not_specify_contiguous_storage
)
20872 << OASE
->getSourceRange();
20877 AllowAnotherPtr
= false;
20879 if (const auto *TE
= dyn_cast
<CXXThisExpr
>(E
)) {
20880 Expr::EvalResult ResultR
;
20881 Expr::EvalResult ResultL
;
20882 if (!OASE
->getLength()->isValueDependent() &&
20883 OASE
->getLength()->EvaluateAsInt(ResultR
, SemaRef
.getASTContext()) &&
20884 !ResultR
.Val
.getInt().isOne()) {
20885 SemaRef
.Diag(OASE
->getLength()->getExprLoc(),
20886 diag::err_omp_invalid_map_this_expr
);
20887 SemaRef
.Diag(OASE
->getLength()->getExprLoc(),
20888 diag::note_omp_invalid_length_on_this_ptr_mapping
);
20890 if (OASE
->getLowerBound() && !OASE
->getLowerBound()->isValueDependent() &&
20891 OASE
->getLowerBound()->EvaluateAsInt(ResultL
,
20892 SemaRef
.getASTContext()) &&
20893 !ResultL
.Val
.getInt().isZero()) {
20894 SemaRef
.Diag(OASE
->getLowerBound()->getExprLoc(),
20895 diag::err_omp_invalid_map_this_expr
);
20896 SemaRef
.Diag(OASE
->getLowerBound()->getExprLoc(),
20897 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping
);
20899 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20903 // Record the component - we don't have any declaration associated.
20904 Components
.emplace_back(OASE
, nullptr, /*IsNonContiguous=*/false);
20905 return RelevantExpr
|| Visit(E
);
20907 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr
*E
) {
20908 Expr
*Base
= E
->getBase();
20910 // Record the component - we don't have any declaration associated.
20911 Components
.emplace_back(E
, nullptr, IsNonContiguous
);
20913 return Visit(Base
->IgnoreParenImpCasts());
20916 bool VisitUnaryOperator(UnaryOperator
*UO
) {
20917 if (SemaRef
.getLangOpts().OpenMP
< 50 || !UO
->isLValue() ||
20918 UO
->getOpcode() != UO_Deref
) {
20922 if (!RelevantExpr
) {
20923 // Record the component if haven't found base decl.
20924 Components
.emplace_back(UO
, nullptr, /*IsNonContiguous=*/false);
20926 return RelevantExpr
|| Visit(UO
->getSubExpr()->IgnoreParenImpCasts());
20928 bool VisitBinaryOperator(BinaryOperator
*BO
) {
20929 if (SemaRef
.getLangOpts().OpenMP
< 50 || !BO
->getType()->isPointerType()) {
20934 // Pointer arithmetic is the only thing we expect to happen here so after we
20935 // make sure the binary operator is a pointer type, the we only thing need
20936 // to to is to visit the subtree that has the same type as root (so that we
20937 // know the other subtree is just an offset)
20938 Expr
*LE
= BO
->getLHS()->IgnoreParenImpCasts();
20939 Expr
*RE
= BO
->getRHS()->IgnoreParenImpCasts();
20940 Components
.emplace_back(BO
, nullptr, false);
20941 assert((LE
->getType().getTypePtr() == BO
->getType().getTypePtr() ||
20942 RE
->getType().getTypePtr() == BO
->getType().getTypePtr()) &&
20943 "Either LHS or RHS have base decl inside");
20944 if (BO
->getType().getTypePtr() == LE
->getType().getTypePtr())
20945 return RelevantExpr
|| Visit(LE
);
20946 return RelevantExpr
|| Visit(RE
);
20948 bool VisitCXXThisExpr(CXXThisExpr
*CTE
) {
20949 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20950 RelevantExpr
= CTE
;
20951 Components
.emplace_back(CTE
, nullptr, IsNonContiguous
);
20954 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr
*COCE
) {
20955 assert(!RelevantExpr
&& "RelevantExpr is expected to be nullptr");
20956 Components
.emplace_back(COCE
, nullptr, IsNonContiguous
);
20959 bool VisitOpaqueValueExpr(OpaqueValueExpr
*E
) {
20960 Expr
*Source
= E
->getSourceExpr();
20965 return Visit(Source
);
20967 bool VisitStmt(Stmt
*) {
20971 const Expr
*getFoundBase() const { return RelevantExpr
; }
20972 explicit MapBaseChecker(
20973 Sema
&SemaRef
, OpenMPClauseKind CKind
, OpenMPDirectiveKind DKind
,
20974 OMPClauseMappableExprCommon::MappableExprComponentList
&Components
,
20975 bool NoDiagnose
, SourceLocation
&ELoc
, SourceRange
&ERange
)
20976 : SemaRef(SemaRef
), CKind(CKind
), DKind(DKind
), Components(Components
),
20977 NoDiagnose(NoDiagnose
), ELoc(ELoc
), ERange(ERange
) {}
20981 /// Return the expression of the base of the mappable expression or null if it
20982 /// cannot be determined and do all the necessary checks to see if the
20983 /// expression is valid as a standalone mappable expression. In the process,
20984 /// record all the components of the expression.
20985 static const Expr
*checkMapClauseExpressionBase(
20986 Sema
&SemaRef
, Expr
*E
,
20987 OMPClauseMappableExprCommon::MappableExprComponentList
&CurComponents
,
20988 OpenMPClauseKind CKind
, OpenMPDirectiveKind DKind
, bool NoDiagnose
) {
20989 SourceLocation ELoc
= E
->getExprLoc();
20990 SourceRange ERange
= E
->getSourceRange();
20991 MapBaseChecker
Checker(SemaRef
, CKind
, DKind
, CurComponents
, NoDiagnose
, ELoc
,
20993 if (Checker
.Visit(E
->IgnoreParens())) {
20994 // Check if the highest dimension array section has length specified
20995 if (SemaRef
.getLangOpts().OpenMP
>= 50 && !CurComponents
.empty() &&
20996 (CKind
== OMPC_to
|| CKind
== OMPC_from
)) {
20997 auto CI
= CurComponents
.rbegin();
20998 auto CE
= CurComponents
.rend();
20999 for (; CI
!= CE
; ++CI
) {
21001 dyn_cast
<OMPArraySectionExpr
>(CI
->getAssociatedExpression());
21004 if (OASE
&& OASE
->getLength())
21006 SemaRef
.Diag(ELoc
, diag::err_array_section_does_not_specify_length
)
21010 return Checker
.getFoundBase();
21015 // Return true if expression E associated with value VD has conflicts with other
21016 // map information.
21017 static bool checkMapConflicts(
21018 Sema
&SemaRef
, DSAStackTy
*DSAS
, const ValueDecl
*VD
, const Expr
*E
,
21019 bool CurrentRegionOnly
,
21020 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents
,
21021 OpenMPClauseKind CKind
) {
21023 SourceLocation ELoc
= E
->getExprLoc();
21024 SourceRange ERange
= E
->getSourceRange();
21026 // In order to easily check the conflicts we need to match each component of
21027 // the expression under test with the components of the expressions that are
21028 // already in the stack.
21030 assert(!CurComponents
.empty() && "Map clause expression with no components!");
21031 assert(CurComponents
.back().getAssociatedDeclaration() == VD
&&
21032 "Map clause expression with unexpected base!");
21034 // Variables to help detecting enclosing problems in data environment nests.
21035 bool IsEnclosedByDataEnvironmentExpr
= false;
21036 const Expr
*EnclosingExpr
= nullptr;
21038 bool FoundError
= DSAS
->checkMappableExprComponentListsForDecl(
21039 VD
, CurrentRegionOnly
,
21040 [&IsEnclosedByDataEnvironmentExpr
, &SemaRef
, VD
, CurrentRegionOnly
, ELoc
,
21041 ERange
, CKind
, &EnclosingExpr
,
21042 CurComponents
](OMPClauseMappableExprCommon::MappableExprComponentListRef
21044 OpenMPClauseKind Kind
) {
21045 if (CKind
== Kind
&& SemaRef
.LangOpts
.OpenMP
>= 50)
21047 assert(!StackComponents
.empty() &&
21048 "Map clause expression with no components!");
21049 assert(StackComponents
.back().getAssociatedDeclaration() == VD
&&
21050 "Map clause expression with unexpected base!");
21053 // The whole expression in the stack.
21054 const Expr
*RE
= StackComponents
.front().getAssociatedExpression();
21056 // Expressions must start from the same base. Here we detect at which
21057 // point both expressions diverge from each other and see if we can
21058 // detect if the memory referred to both expressions is contiguous and
21060 auto CI
= CurComponents
.rbegin();
21061 auto CE
= CurComponents
.rend();
21062 auto SI
= StackComponents
.rbegin();
21063 auto SE
= StackComponents
.rend();
21064 for (; CI
!= CE
&& SI
!= SE
; ++CI
, ++SI
) {
21066 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21067 // At most one list item can be an array item derived from a given
21068 // variable in map clauses of the same construct.
21069 if (CurrentRegionOnly
&&
21070 (isa
<ArraySubscriptExpr
>(CI
->getAssociatedExpression()) ||
21071 isa
<OMPArraySectionExpr
>(CI
->getAssociatedExpression()) ||
21072 isa
<OMPArrayShapingExpr
>(CI
->getAssociatedExpression())) &&
21073 (isa
<ArraySubscriptExpr
>(SI
->getAssociatedExpression()) ||
21074 isa
<OMPArraySectionExpr
>(SI
->getAssociatedExpression()) ||
21075 isa
<OMPArrayShapingExpr
>(SI
->getAssociatedExpression()))) {
21076 SemaRef
.Diag(CI
->getAssociatedExpression()->getExprLoc(),
21077 diag::err_omp_multiple_array_items_in_map_clause
)
21078 << CI
->getAssociatedExpression()->getSourceRange();
21079 SemaRef
.Diag(SI
->getAssociatedExpression()->getExprLoc(),
21080 diag::note_used_here
)
21081 << SI
->getAssociatedExpression()->getSourceRange();
21085 // Do both expressions have the same kind?
21086 if (CI
->getAssociatedExpression()->getStmtClass() !=
21087 SI
->getAssociatedExpression()->getStmtClass())
21090 // Are we dealing with different variables/fields?
21091 if (CI
->getAssociatedDeclaration() != SI
->getAssociatedDeclaration())
21094 // Check if the extra components of the expressions in the enclosing
21095 // data environment are redundant for the current base declaration.
21096 // If they are, the maps completely overlap, which is legal.
21097 for (; SI
!= SE
; ++SI
) {
21099 if (const auto *ASE
=
21100 dyn_cast
<ArraySubscriptExpr
>(SI
->getAssociatedExpression())) {
21101 Type
= ASE
->getBase()->IgnoreParenImpCasts()->getType();
21102 } else if (const auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(
21103 SI
->getAssociatedExpression())) {
21104 const Expr
*E
= OASE
->getBase()->IgnoreParenImpCasts();
21106 OMPArraySectionExpr::getBaseOriginalType(E
).getCanonicalType();
21107 } else if (const auto *OASE
= dyn_cast
<OMPArrayShapingExpr
>(
21108 SI
->getAssociatedExpression())) {
21109 Type
= OASE
->getBase()->getType()->getPointeeType();
21111 if (Type
.isNull() || Type
->isAnyPointerType() ||
21112 checkArrayExpressionDoesNotReferToWholeSize(
21113 SemaRef
, SI
->getAssociatedExpression(), Type
))
21117 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21118 // List items of map clauses in the same construct must not share
21119 // original storage.
21121 // If the expressions are exactly the same or one is a subset of the
21122 // other, it means they are sharing storage.
21123 if (CI
== CE
&& SI
== SE
) {
21124 if (CurrentRegionOnly
) {
21125 if (CKind
== OMPC_map
) {
21126 SemaRef
.Diag(ELoc
, diag::err_omp_map_shared_storage
) << ERange
;
21128 assert(CKind
== OMPC_to
|| CKind
== OMPC_from
);
21129 SemaRef
.Diag(ELoc
, diag::err_omp_once_referenced_in_target_update
)
21132 SemaRef
.Diag(RE
->getExprLoc(), diag::note_used_here
)
21133 << RE
->getSourceRange();
21136 // If we find the same expression in the enclosing data environment,
21138 IsEnclosedByDataEnvironmentExpr
= true;
21142 QualType DerivedType
=
21143 std::prev(CI
)->getAssociatedDeclaration()->getType();
21144 SourceLocation DerivedLoc
=
21145 std::prev(CI
)->getAssociatedExpression()->getExprLoc();
21147 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21148 // If the type of a list item is a reference to a type T then the type
21149 // will be considered to be T for all purposes of this clause.
21150 DerivedType
= DerivedType
.getNonReferenceType();
21152 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21153 // A variable for which the type is pointer and an array section
21154 // derived from that variable must not appear as list items of map
21155 // clauses of the same construct.
21157 // Also, cover one of the cases in:
21158 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21159 // If any part of the original storage of a list item has corresponding
21160 // storage in the device data environment, all of the original storage
21161 // must have corresponding storage in the device data environment.
21163 if (DerivedType
->isAnyPointerType()) {
21164 if (CI
== CE
|| SI
== SE
) {
21167 diag::err_omp_pointer_mapped_along_with_derived_section
)
21169 SemaRef
.Diag(RE
->getExprLoc(), diag::note_used_here
)
21170 << RE
->getSourceRange();
21173 if (CI
->getAssociatedExpression()->getStmtClass() !=
21174 SI
->getAssociatedExpression()->getStmtClass() ||
21175 CI
->getAssociatedDeclaration()->getCanonicalDecl() ==
21176 SI
->getAssociatedDeclaration()->getCanonicalDecl()) {
21177 assert(CI
!= CE
&& SI
!= SE
);
21178 SemaRef
.Diag(DerivedLoc
, diag::err_omp_same_pointer_dereferenced
)
21180 SemaRef
.Diag(RE
->getExprLoc(), diag::note_used_here
)
21181 << RE
->getSourceRange();
21186 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21187 // List items of map clauses in the same construct must not share
21188 // original storage.
21190 // An expression is a subset of the other.
21191 if (CurrentRegionOnly
&& (CI
== CE
|| SI
== SE
)) {
21192 if (CKind
== OMPC_map
) {
21193 if (CI
!= CE
|| SI
!= SE
) {
21194 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21197 CI
!= CE
? CurComponents
.begin() : StackComponents
.begin();
21198 auto End
= CI
!= CE
? CurComponents
.end() : StackComponents
.end();
21200 while (It
!= End
&& !It
->getAssociatedDeclaration())
21201 std::advance(It
, 1);
21202 assert(It
!= End
&&
21203 "Expected at least one component with the declaration.");
21204 if (It
!= Begin
&& It
->getAssociatedDeclaration()
21206 .getCanonicalType()
21207 ->isAnyPointerType()) {
21208 IsEnclosedByDataEnvironmentExpr
= false;
21209 EnclosingExpr
= nullptr;
21213 SemaRef
.Diag(ELoc
, diag::err_omp_map_shared_storage
) << ERange
;
21215 assert(CKind
== OMPC_to
|| CKind
== OMPC_from
);
21216 SemaRef
.Diag(ELoc
, diag::err_omp_once_referenced_in_target_update
)
21219 SemaRef
.Diag(RE
->getExprLoc(), diag::note_used_here
)
21220 << RE
->getSourceRange();
21224 // The current expression uses the same base as other expression in the
21225 // data environment but does not contain it completely.
21226 if (!CurrentRegionOnly
&& SI
!= SE
)
21227 EnclosingExpr
= RE
;
21229 // The current expression is a subset of the expression in the data
21231 IsEnclosedByDataEnvironmentExpr
|=
21232 (!CurrentRegionOnly
&& CI
!= CE
&& SI
== SE
);
21237 if (CurrentRegionOnly
)
21240 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21241 // If any part of the original storage of a list item has corresponding
21242 // storage in the device data environment, all of the original storage must
21243 // have corresponding storage in the device data environment.
21244 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21245 // If a list item is an element of a structure, and a different element of
21246 // the structure has a corresponding list item in the device data environment
21247 // prior to a task encountering the construct associated with the map clause,
21248 // then the list item must also have a corresponding list item in the device
21249 // data environment prior to the task encountering the construct.
21251 if (EnclosingExpr
&& !IsEnclosedByDataEnvironmentExpr
) {
21253 diag::err_omp_original_storage_is_shared_and_does_not_contain
)
21255 SemaRef
.Diag(EnclosingExpr
->getExprLoc(), diag::note_used_here
)
21256 << EnclosingExpr
->getSourceRange();
21263 // Look up the user-defined mapper given the mapper name and mapped type, and
21264 // build a reference to it.
21265 static ExprResult
buildUserDefinedMapperRef(Sema
&SemaRef
, Scope
*S
,
21266 CXXScopeSpec
&MapperIdScopeSpec
,
21267 const DeclarationNameInfo
&MapperId
,
21269 Expr
*UnresolvedMapper
) {
21270 if (MapperIdScopeSpec
.isInvalid())
21271 return ExprError();
21272 // Get the actual type for the array type.
21273 if (Type
->isArrayType()) {
21274 assert(Type
->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21275 Type
= Type
->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21277 // Find all user-defined mappers with the given MapperId.
21278 SmallVector
<UnresolvedSet
<8>, 4> Lookups
;
21279 LookupResult
Lookup(SemaRef
, MapperId
, Sema::LookupOMPMapperName
);
21280 Lookup
.suppressDiagnostics();
21282 while (S
&& SemaRef
.LookupParsedName(Lookup
, S
, &MapperIdScopeSpec
)) {
21283 NamedDecl
*D
= Lookup
.getRepresentativeDecl();
21284 while (S
&& !S
->isDeclScope(D
))
21285 S
= S
->getParent();
21287 S
= S
->getParent();
21288 Lookups
.emplace_back();
21289 Lookups
.back().append(Lookup
.begin(), Lookup
.end());
21292 } else if (auto *ULE
= cast_or_null
<UnresolvedLookupExpr
>(UnresolvedMapper
)) {
21293 // Extract the user-defined mappers with the given MapperId.
21294 Lookups
.push_back(UnresolvedSet
<8>());
21295 for (NamedDecl
*D
: ULE
->decls()) {
21296 auto *DMD
= cast
<OMPDeclareMapperDecl
>(D
);
21297 assert(DMD
&& "Expect valid OMPDeclareMapperDecl during instantiation.");
21298 Lookups
.back().addDecl(DMD
);
21301 // Defer the lookup for dependent types. The results will be passed through
21302 // UnresolvedMapper on instantiation.
21303 if (SemaRef
.CurContext
->isDependentContext() || Type
->isDependentType() ||
21304 Type
->isInstantiationDependentType() ||
21305 Type
->containsUnexpandedParameterPack() ||
21306 filterLookupForUDReductionAndMapper
<bool>(Lookups
, [](ValueDecl
*D
) {
21307 return !D
->isInvalidDecl() &&
21308 (D
->getType()->isDependentType() ||
21309 D
->getType()->isInstantiationDependentType() ||
21310 D
->getType()->containsUnexpandedParameterPack());
21312 UnresolvedSet
<8> URS
;
21313 for (const UnresolvedSet
<8> &Set
: Lookups
) {
21316 URS
.append(Set
.begin(), Set
.end());
21318 return UnresolvedLookupExpr::Create(
21319 SemaRef
.Context
, /*NamingClass=*/nullptr,
21320 MapperIdScopeSpec
.getWithLocInContext(SemaRef
.Context
), MapperId
,
21321 /*ADL=*/false, /*Overloaded=*/true, URS
.begin(), URS
.end());
21323 SourceLocation Loc
= MapperId
.getLoc();
21324 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21325 // The type must be of struct, union or class type in C and C++
21326 if (!Type
->isStructureOrClassType() && !Type
->isUnionType() &&
21327 (MapperIdScopeSpec
.isSet() || MapperId
.getAsString() != "default")) {
21328 SemaRef
.Diag(Loc
, diag::err_omp_mapper_wrong_type
);
21329 return ExprError();
21331 // Perform argument dependent lookup.
21332 if (SemaRef
.getLangOpts().CPlusPlus
&& !MapperIdScopeSpec
.isSet())
21333 argumentDependentLookup(SemaRef
, MapperId
, Loc
, Type
, Lookups
);
21334 // Return the first user-defined mapper with the desired type.
21335 if (auto *VD
= filterLookupForUDReductionAndMapper
<ValueDecl
*>(
21336 Lookups
, [&SemaRef
, Type
](ValueDecl
*D
) -> ValueDecl
* {
21337 if (!D
->isInvalidDecl() &&
21338 SemaRef
.Context
.hasSameType(D
->getType(), Type
))
21342 return SemaRef
.BuildDeclRefExpr(VD
, Type
, VK_LValue
, Loc
);
21343 // Find the first user-defined mapper with a type derived from the desired
21345 if (auto *VD
= filterLookupForUDReductionAndMapper
<ValueDecl
*>(
21346 Lookups
, [&SemaRef
, Type
, Loc
](ValueDecl
*D
) -> ValueDecl
* {
21347 if (!D
->isInvalidDecl() &&
21348 SemaRef
.IsDerivedFrom(Loc
, Type
, D
->getType()) &&
21349 !Type
.isMoreQualifiedThan(D
->getType()))
21353 CXXBasePaths
Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21354 /*DetectVirtual=*/false);
21355 if (SemaRef
.IsDerivedFrom(Loc
, Type
, VD
->getType(), Paths
)) {
21356 if (!Paths
.isAmbiguous(SemaRef
.Context
.getCanonicalType(
21357 VD
->getType().getUnqualifiedType()))) {
21358 if (SemaRef
.CheckBaseClassAccess(
21359 Loc
, VD
->getType(), Type
, Paths
.front(),
21360 /*DiagID=*/0) != Sema::AR_inaccessible
) {
21361 return SemaRef
.BuildDeclRefExpr(VD
, Type
, VK_LValue
, Loc
);
21366 // Report error if a mapper is specified, but cannot be found.
21367 if (MapperIdScopeSpec
.isSet() || MapperId
.getAsString() != "default") {
21368 SemaRef
.Diag(Loc
, diag::err_omp_invalid_mapper
)
21369 << Type
<< MapperId
.getName();
21370 return ExprError();
21372 return ExprEmpty();
21376 // Utility struct that gathers all the related lists associated with a mappable
21378 struct MappableVarListInfo
{
21379 // The list of expressions.
21380 ArrayRef
<Expr
*> VarList
;
21381 // The list of processed expressions.
21382 SmallVector
<Expr
*, 16> ProcessedVarList
;
21383 // The mappble components for each expression.
21384 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents
;
21385 // The base declaration of the variable.
21386 SmallVector
<ValueDecl
*, 16> VarBaseDeclarations
;
21387 // The reference to the user-defined mapper associated with every expression.
21388 SmallVector
<Expr
*, 16> UDMapperList
;
21390 MappableVarListInfo(ArrayRef
<Expr
*> VarList
) : VarList(VarList
) {
21391 // We have a list of components and base declarations for each entry in the
21393 VarComponents
.reserve(VarList
.size());
21394 VarBaseDeclarations
.reserve(VarList
.size());
21399 // Check the validity of the provided variable list for the provided clause kind
21400 // \a CKind. In the check process the valid expressions, mappable expression
21401 // components, variables, and user-defined mappers are extracted and used to
21402 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21403 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21404 // and \a MapperId are expected to be valid if the clause kind is 'map'.
21405 static void checkMappableExpressionList(
21406 Sema
&SemaRef
, DSAStackTy
*DSAS
, OpenMPClauseKind CKind
,
21407 MappableVarListInfo
&MVLI
, SourceLocation StartLoc
,
21408 CXXScopeSpec
&MapperIdScopeSpec
, DeclarationNameInfo MapperId
,
21409 ArrayRef
<Expr
*> UnresolvedMappers
,
21410 OpenMPMapClauseKind MapType
= OMPC_MAP_unknown
,
21411 ArrayRef
<OpenMPMapModifierKind
> Modifiers
= None
,
21412 bool IsMapTypeImplicit
= false, bool NoDiagnose
= false) {
21413 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21414 assert((CKind
== OMPC_map
|| CKind
== OMPC_to
|| CKind
== OMPC_from
) &&
21415 "Unexpected clause kind with mappable expressions!");
21417 // If the identifier of user-defined mapper is not specified, it is "default".
21418 // We do not change the actual name in this clause to distinguish whether a
21419 // mapper is specified explicitly, i.e., it is not explicitly specified when
21420 // MapperId.getName() is empty.
21421 if (!MapperId
.getName() || MapperId
.getName().isEmpty()) {
21422 auto &DeclNames
= SemaRef
.getASTContext().DeclarationNames
;
21423 MapperId
.setName(DeclNames
.getIdentifier(
21424 &SemaRef
.getASTContext().Idents
.get("default")));
21425 MapperId
.setLoc(StartLoc
);
21428 // Iterators to find the current unresolved mapper expression.
21429 auto UMIt
= UnresolvedMappers
.begin(), UMEnd
= UnresolvedMappers
.end();
21430 bool UpdateUMIt
= false;
21431 Expr
*UnresolvedMapper
= nullptr;
21433 bool HasHoldModifier
=
21434 llvm::is_contained(Modifiers
, OMPC_MAP_MODIFIER_ompx_hold
);
21436 // Keep track of the mappable components and base declarations in this clause.
21437 // Each entry in the list is going to have a list of components associated. We
21438 // record each set of the components so that we can build the clause later on.
21439 // In the end we should have the same amount of declarations and component
21442 for (Expr
*RE
: MVLI
.VarList
) {
21443 assert(RE
&& "Null expr in omp to/from/map clause");
21444 SourceLocation ELoc
= RE
->getExprLoc();
21446 // Find the current unresolved mapper expression.
21447 if (UpdateUMIt
&& UMIt
!= UMEnd
) {
21451 "Expect the size of UnresolvedMappers to match with that of VarList");
21455 UnresolvedMapper
= *UMIt
;
21457 const Expr
*VE
= RE
->IgnoreParenLValueCasts();
21459 if (VE
->isValueDependent() || VE
->isTypeDependent() ||
21460 VE
->isInstantiationDependent() ||
21461 VE
->containsUnexpandedParameterPack()) {
21462 // Try to find the associated user-defined mapper.
21463 ExprResult ER
= buildUserDefinedMapperRef(
21464 SemaRef
, DSAS
->getCurScope(), MapperIdScopeSpec
, MapperId
,
21465 VE
->getType().getCanonicalType(), UnresolvedMapper
);
21466 if (ER
.isInvalid())
21468 MVLI
.UDMapperList
.push_back(ER
.get());
21469 // We can only analyze this information once the missing information is
21471 MVLI
.ProcessedVarList
.push_back(RE
);
21475 Expr
*SimpleExpr
= RE
->IgnoreParenCasts();
21477 if (!RE
->isLValue()) {
21478 if (SemaRef
.getLangOpts().OpenMP
< 50) {
21480 ELoc
, diag::err_omp_expected_named_var_member_or_array_expression
)
21481 << RE
->getSourceRange();
21483 SemaRef
.Diag(ELoc
, diag::err_omp_non_lvalue_in_map_or_motion_clauses
)
21484 << getOpenMPClauseName(CKind
) << RE
->getSourceRange();
21489 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents
;
21490 ValueDecl
*CurDeclaration
= nullptr;
21492 // Obtain the array or member expression bases if required. Also, fill the
21493 // components array with all the components identified in the process.
21495 checkMapClauseExpressionBase(SemaRef
, SimpleExpr
, CurComponents
, CKind
,
21496 DSAS
->getCurrentDirective(), NoDiagnose
);
21500 assert(!CurComponents
.empty() &&
21501 "Invalid mappable expression information.");
21503 if (const auto *TE
= dyn_cast
<CXXThisExpr
>(BE
)) {
21504 // Add store "this" pointer to class in DSAStackTy for future checking
21505 DSAS
->addMappedClassesQualTypes(TE
->getType());
21506 // Try to find the associated user-defined mapper.
21507 ExprResult ER
= buildUserDefinedMapperRef(
21508 SemaRef
, DSAS
->getCurScope(), MapperIdScopeSpec
, MapperId
,
21509 VE
->getType().getCanonicalType(), UnresolvedMapper
);
21510 if (ER
.isInvalid())
21512 MVLI
.UDMapperList
.push_back(ER
.get());
21513 // Skip restriction checking for variable or field declarations
21514 MVLI
.ProcessedVarList
.push_back(RE
);
21515 MVLI
.VarComponents
.resize(MVLI
.VarComponents
.size() + 1);
21516 MVLI
.VarComponents
.back().append(CurComponents
.begin(),
21517 CurComponents
.end());
21518 MVLI
.VarBaseDeclarations
.push_back(nullptr);
21522 // For the following checks, we rely on the base declaration which is
21523 // expected to be associated with the last component. The declaration is
21524 // expected to be a variable or a field (if 'this' is being mapped).
21525 CurDeclaration
= CurComponents
.back().getAssociatedDeclaration();
21526 assert(CurDeclaration
&& "Null decl on map clause.");
21528 CurDeclaration
->isCanonicalDecl() &&
21529 "Expecting components to have associated only canonical declarations.");
21531 auto *VD
= dyn_cast
<VarDecl
>(CurDeclaration
);
21532 const auto *FD
= dyn_cast
<FieldDecl
>(CurDeclaration
);
21534 assert((VD
|| FD
) && "Only variables or fields are expected here!");
21537 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21538 // threadprivate variables cannot appear in a map clause.
21539 // OpenMP 4.5 [2.10.5, target update Construct]
21540 // threadprivate variables cannot appear in a from clause.
21541 if (VD
&& DSAS
->isThreadPrivate(VD
)) {
21544 DSAStackTy::DSAVarData DVar
= DSAS
->getTopDSA(VD
, /*FromParent=*/false);
21545 SemaRef
.Diag(ELoc
, diag::err_omp_threadprivate_in_clause
)
21546 << getOpenMPClauseName(CKind
);
21547 reportOriginalDsa(SemaRef
, DSAS
, VD
, DVar
);
21551 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21552 // A list item cannot appear in both a map clause and a data-sharing
21553 // attribute clause on the same construct.
21555 // Check conflicts with other map clause expressions. We check the conflicts
21556 // with the current construct separately from the enclosing data
21557 // environment, because the restrictions are different. We only have to
21558 // check conflicts across regions for the map clauses.
21559 if (checkMapConflicts(SemaRef
, DSAS
, CurDeclaration
, SimpleExpr
,
21560 /*CurrentRegionOnly=*/true, CurComponents
, CKind
))
21562 if (CKind
== OMPC_map
&&
21563 (SemaRef
.getLangOpts().OpenMP
<= 45 || StartLoc
.isValid()) &&
21564 checkMapConflicts(SemaRef
, DSAS
, CurDeclaration
, SimpleExpr
,
21565 /*CurrentRegionOnly=*/false, CurComponents
, CKind
))
21568 // OpenMP 4.5 [2.10.5, target update Construct]
21569 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21570 // If the type of a list item is a reference to a type T then the type will
21571 // be considered to be T for all purposes of this clause.
21572 auto I
= llvm::find_if(
21574 [](const OMPClauseMappableExprCommon::MappableComponent
&MC
) {
21575 return MC
.getAssociatedDeclaration();
21577 assert(I
!= CurComponents
.end() && "Null decl on map clause.");
21580 auto *ASE
= dyn_cast
<ArraySubscriptExpr
>(VE
->IgnoreParens());
21581 auto *OASE
= dyn_cast
<OMPArraySectionExpr
>(VE
->IgnoreParens());
21582 auto *OAShE
= dyn_cast
<OMPArrayShapingExpr
>(VE
->IgnoreParens());
21584 Type
= ASE
->getType().getNonReferenceType();
21586 QualType BaseType
=
21587 OMPArraySectionExpr::getBaseOriginalType(OASE
->getBase());
21588 if (const auto *ATy
= BaseType
->getAsArrayTypeUnsafe())
21589 Type
= ATy
->getElementType();
21591 Type
= BaseType
->getPointeeType();
21592 Type
= Type
.getNonReferenceType();
21593 } else if (OAShE
) {
21594 Type
= OAShE
->getBase()->getType()->getPointeeType();
21596 Type
= VE
->getType();
21599 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21600 // A list item in a to or from clause must have a mappable type.
21601 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21602 // A list item must have a mappable type.
21603 if (!checkTypeMappable(VE
->getExprLoc(), VE
->getSourceRange(), SemaRef
,
21604 DSAS
, Type
, /*FullCheck=*/true))
21607 if (CKind
== OMPC_map
) {
21608 // target enter data
21609 // OpenMP [2.10.2, Restrictions, p. 99]
21610 // A map-type must be specified in all map clauses and must be either
21612 OpenMPDirectiveKind DKind
= DSAS
->getCurrentDirective();
21613 if (DKind
== OMPD_target_enter_data
&&
21614 !(MapType
== OMPC_MAP_to
|| MapType
== OMPC_MAP_alloc
)) {
21615 SemaRef
.Diag(StartLoc
, diag::err_omp_invalid_map_type_for_directive
)
21616 << (IsMapTypeImplicit
? 1 : 0)
21617 << getOpenMPSimpleClauseTypeName(OMPC_map
, MapType
)
21618 << getOpenMPDirectiveName(DKind
);
21622 // target exit_data
21623 // OpenMP [2.10.3, Restrictions, p. 102]
21624 // A map-type must be specified in all map clauses and must be either
21625 // from, release, or delete.
21626 if (DKind
== OMPD_target_exit_data
&&
21627 !(MapType
== OMPC_MAP_from
|| MapType
== OMPC_MAP_release
||
21628 MapType
== OMPC_MAP_delete
)) {
21629 SemaRef
.Diag(StartLoc
, diag::err_omp_invalid_map_type_for_directive
)
21630 << (IsMapTypeImplicit
? 1 : 0)
21631 << getOpenMPSimpleClauseTypeName(OMPC_map
, MapType
)
21632 << getOpenMPDirectiveName(DKind
);
21636 // The 'ompx_hold' modifier is specifically intended to be used on a
21637 // 'target' or 'target data' directive to prevent data from being unmapped
21638 // during the associated statement. It is not permitted on a 'target
21639 // enter data' or 'target exit data' directive, which have no associated
21641 if ((DKind
== OMPD_target_enter_data
|| DKind
== OMPD_target_exit_data
) &&
21643 SemaRef
.Diag(StartLoc
,
21644 diag::err_omp_invalid_map_type_modifier_for_directive
)
21645 << getOpenMPSimpleClauseTypeName(OMPC_map
,
21646 OMPC_MAP_MODIFIER_ompx_hold
)
21647 << getOpenMPDirectiveName(DKind
);
21651 // target, target data
21652 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21653 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21654 // A map-type in a map clause must be to, from, tofrom or alloc
21655 if ((DKind
== OMPD_target_data
||
21656 isOpenMPTargetExecutionDirective(DKind
)) &&
21657 !(MapType
== OMPC_MAP_to
|| MapType
== OMPC_MAP_from
||
21658 MapType
== OMPC_MAP_tofrom
|| MapType
== OMPC_MAP_alloc
)) {
21659 SemaRef
.Diag(StartLoc
, diag::err_omp_invalid_map_type_for_directive
)
21660 << (IsMapTypeImplicit
? 1 : 0)
21661 << getOpenMPSimpleClauseTypeName(OMPC_map
, MapType
)
21662 << getOpenMPDirectiveName(DKind
);
21666 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21667 // A list item cannot appear in both a map clause and a data-sharing
21668 // attribute clause on the same construct
21670 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21671 // A list item cannot appear in both a map clause and a data-sharing
21672 // attribute clause on the same construct unless the construct is a
21673 // combined construct.
21674 if (VD
&& ((SemaRef
.LangOpts
.OpenMP
<= 45 &&
21675 isOpenMPTargetExecutionDirective(DKind
)) ||
21676 DKind
== OMPD_target
)) {
21677 DSAStackTy::DSAVarData DVar
= DSAS
->getTopDSA(VD
, /*FromParent=*/false);
21678 if (isOpenMPPrivate(DVar
.CKind
)) {
21679 SemaRef
.Diag(ELoc
, diag::err_omp_variable_in_given_clause_and_dsa
)
21680 << getOpenMPClauseName(DVar
.CKind
)
21681 << getOpenMPClauseName(OMPC_map
)
21682 << getOpenMPDirectiveName(DSAS
->getCurrentDirective());
21683 reportOriginalDsa(SemaRef
, DSAS
, CurDeclaration
, DVar
);
21689 // Try to find the associated user-defined mapper.
21690 ExprResult ER
= buildUserDefinedMapperRef(
21691 SemaRef
, DSAS
->getCurScope(), MapperIdScopeSpec
, MapperId
,
21692 Type
.getCanonicalType(), UnresolvedMapper
);
21693 if (ER
.isInvalid())
21695 MVLI
.UDMapperList
.push_back(ER
.get());
21697 // Save the current expression.
21698 MVLI
.ProcessedVarList
.push_back(RE
);
21700 // Store the components in the stack so that they can be used to check
21701 // against other clauses later on.
21702 DSAS
->addMappableExpressionComponents(CurDeclaration
, CurComponents
,
21703 /*WhereFoundClauseKind=*/OMPC_map
);
21705 // Save the components and declaration to create the clause. For purposes of
21706 // the clause creation, any component list that has has base 'this' uses
21707 // null as base declaration.
21708 MVLI
.VarComponents
.resize(MVLI
.VarComponents
.size() + 1);
21709 MVLI
.VarComponents
.back().append(CurComponents
.begin(),
21710 CurComponents
.end());
21711 MVLI
.VarBaseDeclarations
.push_back(isa
<MemberExpr
>(BE
) ? nullptr
21716 OMPClause
*Sema::ActOnOpenMPMapClause(
21717 ArrayRef
<OpenMPMapModifierKind
> MapTypeModifiers
,
21718 ArrayRef
<SourceLocation
> MapTypeModifiersLoc
,
21719 CXXScopeSpec
&MapperIdScopeSpec
, DeclarationNameInfo
&MapperId
,
21720 OpenMPMapClauseKind MapType
, bool IsMapTypeImplicit
, SourceLocation MapLoc
,
21721 SourceLocation ColonLoc
, ArrayRef
<Expr
*> VarList
,
21722 const OMPVarListLocTy
&Locs
, bool NoDiagnose
,
21723 ArrayRef
<Expr
*> UnresolvedMappers
) {
21724 OpenMPMapModifierKind Modifiers
[] = {
21725 OMPC_MAP_MODIFIER_unknown
, OMPC_MAP_MODIFIER_unknown
,
21726 OMPC_MAP_MODIFIER_unknown
, OMPC_MAP_MODIFIER_unknown
,
21727 OMPC_MAP_MODIFIER_unknown
};
21728 SourceLocation ModifiersLoc
[NumberOfOMPMapClauseModifiers
];
21730 // Process map-type-modifiers, flag errors for duplicate modifiers.
21731 unsigned Count
= 0;
21732 for (unsigned I
= 0, E
= MapTypeModifiers
.size(); I
< E
; ++I
) {
21733 if (MapTypeModifiers
[I
] != OMPC_MAP_MODIFIER_unknown
&&
21734 llvm::is_contained(Modifiers
, MapTypeModifiers
[I
])) {
21735 Diag(MapTypeModifiersLoc
[I
], diag::err_omp_duplicate_map_type_modifier
);
21738 assert(Count
< NumberOfOMPMapClauseModifiers
&&
21739 "Modifiers exceed the allowed number of map type modifiers");
21740 Modifiers
[Count
] = MapTypeModifiers
[I
];
21741 ModifiersLoc
[Count
] = MapTypeModifiersLoc
[I
];
21745 MappableVarListInfo
MVLI(VarList
);
21746 checkMappableExpressionList(*this, DSAStack
, OMPC_map
, MVLI
, Locs
.StartLoc
,
21747 MapperIdScopeSpec
, MapperId
, UnresolvedMappers
,
21748 MapType
, Modifiers
, IsMapTypeImplicit
,
21751 // We need to produce a map clause even if we don't have variables so that
21752 // other diagnostics related with non-existing map clauses are accurate.
21753 return OMPMapClause::Create(Context
, Locs
, MVLI
.ProcessedVarList
,
21754 MVLI
.VarBaseDeclarations
, MVLI
.VarComponents
,
21755 MVLI
.UDMapperList
, Modifiers
, ModifiersLoc
,
21756 MapperIdScopeSpec
.getWithLocInContext(Context
),
21757 MapperId
, MapType
, IsMapTypeImplicit
, MapLoc
);
21760 QualType
Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc
,
21761 TypeResult ParsedType
) {
21762 assert(ParsedType
.isUsable());
21764 QualType ReductionType
= GetTypeFromParser(ParsedType
.get());
21765 if (ReductionType
.isNull())
21768 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21769 // A type name in a declare reduction directive cannot be a function type, an
21770 // array type, a reference type, or a type qualified with const, volatile or
21772 if (ReductionType
.hasQualifiers()) {
21773 Diag(TyLoc
, diag::err_omp_reduction_wrong_type
) << 0;
21777 if (ReductionType
->isFunctionType()) {
21778 Diag(TyLoc
, diag::err_omp_reduction_wrong_type
) << 1;
21781 if (ReductionType
->isReferenceType()) {
21782 Diag(TyLoc
, diag::err_omp_reduction_wrong_type
) << 2;
21785 if (ReductionType
->isArrayType()) {
21786 Diag(TyLoc
, diag::err_omp_reduction_wrong_type
) << 3;
21789 return ReductionType
;
21792 Sema::DeclGroupPtrTy
Sema::ActOnOpenMPDeclareReductionDirectiveStart(
21793 Scope
*S
, DeclContext
*DC
, DeclarationName Name
,
21794 ArrayRef
<std::pair
<QualType
, SourceLocation
>> ReductionTypes
,
21795 AccessSpecifier AS
, Decl
*PrevDeclInScope
) {
21796 SmallVector
<Decl
*, 8> Decls
;
21797 Decls
.reserve(ReductionTypes
.size());
21799 LookupResult
Lookup(*this, Name
, SourceLocation(), LookupOMPReductionName
,
21800 forRedeclarationInCurContext());
21801 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
21802 // A reduction-identifier may not be re-declared in the current scope for the
21803 // same type or for a type that is compatible according to the base language
21805 llvm::DenseMap
<QualType
, SourceLocation
> PreviousRedeclTypes
;
21806 OMPDeclareReductionDecl
*PrevDRD
= nullptr;
21807 bool InCompoundScope
= true;
21808 if (S
!= nullptr) {
21809 // Find previous declaration with the same name not referenced in other
21811 FunctionScopeInfo
*ParentFn
= getEnclosingFunction();
21813 (ParentFn
!= nullptr) && !ParentFn
->CompoundScopes
.empty();
21814 LookupName(Lookup
, S
);
21815 FilterLookupForScope(Lookup
, DC
, S
, /*ConsiderLinkage=*/false,
21816 /*AllowInlineNamespace=*/false);
21817 llvm::DenseMap
<OMPDeclareReductionDecl
*, bool> UsedAsPrevious
;
21818 LookupResult::Filter Filter
= Lookup
.makeFilter();
21819 while (Filter
.hasNext()) {
21820 auto *PrevDecl
= cast
<OMPDeclareReductionDecl
>(Filter
.next());
21821 if (InCompoundScope
) {
21822 auto I
= UsedAsPrevious
.find(PrevDecl
);
21823 if (I
== UsedAsPrevious
.end())
21824 UsedAsPrevious
[PrevDecl
] = false;
21825 if (OMPDeclareReductionDecl
*D
= PrevDecl
->getPrevDeclInScope())
21826 UsedAsPrevious
[D
] = true;
21828 PreviousRedeclTypes
[PrevDecl
->getType().getCanonicalType()] =
21829 PrevDecl
->getLocation();
21832 if (InCompoundScope
) {
21833 for (const auto &PrevData
: UsedAsPrevious
) {
21834 if (!PrevData
.second
) {
21835 PrevDRD
= PrevData
.first
;
21840 } else if (PrevDeclInScope
!= nullptr) {
21841 auto *PrevDRDInScope
= PrevDRD
=
21842 cast
<OMPDeclareReductionDecl
>(PrevDeclInScope
);
21844 PreviousRedeclTypes
[PrevDRDInScope
->getType().getCanonicalType()] =
21845 PrevDRDInScope
->getLocation();
21846 PrevDRDInScope
= PrevDRDInScope
->getPrevDeclInScope();
21847 } while (PrevDRDInScope
!= nullptr);
21849 for (const auto &TyData
: ReductionTypes
) {
21850 const auto I
= PreviousRedeclTypes
.find(TyData
.first
.getCanonicalType());
21851 bool Invalid
= false;
21852 if (I
!= PreviousRedeclTypes
.end()) {
21853 Diag(TyData
.second
, diag::err_omp_declare_reduction_redefinition
)
21855 Diag(I
->second
, diag::note_previous_definition
);
21858 PreviousRedeclTypes
[TyData
.first
.getCanonicalType()] = TyData
.second
;
21859 auto *DRD
= OMPDeclareReductionDecl::Create(Context
, DC
, TyData
.second
,
21860 Name
, TyData
.first
, PrevDRD
);
21862 DRD
->setAccess(AS
);
21863 Decls
.push_back(DRD
);
21865 DRD
->setInvalidDecl();
21870 return DeclGroupPtrTy::make(
21871 DeclGroupRef::Create(Context
, Decls
.begin(), Decls
.size()));
21874 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope
*S
, Decl
*D
) {
21875 auto *DRD
= cast
<OMPDeclareReductionDecl
>(D
);
21877 // Enter new function scope.
21878 PushFunctionScope();
21879 setFunctionHasBranchProtectedScope();
21880 getCurFunction()->setHasOMPDeclareReductionCombiner();
21883 PushDeclContext(S
, DRD
);
21887 PushExpressionEvaluationContext(
21888 ExpressionEvaluationContext::PotentiallyEvaluated
);
21890 QualType ReductionType
= DRD
->getType();
21891 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21892 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21893 // uses semantics of argument handles by value, but it should be passed by
21894 // reference. C lang does not support references, so pass all parameters as
21896 // Create 'T omp_in;' variable.
21897 VarDecl
*OmpInParm
=
21898 buildVarDecl(*this, D
->getLocation(), ReductionType
, "omp_in");
21899 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21900 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21901 // uses semantics of argument handles by value, but it should be passed by
21902 // reference. C lang does not support references, so pass all parameters as
21904 // Create 'T omp_out;' variable.
21905 VarDecl
*OmpOutParm
=
21906 buildVarDecl(*this, D
->getLocation(), ReductionType
, "omp_out");
21907 if (S
!= nullptr) {
21908 PushOnScopeChains(OmpInParm
, S
);
21909 PushOnScopeChains(OmpOutParm
, S
);
21911 DRD
->addDecl(OmpInParm
);
21912 DRD
->addDecl(OmpOutParm
);
21915 ::buildDeclRefExpr(*this, OmpInParm
, ReductionType
, D
->getLocation());
21917 ::buildDeclRefExpr(*this, OmpOutParm
, ReductionType
, D
->getLocation());
21918 DRD
->setCombinerData(InE
, OutE
);
21921 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl
*D
, Expr
*Combiner
) {
21922 auto *DRD
= cast
<OMPDeclareReductionDecl
>(D
);
21923 DiscardCleanupsInEvaluationContext();
21924 PopExpressionEvaluationContext();
21927 PopFunctionScopeInfo();
21929 if (Combiner
!= nullptr)
21930 DRD
->setCombiner(Combiner
);
21932 DRD
->setInvalidDecl();
21935 VarDecl
*Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope
*S
, Decl
*D
) {
21936 auto *DRD
= cast
<OMPDeclareReductionDecl
>(D
);
21938 // Enter new function scope.
21939 PushFunctionScope();
21940 setFunctionHasBranchProtectedScope();
21943 PushDeclContext(S
, DRD
);
21947 PushExpressionEvaluationContext(
21948 ExpressionEvaluationContext::PotentiallyEvaluated
);
21950 QualType ReductionType
= DRD
->getType();
21951 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21952 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21953 // uses semantics of argument handles by value, but it should be passed by
21954 // reference. C lang does not support references, so pass all parameters as
21956 // Create 'T omp_priv;' variable.
21957 VarDecl
*OmpPrivParm
=
21958 buildVarDecl(*this, D
->getLocation(), ReductionType
, "omp_priv");
21959 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21960 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21961 // uses semantics of argument handles by value, but it should be passed by
21962 // reference. C lang does not support references, so pass all parameters as
21964 // Create 'T omp_orig;' variable.
21965 VarDecl
*OmpOrigParm
=
21966 buildVarDecl(*this, D
->getLocation(), ReductionType
, "omp_orig");
21967 if (S
!= nullptr) {
21968 PushOnScopeChains(OmpPrivParm
, S
);
21969 PushOnScopeChains(OmpOrigParm
, S
);
21971 DRD
->addDecl(OmpPrivParm
);
21972 DRD
->addDecl(OmpOrigParm
);
21975 ::buildDeclRefExpr(*this, OmpOrigParm
, ReductionType
, D
->getLocation());
21977 ::buildDeclRefExpr(*this, OmpPrivParm
, ReductionType
, D
->getLocation());
21978 DRD
->setInitializerData(OrigE
, PrivE
);
21979 return OmpPrivParm
;
21982 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl
*D
, Expr
*Initializer
,
21983 VarDecl
*OmpPrivParm
) {
21984 auto *DRD
= cast
<OMPDeclareReductionDecl
>(D
);
21985 DiscardCleanupsInEvaluationContext();
21986 PopExpressionEvaluationContext();
21989 PopFunctionScopeInfo();
21991 if (Initializer
!= nullptr) {
21992 DRD
->setInitializer(Initializer
, OMPDeclareReductionDecl::CallInit
);
21993 } else if (OmpPrivParm
->hasInit()) {
21994 DRD
->setInitializer(OmpPrivParm
->getInit(),
21995 OmpPrivParm
->isDirectInit()
21996 ? OMPDeclareReductionDecl::DirectInit
21997 : OMPDeclareReductionDecl::CopyInit
);
21999 DRD
->setInvalidDecl();
22003 Sema::DeclGroupPtrTy
Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22004 Scope
*S
, DeclGroupPtrTy DeclReductions
, bool IsValid
) {
22005 for (Decl
*D
: DeclReductions
.get()) {
22008 PushOnScopeChains(cast
<OMPDeclareReductionDecl
>(D
), S
,
22009 /*AddToContext=*/false);
22011 D
->setInvalidDecl();
22014 return DeclReductions
;
22017 TypeResult
Sema::ActOnOpenMPDeclareMapperVarDecl(Scope
*S
, Declarator
&D
) {
22018 TypeSourceInfo
*TInfo
= GetTypeForDeclarator(D
, S
);
22019 QualType T
= TInfo
->getType();
22020 if (D
.isInvalidType())
22023 if (getLangOpts().CPlusPlus
) {
22024 // Check that there are no default arguments (C++ only).
22025 CheckExtraCXXDefaultArguments(D
);
22028 return CreateParsedType(T
, TInfo
);
22031 QualType
Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc
,
22032 TypeResult ParsedType
) {
22033 assert(ParsedType
.isUsable() && "Expect usable parsed mapper type");
22035 QualType MapperType
= GetTypeFromParser(ParsedType
.get());
22036 assert(!MapperType
.isNull() && "Expect valid mapper type");
22038 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22039 // The type must be of struct, union or class type in C and C++
22040 if (!MapperType
->isStructureOrClassType() && !MapperType
->isUnionType()) {
22041 Diag(TyLoc
, diag::err_omp_mapper_wrong_type
);
22047 Sema::DeclGroupPtrTy
Sema::ActOnOpenMPDeclareMapperDirective(
22048 Scope
*S
, DeclContext
*DC
, DeclarationName Name
, QualType MapperType
,
22049 SourceLocation StartLoc
, DeclarationName VN
, AccessSpecifier AS
,
22050 Expr
*MapperVarRef
, ArrayRef
<OMPClause
*> Clauses
, Decl
*PrevDeclInScope
) {
22051 LookupResult
Lookup(*this, Name
, SourceLocation(), LookupOMPMapperName
,
22052 forRedeclarationInCurContext());
22053 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22054 // A mapper-identifier may not be redeclared in the current scope for the
22055 // same type or for a type that is compatible according to the base language
22057 llvm::DenseMap
<QualType
, SourceLocation
> PreviousRedeclTypes
;
22058 OMPDeclareMapperDecl
*PrevDMD
= nullptr;
22059 bool InCompoundScope
= true;
22060 if (S
!= nullptr) {
22061 // Find previous declaration with the same name not referenced in other
22063 FunctionScopeInfo
*ParentFn
= getEnclosingFunction();
22065 (ParentFn
!= nullptr) && !ParentFn
->CompoundScopes
.empty();
22066 LookupName(Lookup
, S
);
22067 FilterLookupForScope(Lookup
, DC
, S
, /*ConsiderLinkage=*/false,
22068 /*AllowInlineNamespace=*/false);
22069 llvm::DenseMap
<OMPDeclareMapperDecl
*, bool> UsedAsPrevious
;
22070 LookupResult::Filter Filter
= Lookup
.makeFilter();
22071 while (Filter
.hasNext()) {
22072 auto *PrevDecl
= cast
<OMPDeclareMapperDecl
>(Filter
.next());
22073 if (InCompoundScope
) {
22074 auto I
= UsedAsPrevious
.find(PrevDecl
);
22075 if (I
== UsedAsPrevious
.end())
22076 UsedAsPrevious
[PrevDecl
] = false;
22077 if (OMPDeclareMapperDecl
*D
= PrevDecl
->getPrevDeclInScope())
22078 UsedAsPrevious
[D
] = true;
22080 PreviousRedeclTypes
[PrevDecl
->getType().getCanonicalType()] =
22081 PrevDecl
->getLocation();
22084 if (InCompoundScope
) {
22085 for (const auto &PrevData
: UsedAsPrevious
) {
22086 if (!PrevData
.second
) {
22087 PrevDMD
= PrevData
.first
;
22092 } else if (PrevDeclInScope
) {
22093 auto *PrevDMDInScope
= PrevDMD
=
22094 cast
<OMPDeclareMapperDecl
>(PrevDeclInScope
);
22096 PreviousRedeclTypes
[PrevDMDInScope
->getType().getCanonicalType()] =
22097 PrevDMDInScope
->getLocation();
22098 PrevDMDInScope
= PrevDMDInScope
->getPrevDeclInScope();
22099 } while (PrevDMDInScope
!= nullptr);
22101 const auto I
= PreviousRedeclTypes
.find(MapperType
.getCanonicalType());
22102 bool Invalid
= false;
22103 if (I
!= PreviousRedeclTypes
.end()) {
22104 Diag(StartLoc
, diag::err_omp_declare_mapper_redefinition
)
22105 << MapperType
<< Name
;
22106 Diag(I
->second
, diag::note_previous_definition
);
22109 // Build expressions for implicit maps of data members with 'default'
22111 SmallVector
<OMPClause
*, 4> ClausesWithImplicit(Clauses
.begin(),
22113 if (LangOpts
.OpenMP
>= 50)
22114 processImplicitMapsWithDefaultMappers(*this, DSAStack
, ClausesWithImplicit
);
22116 OMPDeclareMapperDecl::Create(Context
, DC
, StartLoc
, Name
, MapperType
, VN
,
22117 ClausesWithImplicit
, PrevDMD
);
22119 PushOnScopeChains(DMD
, S
);
22122 DMD
->setAccess(AS
);
22124 DMD
->setInvalidDecl();
22126 auto *VD
= cast
<DeclRefExpr
>(MapperVarRef
)->getDecl();
22127 VD
->setDeclContext(DMD
);
22128 VD
->setLexicalDeclContext(DMD
);
22130 DMD
->setMapperVarRef(MapperVarRef
);
22132 return DeclGroupPtrTy::make(DeclGroupRef(DMD
));
22136 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope
*S
, QualType MapperType
,
22137 SourceLocation StartLoc
,
22138 DeclarationName VN
) {
22139 TypeSourceInfo
*TInfo
=
22140 Context
.getTrivialTypeSourceInfo(MapperType
, StartLoc
);
22141 auto *VD
= VarDecl::Create(Context
, Context
.getTranslationUnitDecl(),
22142 StartLoc
, StartLoc
, VN
.getAsIdentifierInfo(),
22143 MapperType
, TInfo
, SC_None
);
22145 PushOnScopeChains(VD
, S
, /*AddToContext=*/false);
22146 Expr
*E
= buildDeclRefExpr(*this, VD
, MapperType
, StartLoc
);
22147 DSAStack
->addDeclareMapperVarRef(E
);
22151 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl
*VD
) const {
22152 assert(LangOpts
.OpenMP
&& "Expected OpenMP mode.");
22153 const Expr
*Ref
= DSAStack
->getDeclareMapperVarRef();
22154 if (const auto *DRE
= cast_or_null
<DeclRefExpr
>(Ref
)) {
22155 if (VD
->getCanonicalDecl() == DRE
->getDecl()->getCanonicalDecl())
22157 if (VD
->isUsableInConstantExpressions(Context
))
22164 const ValueDecl
*Sema::getOpenMPDeclareMapperVarName() const {
22165 assert(LangOpts
.OpenMP
&& "Expected OpenMP mode.");
22166 return cast
<DeclRefExpr
>(DSAStack
->getDeclareMapperVarRef())->getDecl();
22169 OMPClause
*Sema::ActOnOpenMPNumTeamsClause(Expr
*NumTeams
,
22170 SourceLocation StartLoc
,
22171 SourceLocation LParenLoc
,
22172 SourceLocation EndLoc
) {
22173 Expr
*ValExpr
= NumTeams
;
22174 Stmt
*HelperValStmt
= nullptr;
22176 // OpenMP [teams Constrcut, Restrictions]
22177 // The num_teams expression must evaluate to a positive integer value.
22178 if (!isNonNegativeIntegerValue(ValExpr
, *this, OMPC_num_teams
,
22179 /*StrictlyPositive=*/true))
22182 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
22183 OpenMPDirectiveKind CaptureRegion
=
22184 getOpenMPCaptureRegionForClause(DKind
, OMPC_num_teams
, LangOpts
.OpenMP
);
22185 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
22186 ValExpr
= MakeFullExpr(ValExpr
).get();
22187 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
22188 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
22189 HelperValStmt
= buildPreInits(Context
, Captures
);
22192 return new (Context
) OMPNumTeamsClause(ValExpr
, HelperValStmt
, CaptureRegion
,
22193 StartLoc
, LParenLoc
, EndLoc
);
22196 OMPClause
*Sema::ActOnOpenMPThreadLimitClause(Expr
*ThreadLimit
,
22197 SourceLocation StartLoc
,
22198 SourceLocation LParenLoc
,
22199 SourceLocation EndLoc
) {
22200 Expr
*ValExpr
= ThreadLimit
;
22201 Stmt
*HelperValStmt
= nullptr;
22203 // OpenMP [teams Constrcut, Restrictions]
22204 // The thread_limit expression must evaluate to a positive integer value.
22205 if (!isNonNegativeIntegerValue(ValExpr
, *this, OMPC_thread_limit
,
22206 /*StrictlyPositive=*/true))
22209 OpenMPDirectiveKind DKind
= DSAStack
->getCurrentDirective();
22210 OpenMPDirectiveKind CaptureRegion
= getOpenMPCaptureRegionForClause(
22211 DKind
, OMPC_thread_limit
, LangOpts
.OpenMP
);
22212 if (CaptureRegion
!= OMPD_unknown
&& !CurContext
->isDependentContext()) {
22213 ValExpr
= MakeFullExpr(ValExpr
).get();
22214 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
22215 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
22216 HelperValStmt
= buildPreInits(Context
, Captures
);
22219 return new (Context
) OMPThreadLimitClause(
22220 ValExpr
, HelperValStmt
, CaptureRegion
, StartLoc
, LParenLoc
, EndLoc
);
22223 OMPClause
*Sema::ActOnOpenMPPriorityClause(Expr
*Priority
,
22224 SourceLocation StartLoc
,
22225 SourceLocation LParenLoc
,
22226 SourceLocation EndLoc
) {
22227 Expr
*ValExpr
= Priority
;
22228 Stmt
*HelperValStmt
= nullptr;
22229 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
22231 // OpenMP [2.9.1, task Constrcut]
22232 // The priority-value is a non-negative numerical scalar expression.
22233 if (!isNonNegativeIntegerValue(
22234 ValExpr
, *this, OMPC_priority
,
22235 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22236 DSAStack
->getCurrentDirective(), &CaptureRegion
, &HelperValStmt
))
22239 return new (Context
) OMPPriorityClause(ValExpr
, HelperValStmt
, CaptureRegion
,
22240 StartLoc
, LParenLoc
, EndLoc
);
22243 OMPClause
*Sema::ActOnOpenMPGrainsizeClause(Expr
*Grainsize
,
22244 SourceLocation StartLoc
,
22245 SourceLocation LParenLoc
,
22246 SourceLocation EndLoc
) {
22247 Expr
*ValExpr
= Grainsize
;
22248 Stmt
*HelperValStmt
= nullptr;
22249 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
22251 // OpenMP [2.9.2, taskloop Constrcut]
22252 // The parameter of the grainsize clause must be a positive integer
22254 if (!isNonNegativeIntegerValue(
22255 ValExpr
, *this, OMPC_grainsize
,
22256 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22257 DSAStack
->getCurrentDirective(), &CaptureRegion
, &HelperValStmt
))
22260 return new (Context
) OMPGrainsizeClause(ValExpr
, HelperValStmt
, CaptureRegion
,
22261 StartLoc
, LParenLoc
, EndLoc
);
22264 OMPClause
*Sema::ActOnOpenMPNumTasksClause(Expr
*NumTasks
,
22265 SourceLocation StartLoc
,
22266 SourceLocation LParenLoc
,
22267 SourceLocation EndLoc
) {
22268 Expr
*ValExpr
= NumTasks
;
22269 Stmt
*HelperValStmt
= nullptr;
22270 OpenMPDirectiveKind CaptureRegion
= OMPD_unknown
;
22272 // OpenMP [2.9.2, taskloop Constrcut]
22273 // The parameter of the num_tasks clause must be a positive integer
22275 if (!isNonNegativeIntegerValue(
22276 ValExpr
, *this, OMPC_num_tasks
,
22277 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22278 DSAStack
->getCurrentDirective(), &CaptureRegion
, &HelperValStmt
))
22281 return new (Context
) OMPNumTasksClause(ValExpr
, HelperValStmt
, CaptureRegion
,
22282 StartLoc
, LParenLoc
, EndLoc
);
22285 OMPClause
*Sema::ActOnOpenMPHintClause(Expr
*Hint
, SourceLocation StartLoc
,
22286 SourceLocation LParenLoc
,
22287 SourceLocation EndLoc
) {
22288 // OpenMP [2.13.2, critical construct, Description]
22289 // ... where hint-expression is an integer constant expression that evaluates
22290 // to a valid lock hint.
22291 ExprResult HintExpr
=
22292 VerifyPositiveIntegerConstantInClause(Hint
, OMPC_hint
, false);
22293 if (HintExpr
.isInvalid())
22295 return new (Context
)
22296 OMPHintClause(HintExpr
.get(), StartLoc
, LParenLoc
, EndLoc
);
22299 /// Tries to find omp_event_handle_t type.
22300 static bool findOMPEventHandleT(Sema
&S
, SourceLocation Loc
,
22301 DSAStackTy
*Stack
) {
22302 QualType OMPEventHandleT
= Stack
->getOMPEventHandleT();
22303 if (!OMPEventHandleT
.isNull())
22305 IdentifierInfo
*II
= &S
.PP
.getIdentifierTable().get("omp_event_handle_t");
22306 ParsedType PT
= S
.getTypeName(*II
, Loc
, S
.getCurScope());
22307 if (!PT
.getAsOpaquePtr() || PT
.get().isNull()) {
22308 S
.Diag(Loc
, diag::err_omp_implied_type_not_found
) << "omp_event_handle_t";
22311 Stack
->setOMPEventHandleT(PT
.get());
22315 OMPClause
*Sema::ActOnOpenMPDetachClause(Expr
*Evt
, SourceLocation StartLoc
,
22316 SourceLocation LParenLoc
,
22317 SourceLocation EndLoc
) {
22318 if (!Evt
->isValueDependent() && !Evt
->isTypeDependent() &&
22319 !Evt
->isInstantiationDependent() &&
22320 !Evt
->containsUnexpandedParameterPack()) {
22321 if (!findOMPEventHandleT(*this, Evt
->getExprLoc(), DSAStack
))
22323 // OpenMP 5.0, 2.10.1 task Construct.
22324 // event-handle is a variable of the omp_event_handle_t type.
22325 auto *Ref
= dyn_cast
<DeclRefExpr
>(Evt
->IgnoreParenImpCasts());
22327 Diag(Evt
->getExprLoc(), diag::err_omp_var_expected
)
22328 << "omp_event_handle_t" << 0 << Evt
->getSourceRange();
22331 auto *VD
= dyn_cast_or_null
<VarDecl
>(Ref
->getDecl());
22333 Diag(Evt
->getExprLoc(), diag::err_omp_var_expected
)
22334 << "omp_event_handle_t" << 0 << Evt
->getSourceRange();
22337 if (!Context
.hasSameUnqualifiedType(DSAStack
->getOMPEventHandleT(),
22339 VD
->getType().isConstant(Context
)) {
22340 Diag(Evt
->getExprLoc(), diag::err_omp_var_expected
)
22341 << "omp_event_handle_t" << 1 << VD
->getType()
22342 << Evt
->getSourceRange();
22345 // OpenMP 5.0, 2.10.1 task Construct
22346 // [detach clause]... The event-handle will be considered as if it was
22347 // specified on a firstprivate clause.
22348 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(VD
, /*FromParent=*/false);
22349 if (DVar
.CKind
!= OMPC_unknown
&& DVar
.CKind
!= OMPC_firstprivate
&&
22351 Diag(Evt
->getExprLoc(), diag::err_omp_wrong_dsa
)
22352 << getOpenMPClauseName(DVar
.CKind
)
22353 << getOpenMPClauseName(OMPC_firstprivate
);
22354 reportOriginalDsa(*this, DSAStack
, VD
, DVar
);
22359 return new (Context
) OMPDetachClause(Evt
, StartLoc
, LParenLoc
, EndLoc
);
22362 OMPClause
*Sema::ActOnOpenMPDistScheduleClause(
22363 OpenMPDistScheduleClauseKind Kind
, Expr
*ChunkSize
, SourceLocation StartLoc
,
22364 SourceLocation LParenLoc
, SourceLocation KindLoc
, SourceLocation CommaLoc
,
22365 SourceLocation EndLoc
) {
22366 if (Kind
== OMPC_DIST_SCHEDULE_unknown
) {
22367 std::string Values
;
22369 Values
+= getOpenMPSimpleClauseTypeName(OMPC_dist_schedule
, 0);
22371 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
22372 << Values
<< getOpenMPClauseName(OMPC_dist_schedule
);
22375 Expr
*ValExpr
= ChunkSize
;
22376 Stmt
*HelperValStmt
= nullptr;
22378 if (!ChunkSize
->isValueDependent() && !ChunkSize
->isTypeDependent() &&
22379 !ChunkSize
->isInstantiationDependent() &&
22380 !ChunkSize
->containsUnexpandedParameterPack()) {
22381 SourceLocation ChunkSizeLoc
= ChunkSize
->getBeginLoc();
22383 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc
, ChunkSize
);
22384 if (Val
.isInvalid())
22387 ValExpr
= Val
.get();
22389 // OpenMP [2.7.1, Restrictions]
22390 // chunk_size must be a loop invariant integer expression with a positive
22392 if (Optional
<llvm::APSInt
> Result
=
22393 ValExpr
->getIntegerConstantExpr(Context
)) {
22394 if (Result
->isSigned() && !Result
->isStrictlyPositive()) {
22395 Diag(ChunkSizeLoc
, diag::err_omp_negative_expression_in_clause
)
22396 << "dist_schedule" << ChunkSize
->getSourceRange();
22399 } else if (getOpenMPCaptureRegionForClause(
22400 DSAStack
->getCurrentDirective(), OMPC_dist_schedule
,
22401 LangOpts
.OpenMP
) != OMPD_unknown
&&
22402 !CurContext
->isDependentContext()) {
22403 ValExpr
= MakeFullExpr(ValExpr
).get();
22404 llvm::MapVector
<const Expr
*, DeclRefExpr
*> Captures
;
22405 ValExpr
= tryBuildCapture(*this, ValExpr
, Captures
).get();
22406 HelperValStmt
= buildPreInits(Context
, Captures
);
22411 return new (Context
)
22412 OMPDistScheduleClause(StartLoc
, LParenLoc
, KindLoc
, CommaLoc
, EndLoc
,
22413 Kind
, ValExpr
, HelperValStmt
);
22416 OMPClause
*Sema::ActOnOpenMPDefaultmapClause(
22417 OpenMPDefaultmapClauseModifier M
, OpenMPDefaultmapClauseKind Kind
,
22418 SourceLocation StartLoc
, SourceLocation LParenLoc
, SourceLocation MLoc
,
22419 SourceLocation KindLoc
, SourceLocation EndLoc
) {
22420 if (getLangOpts().OpenMP
< 50) {
22421 if (M
!= OMPC_DEFAULTMAP_MODIFIER_tofrom
||
22422 Kind
!= OMPC_DEFAULTMAP_scalar
) {
22424 SourceLocation Loc
;
22426 if (M
!= OMPC_DEFAULTMAP_MODIFIER_tofrom
) {
22427 Value
+= getOpenMPSimpleClauseTypeName(OMPC_defaultmap
,
22428 OMPC_DEFAULTMAP_MODIFIER_tofrom
);
22431 Value
+= getOpenMPSimpleClauseTypeName(OMPC_defaultmap
,
22432 OMPC_DEFAULTMAP_scalar
);
22436 Diag(Loc
, diag::err_omp_unexpected_clause_value
)
22437 << Value
<< getOpenMPClauseName(OMPC_defaultmap
);
22441 bool isDefaultmapModifier
= (M
!= OMPC_DEFAULTMAP_MODIFIER_unknown
);
22442 bool isDefaultmapKind
= (Kind
!= OMPC_DEFAULTMAP_unknown
) ||
22443 (LangOpts
.OpenMP
>= 50 && KindLoc
.isInvalid());
22444 if (!isDefaultmapKind
|| !isDefaultmapModifier
) {
22445 StringRef KindValue
= "'scalar', 'aggregate', 'pointer'";
22446 if (LangOpts
.OpenMP
== 50) {
22447 StringRef ModifierValue
= "'alloc', 'from', 'to', 'tofrom', "
22448 "'firstprivate', 'none', 'default'";
22449 if (!isDefaultmapKind
&& isDefaultmapModifier
) {
22450 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
22451 << KindValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22452 } else if (isDefaultmapKind
&& !isDefaultmapModifier
) {
22453 Diag(MLoc
, diag::err_omp_unexpected_clause_value
)
22454 << ModifierValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22456 Diag(MLoc
, diag::err_omp_unexpected_clause_value
)
22457 << ModifierValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22458 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
22459 << KindValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22462 StringRef ModifierValue
=
22463 "'alloc', 'from', 'to', 'tofrom', "
22464 "'firstprivate', 'none', 'default', 'present'";
22465 if (!isDefaultmapKind
&& isDefaultmapModifier
) {
22466 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
22467 << KindValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22468 } else if (isDefaultmapKind
&& !isDefaultmapModifier
) {
22469 Diag(MLoc
, diag::err_omp_unexpected_clause_value
)
22470 << ModifierValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22472 Diag(MLoc
, diag::err_omp_unexpected_clause_value
)
22473 << ModifierValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22474 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
22475 << KindValue
<< getOpenMPClauseName(OMPC_defaultmap
);
22481 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22482 // At most one defaultmap clause for each category can appear on the
22484 if (DSAStack
->checkDefaultmapCategory(Kind
)) {
22485 Diag(StartLoc
, diag::err_omp_one_defaultmap_each_category
);
22489 if (Kind
== OMPC_DEFAULTMAP_unknown
) {
22490 // Variable category is not specified - mark all categories.
22491 DSAStack
->setDefaultDMAAttr(M
, OMPC_DEFAULTMAP_aggregate
, StartLoc
);
22492 DSAStack
->setDefaultDMAAttr(M
, OMPC_DEFAULTMAP_scalar
, StartLoc
);
22493 DSAStack
->setDefaultDMAAttr(M
, OMPC_DEFAULTMAP_pointer
, StartLoc
);
22495 DSAStack
->setDefaultDMAAttr(M
, Kind
, StartLoc
);
22498 return new (Context
)
22499 OMPDefaultmapClause(StartLoc
, LParenLoc
, MLoc
, KindLoc
, EndLoc
, Kind
, M
);
22502 bool Sema::ActOnStartOpenMPDeclareTargetContext(
22503 DeclareTargetContextInfo
&DTCI
) {
22504 DeclContext
*CurLexicalContext
= getCurLexicalContext();
22505 if (!CurLexicalContext
->isFileContext() &&
22506 !CurLexicalContext
->isExternCContext() &&
22507 !CurLexicalContext
->isExternCXXContext() &&
22508 !isa
<CXXRecordDecl
>(CurLexicalContext
) &&
22509 !isa
<ClassTemplateDecl
>(CurLexicalContext
) &&
22510 !isa
<ClassTemplatePartialSpecializationDecl
>(CurLexicalContext
) &&
22511 !isa
<ClassTemplateSpecializationDecl
>(CurLexicalContext
)) {
22512 Diag(DTCI
.Loc
, diag::err_omp_region_not_file_context
);
22515 DeclareTargetNesting
.push_back(DTCI
);
22519 const Sema::DeclareTargetContextInfo
22520 Sema::ActOnOpenMPEndDeclareTargetDirective() {
22521 assert(!DeclareTargetNesting
.empty() &&
22522 "check isInOpenMPDeclareTargetContext() first!");
22523 return DeclareTargetNesting
.pop_back_val();
22526 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
22527 DeclareTargetContextInfo
&DTCI
) {
22528 for (auto &It
: DTCI
.ExplicitlyMapped
)
22529 ActOnOpenMPDeclareTargetName(It
.first
, It
.second
.Loc
, It
.second
.MT
, DTCI
);
22532 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
22533 if (DeclareTargetNesting
.empty())
22535 DeclareTargetContextInfo
&DTCI
= DeclareTargetNesting
.back();
22536 Diag(DTCI
.Loc
, diag::warn_omp_unterminated_declare_target
)
22537 << getOpenMPDirectiveName(DTCI
.Kind
);
22540 NamedDecl
*Sema::lookupOpenMPDeclareTargetName(Scope
*CurScope
,
22541 CXXScopeSpec
&ScopeSpec
,
22542 const DeclarationNameInfo
&Id
) {
22543 LookupResult
Lookup(*this, Id
, LookupOrdinaryName
);
22544 LookupParsedName(Lookup
, CurScope
, &ScopeSpec
, true);
22546 if (Lookup
.isAmbiguous())
22548 Lookup
.suppressDiagnostics();
22550 if (!Lookup
.isSingleResult()) {
22551 VarOrFuncDeclFilterCCC
CCC(*this);
22552 if (TypoCorrection Corrected
=
22553 CorrectTypo(Id
, LookupOrdinaryName
, CurScope
, nullptr, CCC
,
22554 CTK_ErrorRecovery
)) {
22555 diagnoseTypo(Corrected
, PDiag(diag::err_undeclared_var_use_suggest
)
22557 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected
.getCorrectionDecl());
22561 Diag(Id
.getLoc(), diag::err_undeclared_var_use
) << Id
.getName();
22565 NamedDecl
*ND
= Lookup
.getAsSingle
<NamedDecl
>();
22566 if (!isa
<VarDecl
>(ND
) && !isa
<FunctionDecl
>(ND
) &&
22567 !isa
<FunctionTemplateDecl
>(ND
)) {
22568 Diag(Id
.getLoc(), diag::err_omp_invalid_target_decl
) << Id
.getName();
22574 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl
*ND
, SourceLocation Loc
,
22575 OMPDeclareTargetDeclAttr::MapTypeTy MT
,
22576 DeclareTargetContextInfo
&DTCI
) {
22577 assert((isa
<VarDecl
>(ND
) || isa
<FunctionDecl
>(ND
) ||
22578 isa
<FunctionTemplateDecl
>(ND
)) &&
22579 "Expected variable, function or function template.");
22581 // Diagnose marking after use as it may lead to incorrect diagnosis and
22583 if (LangOpts
.OpenMP
>= 50 &&
22584 (ND
->isUsed(/*CheckUsedAttr=*/false) || ND
->isReferenced()))
22585 Diag(Loc
, diag::warn_omp_declare_target_after_first_use
);
22587 // Explicit declare target lists have precedence.
22588 const unsigned Level
= -1;
22590 auto *VD
= cast
<ValueDecl
>(ND
);
22591 llvm::Optional
<OMPDeclareTargetDeclAttr
*> ActiveAttr
=
22592 OMPDeclareTargetDeclAttr::getActiveAttr(VD
);
22593 if (ActiveAttr
&& ActiveAttr
.value()->getDevType() != DTCI
.DT
&&
22594 ActiveAttr
.value()->getLevel() == Level
) {
22595 Diag(Loc
, diag::err_omp_device_type_mismatch
)
22596 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI
.DT
)
22597 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22598 ActiveAttr
.value()->getDevType());
22601 if (ActiveAttr
&& ActiveAttr
.value()->getMapType() != MT
&&
22602 ActiveAttr
.value()->getLevel() == Level
) {
22603 Diag(Loc
, diag::err_omp_declare_target_to_and_link
) << ND
;
22607 if (ActiveAttr
&& ActiveAttr
.value()->getLevel() == Level
)
22610 Expr
*IndirectE
= nullptr;
22611 bool IsIndirect
= false;
22612 if (DTCI
.Indirect
) {
22613 IndirectE
= DTCI
.Indirect
.value();
22617 auto *A
= OMPDeclareTargetDeclAttr::CreateImplicit(
22618 Context
, MT
, DTCI
.DT
, IndirectE
, IsIndirect
, Level
,
22619 SourceRange(Loc
, Loc
));
22621 if (ASTMutationListener
*ML
= Context
.getASTMutationListener())
22622 ML
->DeclarationMarkedOpenMPDeclareTarget(ND
, A
);
22623 checkDeclIsAllowedInOpenMPTarget(nullptr, ND
, Loc
);
22626 static void checkDeclInTargetContext(SourceLocation SL
, SourceRange SR
,
22627 Sema
&SemaRef
, Decl
*D
) {
22628 if (!D
|| !isa
<VarDecl
>(D
))
22630 auto *VD
= cast
<VarDecl
>(D
);
22631 Optional
<OMPDeclareTargetDeclAttr::MapTypeTy
> MapTy
=
22632 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD
);
22633 if (SemaRef
.LangOpts
.OpenMP
>= 50 &&
22634 (SemaRef
.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22635 SemaRef
.getCurBlock() || SemaRef
.getCurCapturedRegion()) &&
22636 VD
->hasGlobalStorage()) {
22637 if (!MapTy
|| *MapTy
!= OMPDeclareTargetDeclAttr::MT_To
) {
22638 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22639 // If a lambda declaration and definition appears between a
22640 // declare target directive and the matching end declare target
22641 // directive, all variables that are captured by the lambda
22642 // expression must also appear in a to clause.
22643 SemaRef
.Diag(VD
->getLocation(),
22644 diag::err_omp_lambda_capture_in_declare_target_not_to
);
22645 SemaRef
.Diag(SL
, diag::note_var_explicitly_captured_here
)
22652 SemaRef
.Diag(VD
->getLocation(), diag::warn_omp_not_in_target_context
);
22653 SemaRef
.Diag(SL
, diag::note_used_here
) << SR
;
22656 static bool checkValueDeclInTarget(SourceLocation SL
, SourceRange SR
,
22657 Sema
&SemaRef
, DSAStackTy
*Stack
,
22659 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD
) ||
22660 checkTypeMappable(SL
, SR
, SemaRef
, Stack
, VD
->getType(),
22661 /*FullCheck=*/false);
22664 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr
*E
, Decl
*D
,
22665 SourceLocation IdLoc
) {
22666 if (!D
|| D
->isInvalidDecl())
22668 SourceRange SR
= E
? E
->getSourceRange() : D
->getSourceRange();
22669 SourceLocation SL
= E
? E
->getBeginLoc() : D
->getLocation();
22670 if (auto *VD
= dyn_cast
<VarDecl
>(D
)) {
22671 // Only global variables can be marked as declare target.
22672 if (!VD
->isFileVarDecl() && !VD
->isStaticLocal() &&
22673 !VD
->isStaticDataMember())
22675 // 2.10.6: threadprivate variable cannot appear in a declare target
22677 if (DSAStack
->isThreadPrivate(VD
)) {
22678 Diag(SL
, diag::err_omp_threadprivate_in_target
);
22679 reportOriginalDsa(*this, DSAStack
, VD
, DSAStack
->getTopDSA(VD
, false));
22683 if (const auto *FTD
= dyn_cast
<FunctionTemplateDecl
>(D
))
22684 D
= FTD
->getTemplatedDecl();
22685 if (auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
22686 llvm::Optional
<OMPDeclareTargetDeclAttr::MapTypeTy
> Res
=
22687 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD
);
22688 if (IdLoc
.isValid() && Res
&& *Res
== OMPDeclareTargetDeclAttr::MT_Link
) {
22689 Diag(IdLoc
, diag::err_omp_function_in_link_clause
);
22690 Diag(FD
->getLocation(), diag::note_defined_here
) << FD
;
22694 if (auto *VD
= dyn_cast
<ValueDecl
>(D
)) {
22695 // Problem if any with var declared with incomplete type will be reported
22696 // as normal, so no need to check it here.
22697 if ((E
|| !VD
->getType()->isIncompleteType()) &&
22698 !checkValueDeclInTarget(SL
, SR
, *this, DSAStack
, VD
))
22700 if (!E
&& isInOpenMPDeclareTargetContext()) {
22701 // Checking declaration inside declare target region.
22702 if (isa
<VarDecl
>(D
) || isa
<FunctionDecl
>(D
) ||
22703 isa
<FunctionTemplateDecl
>(D
)) {
22704 llvm::Optional
<OMPDeclareTargetDeclAttr
*> ActiveAttr
=
22705 OMPDeclareTargetDeclAttr::getActiveAttr(VD
);
22706 unsigned Level
= DeclareTargetNesting
.size();
22707 if (ActiveAttr
&& ActiveAttr
.value()->getLevel() >= Level
)
22709 DeclareTargetContextInfo
&DTCI
= DeclareTargetNesting
.back();
22710 Expr
*IndirectE
= nullptr;
22711 bool IsIndirect
= false;
22712 if (DTCI
.Indirect
) {
22713 IndirectE
= DTCI
.Indirect
.value();
22717 auto *A
= OMPDeclareTargetDeclAttr::CreateImplicit(
22718 Context
, OMPDeclareTargetDeclAttr::MT_To
, DTCI
.DT
, IndirectE
,
22719 IsIndirect
, Level
, SourceRange(DTCI
.Loc
, DTCI
.Loc
));
22721 if (ASTMutationListener
*ML
= Context
.getASTMutationListener())
22722 ML
->DeclarationMarkedOpenMPDeclareTarget(D
, A
);
22729 checkDeclInTargetContext(E
->getExprLoc(), E
->getSourceRange(), *this, D
);
22732 OMPClause
*Sema::ActOnOpenMPToClause(
22733 ArrayRef
<OpenMPMotionModifierKind
> MotionModifiers
,
22734 ArrayRef
<SourceLocation
> MotionModifiersLoc
,
22735 CXXScopeSpec
&MapperIdScopeSpec
, DeclarationNameInfo
&MapperId
,
22736 SourceLocation ColonLoc
, ArrayRef
<Expr
*> VarList
,
22737 const OMPVarListLocTy
&Locs
, ArrayRef
<Expr
*> UnresolvedMappers
) {
22738 OpenMPMotionModifierKind Modifiers
[] = {OMPC_MOTION_MODIFIER_unknown
,
22739 OMPC_MOTION_MODIFIER_unknown
};
22740 SourceLocation ModifiersLoc
[NumberOfOMPMotionModifiers
];
22742 // Process motion-modifiers, flag errors for duplicate modifiers.
22743 unsigned Count
= 0;
22744 for (unsigned I
= 0, E
= MotionModifiers
.size(); I
< E
; ++I
) {
22745 if (MotionModifiers
[I
] != OMPC_MOTION_MODIFIER_unknown
&&
22746 llvm::is_contained(Modifiers
, MotionModifiers
[I
])) {
22747 Diag(MotionModifiersLoc
[I
], diag::err_omp_duplicate_motion_modifier
);
22750 assert(Count
< NumberOfOMPMotionModifiers
&&
22751 "Modifiers exceed the allowed number of motion modifiers");
22752 Modifiers
[Count
] = MotionModifiers
[I
];
22753 ModifiersLoc
[Count
] = MotionModifiersLoc
[I
];
22757 MappableVarListInfo
MVLI(VarList
);
22758 checkMappableExpressionList(*this, DSAStack
, OMPC_to
, MVLI
, Locs
.StartLoc
,
22759 MapperIdScopeSpec
, MapperId
, UnresolvedMappers
);
22760 if (MVLI
.ProcessedVarList
.empty())
22763 return OMPToClause::Create(
22764 Context
, Locs
, MVLI
.ProcessedVarList
, MVLI
.VarBaseDeclarations
,
22765 MVLI
.VarComponents
, MVLI
.UDMapperList
, Modifiers
, ModifiersLoc
,
22766 MapperIdScopeSpec
.getWithLocInContext(Context
), MapperId
);
22769 OMPClause
*Sema::ActOnOpenMPFromClause(
22770 ArrayRef
<OpenMPMotionModifierKind
> MotionModifiers
,
22771 ArrayRef
<SourceLocation
> MotionModifiersLoc
,
22772 CXXScopeSpec
&MapperIdScopeSpec
, DeclarationNameInfo
&MapperId
,
22773 SourceLocation ColonLoc
, ArrayRef
<Expr
*> VarList
,
22774 const OMPVarListLocTy
&Locs
, ArrayRef
<Expr
*> UnresolvedMappers
) {
22775 OpenMPMotionModifierKind Modifiers
[] = {OMPC_MOTION_MODIFIER_unknown
,
22776 OMPC_MOTION_MODIFIER_unknown
};
22777 SourceLocation ModifiersLoc
[NumberOfOMPMotionModifiers
];
22779 // Process motion-modifiers, flag errors for duplicate modifiers.
22780 unsigned Count
= 0;
22781 for (unsigned I
= 0, E
= MotionModifiers
.size(); I
< E
; ++I
) {
22782 if (MotionModifiers
[I
] != OMPC_MOTION_MODIFIER_unknown
&&
22783 llvm::is_contained(Modifiers
, MotionModifiers
[I
])) {
22784 Diag(MotionModifiersLoc
[I
], diag::err_omp_duplicate_motion_modifier
);
22787 assert(Count
< NumberOfOMPMotionModifiers
&&
22788 "Modifiers exceed the allowed number of motion modifiers");
22789 Modifiers
[Count
] = MotionModifiers
[I
];
22790 ModifiersLoc
[Count
] = MotionModifiersLoc
[I
];
22794 MappableVarListInfo
MVLI(VarList
);
22795 checkMappableExpressionList(*this, DSAStack
, OMPC_from
, MVLI
, Locs
.StartLoc
,
22796 MapperIdScopeSpec
, MapperId
, UnresolvedMappers
);
22797 if (MVLI
.ProcessedVarList
.empty())
22800 return OMPFromClause::Create(
22801 Context
, Locs
, MVLI
.ProcessedVarList
, MVLI
.VarBaseDeclarations
,
22802 MVLI
.VarComponents
, MVLI
.UDMapperList
, Modifiers
, ModifiersLoc
,
22803 MapperIdScopeSpec
.getWithLocInContext(Context
), MapperId
);
22806 OMPClause
*Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef
<Expr
*> VarList
,
22807 const OMPVarListLocTy
&Locs
) {
22808 MappableVarListInfo
MVLI(VarList
);
22809 SmallVector
<Expr
*, 8> PrivateCopies
;
22810 SmallVector
<Expr
*, 8> Inits
;
22812 for (Expr
*RefExpr
: VarList
) {
22813 assert(RefExpr
&& "NULL expr in OpenMP use_device_ptr clause.");
22814 SourceLocation ELoc
;
22815 SourceRange ERange
;
22816 Expr
*SimpleRefExpr
= RefExpr
;
22817 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
22819 // It will be analyzed later.
22820 MVLI
.ProcessedVarList
.push_back(RefExpr
);
22821 PrivateCopies
.push_back(nullptr);
22822 Inits
.push_back(nullptr);
22824 ValueDecl
*D
= Res
.first
;
22828 QualType Type
= D
->getType();
22829 Type
= Type
.getNonReferenceType().getUnqualifiedType();
22831 auto *VD
= dyn_cast
<VarDecl
>(D
);
22833 // Item should be a pointer or reference to pointer.
22834 if (!Type
->isPointerType()) {
22835 Diag(ELoc
, diag::err_omp_usedeviceptr_not_a_pointer
)
22836 << 0 << RefExpr
->getSourceRange();
22840 // Build the private variable and the expression that refers to it.
22842 buildVarDecl(*this, ELoc
, Type
, D
->getName(),
22843 D
->hasAttrs() ? &D
->getAttrs() : nullptr,
22844 VD
? cast
<DeclRefExpr
>(SimpleRefExpr
) : nullptr);
22845 if (VDPrivate
->isInvalidDecl())
22848 CurContext
->addDecl(VDPrivate
);
22849 DeclRefExpr
*VDPrivateRefExpr
= buildDeclRefExpr(
22850 *this, VDPrivate
, RefExpr
->getType().getUnqualifiedType(), ELoc
);
22852 // Add temporary variable to initialize the private copy of the pointer.
22854 buildVarDecl(*this, RefExpr
->getExprLoc(), Type
, ".devptr.temp");
22855 DeclRefExpr
*VDInitRefExpr
= buildDeclRefExpr(
22856 *this, VDInit
, RefExpr
->getType(), RefExpr
->getExprLoc());
22857 AddInitializerToDecl(VDPrivate
,
22858 DefaultLvalueConversion(VDInitRefExpr
).get(),
22859 /*DirectInit=*/false);
22861 // If required, build a capture to implement the privatization initialized
22862 // with the current list item value.
22863 DeclRefExpr
*Ref
= nullptr;
22865 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
22866 MVLI
.ProcessedVarList
.push_back(VD
? RefExpr
->IgnoreParens() : Ref
);
22867 PrivateCopies
.push_back(VDPrivateRefExpr
);
22868 Inits
.push_back(VDInitRefExpr
);
22870 // We need to add a data sharing attribute for this variable to make sure it
22871 // is correctly captured. A variable that shows up in a use_device_ptr has
22872 // similar properties of a first private variable.
22873 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_firstprivate
, Ref
);
22875 // Create a mappable component for the list item. List items in this clause
22876 // only need a component.
22877 MVLI
.VarBaseDeclarations
.push_back(D
);
22878 MVLI
.VarComponents
.resize(MVLI
.VarComponents
.size() + 1);
22879 MVLI
.VarComponents
.back().emplace_back(SimpleRefExpr
, D
,
22880 /*IsNonContiguous=*/false);
22883 if (MVLI
.ProcessedVarList
.empty())
22886 return OMPUseDevicePtrClause::Create(
22887 Context
, Locs
, MVLI
.ProcessedVarList
, PrivateCopies
, Inits
,
22888 MVLI
.VarBaseDeclarations
, MVLI
.VarComponents
);
22891 OMPClause
*Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef
<Expr
*> VarList
,
22892 const OMPVarListLocTy
&Locs
) {
22893 MappableVarListInfo
MVLI(VarList
);
22895 for (Expr
*RefExpr
: VarList
) {
22896 assert(RefExpr
&& "NULL expr in OpenMP use_device_addr clause.");
22897 SourceLocation ELoc
;
22898 SourceRange ERange
;
22899 Expr
*SimpleRefExpr
= RefExpr
;
22900 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
,
22901 /*AllowArraySection=*/true);
22903 // It will be analyzed later.
22904 MVLI
.ProcessedVarList
.push_back(RefExpr
);
22906 ValueDecl
*D
= Res
.first
;
22909 auto *VD
= dyn_cast
<VarDecl
>(D
);
22911 // If required, build a capture to implement the privatization initialized
22912 // with the current list item value.
22913 DeclRefExpr
*Ref
= nullptr;
22915 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
22916 MVLI
.ProcessedVarList
.push_back(VD
? RefExpr
->IgnoreParens() : Ref
);
22918 // We need to add a data sharing attribute for this variable to make sure it
22919 // is correctly captured. A variable that shows up in a use_device_addr has
22920 // similar properties of a first private variable.
22921 DSAStack
->addDSA(D
, RefExpr
->IgnoreParens(), OMPC_firstprivate
, Ref
);
22923 // Create a mappable component for the list item. List items in this clause
22924 // only need a component.
22925 MVLI
.VarBaseDeclarations
.push_back(D
);
22926 MVLI
.VarComponents
.emplace_back();
22927 Expr
*Component
= SimpleRefExpr
;
22928 if (VD
&& (isa
<OMPArraySectionExpr
>(RefExpr
->IgnoreParenImpCasts()) ||
22929 isa
<ArraySubscriptExpr
>(RefExpr
->IgnoreParenImpCasts())))
22930 Component
= DefaultFunctionArrayLvalueConversion(SimpleRefExpr
).get();
22931 MVLI
.VarComponents
.back().emplace_back(Component
, D
,
22932 /*IsNonContiguous=*/false);
22935 if (MVLI
.ProcessedVarList
.empty())
22938 return OMPUseDeviceAddrClause::Create(Context
, Locs
, MVLI
.ProcessedVarList
,
22939 MVLI
.VarBaseDeclarations
,
22940 MVLI
.VarComponents
);
22943 OMPClause
*Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef
<Expr
*> VarList
,
22944 const OMPVarListLocTy
&Locs
) {
22945 MappableVarListInfo
MVLI(VarList
);
22946 for (Expr
*RefExpr
: VarList
) {
22947 assert(RefExpr
&& "NULL expr in OpenMP is_device_ptr clause.");
22948 SourceLocation ELoc
;
22949 SourceRange ERange
;
22950 Expr
*SimpleRefExpr
= RefExpr
;
22951 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
22953 // It will be analyzed later.
22954 MVLI
.ProcessedVarList
.push_back(RefExpr
);
22956 ValueDecl
*D
= Res
.first
;
22960 QualType Type
= D
->getType();
22961 // item should be a pointer or array or reference to pointer or array
22962 if (!Type
.getNonReferenceType()->isPointerType() &&
22963 !Type
.getNonReferenceType()->isArrayType()) {
22964 Diag(ELoc
, diag::err_omp_argument_type_isdeviceptr
)
22965 << 0 << RefExpr
->getSourceRange();
22969 // Check if the declaration in the clause does not show up in any data
22970 // sharing attribute.
22971 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
22972 if (isOpenMPPrivate(DVar
.CKind
)) {
22973 Diag(ELoc
, diag::err_omp_variable_in_given_clause_and_dsa
)
22974 << getOpenMPClauseName(DVar
.CKind
)
22975 << getOpenMPClauseName(OMPC_is_device_ptr
)
22976 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
22977 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
22981 const Expr
*ConflictExpr
;
22982 if (DSAStack
->checkMappableExprComponentListsForDecl(
22983 D
, /*CurrentRegionOnly=*/true,
22985 OMPClauseMappableExprCommon::MappableExprComponentListRef R
,
22986 OpenMPClauseKind
) -> bool {
22987 ConflictExpr
= R
.front().getAssociatedExpression();
22990 Diag(ELoc
, diag::err_omp_map_shared_storage
) << RefExpr
->getSourceRange();
22991 Diag(ConflictExpr
->getExprLoc(), diag::note_used_here
)
22992 << ConflictExpr
->getSourceRange();
22996 // Store the components in the stack so that they can be used to check
22997 // against other clauses later on.
22998 OMPClauseMappableExprCommon::MappableComponent
MC(
22999 SimpleRefExpr
, D
, /*IsNonContiguous=*/false);
23000 DSAStack
->addMappableExpressionComponents(
23001 D
, MC
, /*WhereFoundClauseKind=*/OMPC_is_device_ptr
);
23003 // Record the expression we've just processed.
23004 MVLI
.ProcessedVarList
.push_back(SimpleRefExpr
);
23006 // Create a mappable component for the list item. List items in this clause
23007 // only need a component. We use a null declaration to signal fields in
23009 assert((isa
<DeclRefExpr
>(SimpleRefExpr
) ||
23010 isa
<CXXThisExpr
>(cast
<MemberExpr
>(SimpleRefExpr
)->getBase())) &&
23011 "Unexpected device pointer expression!");
23012 MVLI
.VarBaseDeclarations
.push_back(
23013 isa
<DeclRefExpr
>(SimpleRefExpr
) ? D
: nullptr);
23014 MVLI
.VarComponents
.resize(MVLI
.VarComponents
.size() + 1);
23015 MVLI
.VarComponents
.back().push_back(MC
);
23018 if (MVLI
.ProcessedVarList
.empty())
23021 return OMPIsDevicePtrClause::Create(Context
, Locs
, MVLI
.ProcessedVarList
,
23022 MVLI
.VarBaseDeclarations
,
23023 MVLI
.VarComponents
);
23026 OMPClause
*Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef
<Expr
*> VarList
,
23027 const OMPVarListLocTy
&Locs
) {
23028 MappableVarListInfo
MVLI(VarList
);
23029 for (Expr
*RefExpr
: VarList
) {
23030 assert(RefExpr
&& "NULL expr in OpenMP has_device_addr clause.");
23031 SourceLocation ELoc
;
23032 SourceRange ERange
;
23033 Expr
*SimpleRefExpr
= RefExpr
;
23034 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
,
23035 /*AllowArraySection=*/true);
23037 // It will be analyzed later.
23038 MVLI
.ProcessedVarList
.push_back(RefExpr
);
23040 ValueDecl
*D
= Res
.first
;
23044 // Check if the declaration in the clause does not show up in any data
23045 // sharing attribute.
23046 DSAStackTy::DSAVarData DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/false);
23047 if (isOpenMPPrivate(DVar
.CKind
)) {
23048 Diag(ELoc
, diag::err_omp_variable_in_given_clause_and_dsa
)
23049 << getOpenMPClauseName(DVar
.CKind
)
23050 << getOpenMPClauseName(OMPC_has_device_addr
)
23051 << getOpenMPDirectiveName(DSAStack
->getCurrentDirective());
23052 reportOriginalDsa(*this, DSAStack
, D
, DVar
);
23056 const Expr
*ConflictExpr
;
23057 if (DSAStack
->checkMappableExprComponentListsForDecl(
23058 D
, /*CurrentRegionOnly=*/true,
23060 OMPClauseMappableExprCommon::MappableExprComponentListRef R
,
23061 OpenMPClauseKind
) -> bool {
23062 ConflictExpr
= R
.front().getAssociatedExpression();
23065 Diag(ELoc
, diag::err_omp_map_shared_storage
) << RefExpr
->getSourceRange();
23066 Diag(ConflictExpr
->getExprLoc(), diag::note_used_here
)
23067 << ConflictExpr
->getSourceRange();
23071 // Store the components in the stack so that they can be used to check
23072 // against other clauses later on.
23073 OMPClauseMappableExprCommon::MappableComponent
MC(
23074 SimpleRefExpr
, D
, /*IsNonContiguous=*/false);
23075 DSAStack
->addMappableExpressionComponents(
23076 D
, MC
, /*WhereFoundClauseKind=*/OMPC_has_device_addr
);
23078 // Record the expression we've just processed.
23079 auto *VD
= dyn_cast
<VarDecl
>(D
);
23080 if (!VD
&& !CurContext
->isDependentContext()) {
23082 buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/true);
23083 assert(Ref
&& "has_device_addr capture failed");
23084 MVLI
.ProcessedVarList
.push_back(Ref
);
23086 MVLI
.ProcessedVarList
.push_back(RefExpr
->IgnoreParens());
23088 // Create a mappable component for the list item. List items in this clause
23089 // only need a component. We use a null declaration to signal fields in
23091 assert((isa
<DeclRefExpr
>(SimpleRefExpr
) ||
23092 isa
<CXXThisExpr
>(cast
<MemberExpr
>(SimpleRefExpr
)->getBase())) &&
23093 "Unexpected device pointer expression!");
23094 MVLI
.VarBaseDeclarations
.push_back(
23095 isa
<DeclRefExpr
>(SimpleRefExpr
) ? D
: nullptr);
23096 MVLI
.VarComponents
.resize(MVLI
.VarComponents
.size() + 1);
23097 MVLI
.VarComponents
.back().push_back(MC
);
23100 if (MVLI
.ProcessedVarList
.empty())
23103 return OMPHasDeviceAddrClause::Create(Context
, Locs
, MVLI
.ProcessedVarList
,
23104 MVLI
.VarBaseDeclarations
,
23105 MVLI
.VarComponents
);
23108 OMPClause
*Sema::ActOnOpenMPAllocateClause(
23109 Expr
*Allocator
, ArrayRef
<Expr
*> VarList
, SourceLocation StartLoc
,
23110 SourceLocation ColonLoc
, SourceLocation LParenLoc
, SourceLocation EndLoc
) {
23112 // OpenMP [2.11.4 allocate Clause, Description]
23113 // allocator is an expression of omp_allocator_handle_t type.
23114 if (!findOMPAllocatorHandleT(*this, Allocator
->getExprLoc(), DSAStack
))
23117 ExprResult AllocatorRes
= DefaultLvalueConversion(Allocator
);
23118 if (AllocatorRes
.isInvalid())
23120 AllocatorRes
= PerformImplicitConversion(AllocatorRes
.get(),
23121 DSAStack
->getOMPAllocatorHandleT(),
23122 Sema::AA_Initializing
,
23123 /*AllowExplicit=*/true);
23124 if (AllocatorRes
.isInvalid())
23126 Allocator
= AllocatorRes
.get();
23128 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23129 // allocate clauses that appear on a target construct or on constructs in a
23130 // target region must specify an allocator expression unless a requires
23131 // directive with the dynamic_allocators clause is present in the same
23132 // compilation unit.
23133 if (LangOpts
.OpenMPIsDevice
&&
23134 !DSAStack
->hasRequiresDeclWithClause
<OMPDynamicAllocatorsClause
>())
23135 targetDiag(StartLoc
, diag::err_expected_allocator_expression
);
23137 // Analyze and build list of variables.
23138 SmallVector
<Expr
*, 8> Vars
;
23139 for (Expr
*RefExpr
: VarList
) {
23140 assert(RefExpr
&& "NULL expr in OpenMP private clause.");
23141 SourceLocation ELoc
;
23142 SourceRange ERange
;
23143 Expr
*SimpleRefExpr
= RefExpr
;
23144 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
23146 // It will be analyzed later.
23147 Vars
.push_back(RefExpr
);
23149 ValueDecl
*D
= Res
.first
;
23153 auto *VD
= dyn_cast
<VarDecl
>(D
);
23154 DeclRefExpr
*Ref
= nullptr;
23155 if (!VD
&& !CurContext
->isDependentContext())
23156 Ref
= buildCapture(*this, D
, SimpleRefExpr
, /*WithInit=*/false);
23157 Vars
.push_back((VD
|| CurContext
->isDependentContext())
23158 ? RefExpr
->IgnoreParens()
23166 DSAStack
->addInnerAllocatorExpr(Allocator
);
23167 return OMPAllocateClause::Create(Context
, StartLoc
, LParenLoc
, Allocator
,
23168 ColonLoc
, EndLoc
, Vars
);
23171 OMPClause
*Sema::ActOnOpenMPNontemporalClause(ArrayRef
<Expr
*> VarList
,
23172 SourceLocation StartLoc
,
23173 SourceLocation LParenLoc
,
23174 SourceLocation EndLoc
) {
23175 SmallVector
<Expr
*, 8> Vars
;
23176 for (Expr
*RefExpr
: VarList
) {
23177 assert(RefExpr
&& "NULL expr in OpenMP nontemporal clause.");
23178 SourceLocation ELoc
;
23179 SourceRange ERange
;
23180 Expr
*SimpleRefExpr
= RefExpr
;
23181 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
);
23183 // It will be analyzed later.
23184 Vars
.push_back(RefExpr
);
23185 ValueDecl
*D
= Res
.first
;
23189 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23190 // A list-item cannot appear in more than one nontemporal clause.
23191 if (const Expr
*PrevRef
=
23192 DSAStack
->addUniqueNontemporal(D
, SimpleRefExpr
)) {
23193 Diag(ELoc
, diag::err_omp_used_in_clause_twice
)
23194 << 0 << getOpenMPClauseName(OMPC_nontemporal
) << ERange
;
23195 Diag(PrevRef
->getExprLoc(), diag::note_omp_explicit_dsa
)
23196 << getOpenMPClauseName(OMPC_nontemporal
);
23200 Vars
.push_back(RefExpr
);
23206 return OMPNontemporalClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
23210 OMPClause
*Sema::ActOnOpenMPInclusiveClause(ArrayRef
<Expr
*> VarList
,
23211 SourceLocation StartLoc
,
23212 SourceLocation LParenLoc
,
23213 SourceLocation EndLoc
) {
23214 SmallVector
<Expr
*, 8> Vars
;
23215 for (Expr
*RefExpr
: VarList
) {
23216 assert(RefExpr
&& "NULL expr in OpenMP nontemporal clause.");
23217 SourceLocation ELoc
;
23218 SourceRange ERange
;
23219 Expr
*SimpleRefExpr
= RefExpr
;
23220 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
,
23221 /*AllowArraySection=*/true);
23223 // It will be analyzed later.
23224 Vars
.push_back(RefExpr
);
23225 ValueDecl
*D
= Res
.first
;
23229 const DSAStackTy::DSAVarData DVar
=
23230 DSAStack
->getTopDSA(D
, /*FromParent=*/true);
23231 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23232 // A list item that appears in the inclusive or exclusive clause must appear
23233 // in a reduction clause with the inscan modifier on the enclosing
23234 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23235 if (DVar
.CKind
!= OMPC_reduction
|| DVar
.Modifier
!= OMPC_REDUCTION_inscan
)
23236 Diag(ELoc
, diag::err_omp_inclusive_exclusive_not_reduction
)
23237 << RefExpr
->getSourceRange();
23239 if (DSAStack
->getParentDirective() != OMPD_unknown
)
23240 DSAStack
->markDeclAsUsedInScanDirective(D
);
23241 Vars
.push_back(RefExpr
);
23247 return OMPInclusiveClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Vars
);
23250 OMPClause
*Sema::ActOnOpenMPExclusiveClause(ArrayRef
<Expr
*> VarList
,
23251 SourceLocation StartLoc
,
23252 SourceLocation LParenLoc
,
23253 SourceLocation EndLoc
) {
23254 SmallVector
<Expr
*, 8> Vars
;
23255 for (Expr
*RefExpr
: VarList
) {
23256 assert(RefExpr
&& "NULL expr in OpenMP nontemporal clause.");
23257 SourceLocation ELoc
;
23258 SourceRange ERange
;
23259 Expr
*SimpleRefExpr
= RefExpr
;
23260 auto Res
= getPrivateItem(*this, SimpleRefExpr
, ELoc
, ERange
,
23261 /*AllowArraySection=*/true);
23263 // It will be analyzed later.
23264 Vars
.push_back(RefExpr
);
23265 ValueDecl
*D
= Res
.first
;
23269 OpenMPDirectiveKind ParentDirective
= DSAStack
->getParentDirective();
23270 DSAStackTy::DSAVarData DVar
;
23271 if (ParentDirective
!= OMPD_unknown
)
23272 DVar
= DSAStack
->getTopDSA(D
, /*FromParent=*/true);
23273 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23274 // A list item that appears in the inclusive or exclusive clause must appear
23275 // in a reduction clause with the inscan modifier on the enclosing
23276 // worksharing-loop, worksharing-loop SIMD, or simd construct.
23277 if (ParentDirective
== OMPD_unknown
|| DVar
.CKind
!= OMPC_reduction
||
23278 DVar
.Modifier
!= OMPC_REDUCTION_inscan
) {
23279 Diag(ELoc
, diag::err_omp_inclusive_exclusive_not_reduction
)
23280 << RefExpr
->getSourceRange();
23282 DSAStack
->markDeclAsUsedInScanDirective(D
);
23284 Vars
.push_back(RefExpr
);
23290 return OMPExclusiveClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
, Vars
);
23293 /// Tries to find omp_alloctrait_t type.
23294 static bool findOMPAlloctraitT(Sema
&S
, SourceLocation Loc
, DSAStackTy
*Stack
) {
23295 QualType OMPAlloctraitT
= Stack
->getOMPAlloctraitT();
23296 if (!OMPAlloctraitT
.isNull())
23298 IdentifierInfo
&II
= S
.PP
.getIdentifierTable().get("omp_alloctrait_t");
23299 ParsedType PT
= S
.getTypeName(II
, Loc
, S
.getCurScope());
23300 if (!PT
.getAsOpaquePtr() || PT
.get().isNull()) {
23301 S
.Diag(Loc
, diag::err_omp_implied_type_not_found
) << "omp_alloctrait_t";
23304 Stack
->setOMPAlloctraitT(PT
.get());
23308 OMPClause
*Sema::ActOnOpenMPUsesAllocatorClause(
23309 SourceLocation StartLoc
, SourceLocation LParenLoc
, SourceLocation EndLoc
,
23310 ArrayRef
<UsesAllocatorsData
> Data
) {
23311 // OpenMP [2.12.5, target Construct]
23312 // allocator is an identifier of omp_allocator_handle_t type.
23313 if (!findOMPAllocatorHandleT(*this, StartLoc
, DSAStack
))
23315 // OpenMP [2.12.5, target Construct]
23316 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23319 [](const UsesAllocatorsData
&D
) { return D
.AllocatorTraits
; }) &&
23320 !findOMPAlloctraitT(*this, StartLoc
, DSAStack
))
23322 llvm::SmallPtrSet
<CanonicalDeclPtr
<Decl
>, 4> PredefinedAllocators
;
23323 for (int I
= 0; I
< OMPAllocateDeclAttr::OMPUserDefinedMemAlloc
; ++I
) {
23324 auto AllocatorKind
= static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I
);
23325 StringRef Allocator
=
23326 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind
);
23327 DeclarationName AllocatorName
= &Context
.Idents
.get(Allocator
);
23328 PredefinedAllocators
.insert(LookupSingleName(
23329 TUScope
, AllocatorName
, StartLoc
, Sema::LookupAnyName
));
23332 SmallVector
<OMPUsesAllocatorsClause::Data
, 4> NewData
;
23333 for (const UsesAllocatorsData
&D
: Data
) {
23334 Expr
*AllocatorExpr
= nullptr;
23335 // Check allocator expression.
23336 if (D
.Allocator
->isTypeDependent()) {
23337 AllocatorExpr
= D
.Allocator
;
23339 // Traits were specified - need to assign new allocator to the specified
23340 // allocator, so it must be an lvalue.
23341 AllocatorExpr
= D
.Allocator
->IgnoreParenImpCasts();
23342 auto *DRE
= dyn_cast
<DeclRefExpr
>(AllocatorExpr
);
23343 bool IsPredefinedAllocator
= false;
23345 IsPredefinedAllocator
= PredefinedAllocators
.count(DRE
->getDecl());
23347 !(Context
.hasSameUnqualifiedType(
23348 AllocatorExpr
->getType(), DSAStack
->getOMPAllocatorHandleT()) ||
23349 Context
.typesAreCompatible(AllocatorExpr
->getType(),
23350 DSAStack
->getOMPAllocatorHandleT(),
23351 /*CompareUnqualified=*/true)) ||
23352 (!IsPredefinedAllocator
&&
23353 (AllocatorExpr
->getType().isConstant(Context
) ||
23354 !AllocatorExpr
->isLValue()))) {
23355 Diag(D
.Allocator
->getExprLoc(), diag::err_omp_var_expected
)
23356 << "omp_allocator_handle_t" << (DRE
? 1 : 0)
23357 << AllocatorExpr
->getType() << D
.Allocator
->getSourceRange();
23360 // OpenMP [2.12.5, target Construct]
23361 // Predefined allocators appearing in a uses_allocators clause cannot have
23362 // traits specified.
23363 if (IsPredefinedAllocator
&& D
.AllocatorTraits
) {
23364 Diag(D
.AllocatorTraits
->getExprLoc(),
23365 diag::err_omp_predefined_allocator_with_traits
)
23366 << D
.AllocatorTraits
->getSourceRange();
23367 Diag(D
.Allocator
->getExprLoc(), diag::note_omp_predefined_allocator
)
23368 << cast
<NamedDecl
>(DRE
->getDecl())->getName()
23369 << D
.Allocator
->getSourceRange();
23372 // OpenMP [2.12.5, target Construct]
23373 // Non-predefined allocators appearing in a uses_allocators clause must
23374 // have traits specified.
23375 if (!IsPredefinedAllocator
&& !D
.AllocatorTraits
) {
23376 Diag(D
.Allocator
->getExprLoc(),
23377 diag::err_omp_nonpredefined_allocator_without_traits
);
23380 // No allocator traits - just convert it to rvalue.
23381 if (!D
.AllocatorTraits
)
23382 AllocatorExpr
= DefaultLvalueConversion(AllocatorExpr
).get();
23383 DSAStack
->addUsesAllocatorsDecl(
23385 IsPredefinedAllocator
23386 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23387 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator
);
23389 Expr
*AllocatorTraitsExpr
= nullptr;
23390 if (D
.AllocatorTraits
) {
23391 if (D
.AllocatorTraits
->isTypeDependent()) {
23392 AllocatorTraitsExpr
= D
.AllocatorTraits
;
23394 // OpenMP [2.12.5, target Construct]
23395 // Arrays that contain allocator traits that appear in a uses_allocators
23396 // clause must be constant arrays, have constant values and be defined
23397 // in the same scope as the construct in which the clause appears.
23398 AllocatorTraitsExpr
= D
.AllocatorTraits
->IgnoreParenImpCasts();
23399 // Check that traits expr is a constant array.
23401 if (const ArrayType
*Ty
=
23402 AllocatorTraitsExpr
->getType()->getAsArrayTypeUnsafe())
23403 if (const auto *ConstArrayTy
= dyn_cast
<ConstantArrayType
>(Ty
))
23404 TraitTy
= ConstArrayTy
->getElementType();
23405 if (TraitTy
.isNull() ||
23406 !(Context
.hasSameUnqualifiedType(TraitTy
,
23407 DSAStack
->getOMPAlloctraitT()) ||
23408 Context
.typesAreCompatible(TraitTy
, DSAStack
->getOMPAlloctraitT(),
23409 /*CompareUnqualified=*/true))) {
23410 Diag(D
.AllocatorTraits
->getExprLoc(),
23411 diag::err_omp_expected_array_alloctraits
)
23412 << AllocatorTraitsExpr
->getType();
23415 // Do not map by default allocator traits if it is a standalone
23417 if (auto *DRE
= dyn_cast
<DeclRefExpr
>(AllocatorTraitsExpr
))
23418 DSAStack
->addUsesAllocatorsDecl(
23420 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait
);
23423 OMPUsesAllocatorsClause::Data
&NewD
= NewData
.emplace_back();
23424 NewD
.Allocator
= AllocatorExpr
;
23425 NewD
.AllocatorTraits
= AllocatorTraitsExpr
;
23426 NewD
.LParenLoc
= D
.LParenLoc
;
23427 NewD
.RParenLoc
= D
.RParenLoc
;
23429 return OMPUsesAllocatorsClause::Create(Context
, StartLoc
, LParenLoc
, EndLoc
,
23433 OMPClause
*Sema::ActOnOpenMPAffinityClause(
23434 SourceLocation StartLoc
, SourceLocation LParenLoc
, SourceLocation ColonLoc
,
23435 SourceLocation EndLoc
, Expr
*Modifier
, ArrayRef
<Expr
*> Locators
) {
23436 SmallVector
<Expr
*, 8> Vars
;
23437 for (Expr
*RefExpr
: Locators
) {
23438 assert(RefExpr
&& "NULL expr in OpenMP shared clause.");
23439 if (isa
<DependentScopeDeclRefExpr
>(RefExpr
) || RefExpr
->isTypeDependent()) {
23440 // It will be analyzed later.
23441 Vars
.push_back(RefExpr
);
23445 SourceLocation ELoc
= RefExpr
->getExprLoc();
23446 Expr
*SimpleExpr
= RefExpr
->IgnoreParenImpCasts();
23448 if (!SimpleExpr
->isLValue()) {
23449 Diag(ELoc
, diag::err_omp_expected_addressable_lvalue_or_array_item
)
23450 << 1 << 0 << RefExpr
->getSourceRange();
23456 Sema::TentativeAnalysisScope
Trap(*this);
23457 Res
= CreateBuiltinUnaryOp(ELoc
, UO_AddrOf
, SimpleExpr
);
23459 if (!Res
.isUsable() && !isa
<OMPArraySectionExpr
>(SimpleExpr
) &&
23460 !isa
<OMPArrayShapingExpr
>(SimpleExpr
)) {
23461 Diag(ELoc
, diag::err_omp_expected_addressable_lvalue_or_array_item
)
23462 << 1 << 0 << RefExpr
->getSourceRange();
23465 Vars
.push_back(SimpleExpr
);
23468 return OMPAffinityClause::Create(Context
, StartLoc
, LParenLoc
, ColonLoc
,
23469 EndLoc
, Modifier
, Vars
);
23472 OMPClause
*Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind
,
23473 SourceLocation KindLoc
,
23474 SourceLocation StartLoc
,
23475 SourceLocation LParenLoc
,
23476 SourceLocation EndLoc
) {
23477 if (Kind
== OMPC_BIND_unknown
) {
23478 Diag(KindLoc
, diag::err_omp_unexpected_clause_value
)
23479 << getListOfPossibleValues(OMPC_bind
, /*First=*/0,
23480 /*Last=*/unsigned(OMPC_BIND_unknown
))
23481 << getOpenMPClauseName(OMPC_bind
);
23485 return OMPBindClause::Create(Context
, Kind
, KindLoc
, StartLoc
, LParenLoc
,