1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// This file implements semantic analysis for OpenMP directives and
12 //===----------------------------------------------------------------------===//
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/Frontend/OpenMP/OMPConstants.h"
41 using namespace clang;
42 using namespace llvm::omp;
44 //===----------------------------------------------------------------------===//
45 // Stack of data-sharing attributes for variables
46 //===----------------------------------------------------------------------===//
48 static const Expr *checkMapClauseExpressionBase(
49 Sema &SemaRef, Expr *E,
50 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
51 OpenMPClauseKind CKind, bool NoDiagnose);
54 /// Default data sharing attributes, which can be applied to directive.
55 enum DefaultDataSharingAttributes {
56 DSA_unspecified = 0, /// Data sharing attribute not specified.
57 DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
58 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
59 DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
62 /// Stack for tracking declarations used in OpenMP directives and
63 /// clauses and their data-sharing attributes.
67 OpenMPDirectiveKind DKind = OMPD_unknown;
68 OpenMPClauseKind CKind = OMPC_unknown;
69 unsigned Modifier = 0;
70 const Expr *RefExpr = nullptr;
71 DeclRefExpr *PrivateCopy = nullptr;
72 SourceLocation ImplicitDSALoc;
73 DSAVarData() = default;
74 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
75 const Expr *RefExpr, DeclRefExpr *PrivateCopy,
76 SourceLocation ImplicitDSALoc, unsigned Modifier)
77 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
78 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
80 using OperatorOffsetTy =
81 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
82 using DoacrossDependMapTy =
83 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
84 /// Kind of the declaration used in the uses_allocators clauses.
85 enum class UsesAllocatorsDeclKind {
86 /// Predefined allocator
88 /// User-defined allocator
90 /// The declaration that represent allocator trait
96 OpenMPClauseKind Attributes = OMPC_unknown;
97 unsigned Modifier = 0;
98 /// Pointer to a reference expression and a flag which shows that the
99 /// variable is marked as lastprivate(true) or not (false).
100 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
101 DeclRefExpr *PrivateCopy = nullptr;
103 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
104 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
105 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
106 using LoopControlVariablesMapTy =
107 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
108 /// Struct that associates a component with the clause kind where they are
110 struct MappedExprComponentTy {
111 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
112 OpenMPClauseKind Kind = OMPC_unknown;
114 using MappedExprComponentsTy =
115 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
116 using CriticalsWithHintsTy =
117 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
118 struct ReductionData {
119 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
120 SourceRange ReductionRange;
121 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
122 ReductionData() = default;
123 void set(BinaryOperatorKind BO, SourceRange RR) {
127 void set(const Expr *RefExpr, SourceRange RR) {
129 ReductionOp = RefExpr;
132 using DeclReductionMapTy =
133 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
134 struct DefaultmapInfo {
135 OpenMPDefaultmapClauseModifier ImplicitBehavior =
136 OMPC_DEFAULTMAP_MODIFIER_unknown;
138 DefaultmapInfo() = default;
139 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
140 : ImplicitBehavior(M), SLoc(Loc) {}
143 struct SharingMapTy {
144 DeclSAMapTy SharingMap;
145 DeclReductionMapTy ReductionMap;
146 UsedRefMapTy AlignedMap;
147 UsedRefMapTy NontemporalMap;
148 MappedExprComponentsTy MappedExprComponents;
149 LoopControlVariablesMapTy LCVMap;
150 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
151 SourceLocation DefaultAttrLoc;
152 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
153 OpenMPDirectiveKind Directive = OMPD_unknown;
154 DeclarationNameInfo DirectiveName;
155 Scope *CurScope = nullptr;
156 SourceLocation ConstructLoc;
157 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
158 /// get the data (loop counters etc.) about enclosing loop-based construct.
159 /// This data is required during codegen.
160 DoacrossDependMapTy DoacrossDepends;
161 /// First argument (Expr *) contains optional argument of the
162 /// 'ordered' clause, the second one is true if the regions has 'ordered'
163 /// clause, false otherwise.
164 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
165 unsigned AssociatedLoops = 1;
166 bool HasMutipleLoops = false;
167 const Decl *PossiblyLoopCounter = nullptr;
168 bool NowaitRegion = false;
169 bool CancelRegion = false;
170 bool LoopStart = false;
171 bool BodyComplete = false;
172 SourceLocation PrevScanLocation;
173 SourceLocation PrevOrderedLocation;
174 SourceLocation InnerTeamsRegionLoc;
175 /// Reference to the taskgroup task_reduction reference expression.
176 Expr *TaskgroupReductionRef = nullptr;
177 llvm::DenseSet<QualType> MappedClassesQualTypes;
178 SmallVector<Expr *, 4> InnerUsedAllocators;
179 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
180 /// List of globals marked as declare target link in this target region
181 /// (isOpenMPTargetExecutionDirective(Directive) == true).
182 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
183 /// List of decls used in inclusive/exclusive clauses of the scan directive.
184 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
185 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
187 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
188 Scope *CurScope, SourceLocation Loc)
189 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
191 SharingMapTy() = default;
194 using StackTy = SmallVector<SharingMapTy, 4>;
196 /// Stack of used declaration and their data-sharing attributes.
197 DeclSAMapTy Threadprivates;
198 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
199 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
200 /// true, if check for DSA must be from parent directive, false, if
201 /// from current directive.
202 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
204 bool ForceCapturing = false;
205 /// true if all the variables in the target executable directives must be
206 /// captured by reference.
207 bool ForceCaptureByReferenceInTargetExecutable = false;
208 CriticalsWithHintsTy Criticals;
209 unsigned IgnoredStackElements = 0;
211 /// Iterators over the stack iterate in order from innermost to outermost
213 using const_iterator = StackTy::const_reverse_iterator;
214 const_iterator begin() const {
215 return Stack.empty() ? const_iterator()
216 : Stack.back().first.rbegin() + IgnoredStackElements;
218 const_iterator end() const {
219 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
221 using iterator = StackTy::reverse_iterator;
223 return Stack.empty() ? iterator()
224 : Stack.back().first.rbegin() + IgnoredStackElements;
227 return Stack.empty() ? iterator() : Stack.back().first.rend();
230 // Convenience operations to get at the elements of the stack.
232 bool isStackEmpty() const {
233 return Stack.empty() ||
234 Stack.back().second != CurrentNonCapturingFunctionScope ||
235 Stack.back().first.size() <= IgnoredStackElements;
237 size_t getStackSize() const {
238 return isStackEmpty() ? 0
239 : Stack.back().first.size() - IgnoredStackElements;
242 SharingMapTy *getTopOfStackOrNull() {
243 size_t Size = getStackSize();
246 return &Stack.back().first[Size - 1];
248 const SharingMapTy *getTopOfStackOrNull() const {
249 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
251 SharingMapTy &getTopOfStack() {
252 assert(!isStackEmpty() && "no current directive");
253 return *getTopOfStackOrNull();
255 const SharingMapTy &getTopOfStack() const {
256 return const_cast<DSAStackTy&>(*this).getTopOfStack();
259 SharingMapTy *getSecondOnStackOrNull() {
260 size_t Size = getStackSize();
263 return &Stack.back().first[Size - 2];
265 const SharingMapTy *getSecondOnStackOrNull() const {
266 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
269 /// Get the stack element at a certain level (previously returned by
270 /// \c getNestingLevel).
272 /// Note that nesting levels count from outermost to innermost, and this is
273 /// the reverse of our iteration order where new inner levels are pushed at
274 /// the front of the stack.
275 SharingMapTy &getStackElemAtLevel(unsigned Level) {
276 assert(Level < getStackSize() && "no such stack element");
277 return Stack.back().first[Level];
279 const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
280 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
283 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
285 /// Checks if the variable is a local for OpenMP region.
286 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
288 /// Vector of previously declared requires directives
289 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
290 /// omp_allocator_handle_t type.
291 QualType OMPAllocatorHandleT;
292 /// omp_depend_t type.
294 /// omp_event_handle_t type.
295 QualType OMPEventHandleT;
296 /// omp_alloctrait_t type.
297 QualType OMPAlloctraitT;
298 /// Expression for the predefined allocators.
299 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
301 /// Vector of previously encountered target directives
302 SmallVector<SourceLocation, 2> TargetLocations;
303 SourceLocation AtomicLocation;
306 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
308 /// Sets omp_allocator_handle_t type.
309 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
310 /// Gets omp_allocator_handle_t type.
311 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
312 /// Sets omp_alloctrait_t type.
313 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
314 /// Gets omp_alloctrait_t type.
315 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
316 /// Sets the given default allocator.
317 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
319 OMPPredefinedAllocators[AllocatorKind] = Allocator;
321 /// Returns the specified default allocator.
322 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
323 return OMPPredefinedAllocators[AllocatorKind];
325 /// Sets omp_depend_t type.
326 void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
327 /// Gets omp_depend_t type.
328 QualType getOMPDependT() const { return OMPDependT; }
330 /// Sets omp_event_handle_t type.
331 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
332 /// Gets omp_event_handle_t type.
333 QualType getOMPEventHandleT() const { return OMPEventHandleT; }
335 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
336 OpenMPClauseKind getClauseParsingMode() const {
337 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
338 return ClauseKindMode;
340 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
342 bool isBodyComplete() const {
343 const SharingMapTy *Top = getTopOfStackOrNull();
344 return Top && Top->BodyComplete;
346 void setBodyComplete() {
347 getTopOfStack().BodyComplete = true;
350 bool isForceVarCapturing() const { return ForceCapturing; }
351 void setForceVarCapturing(bool V) { ForceCapturing = V; }
353 void setForceCaptureByReferenceInTargetExecutable(bool V) {
354 ForceCaptureByReferenceInTargetExecutable = V;
356 bool isForceCaptureByReferenceInTargetExecutable() const {
357 return ForceCaptureByReferenceInTargetExecutable;
360 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
361 Scope *CurScope, SourceLocation Loc) {
362 assert(!IgnoredStackElements &&
363 "cannot change stack while ignoring elements");
365 Stack.back().second != CurrentNonCapturingFunctionScope)
366 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
367 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
368 Stack.back().first.back().DefaultAttrLoc = Loc;
372 assert(!IgnoredStackElements &&
373 "cannot change stack while ignoring elements");
374 assert(!Stack.back().first.empty() &&
375 "Data-sharing attributes stack is empty!");
376 Stack.back().first.pop_back();
379 /// RAII object to temporarily leave the scope of a directive when we want to
380 /// logically operate in its parent.
381 class ParentDirectiveScope {
385 ParentDirectiveScope(DSAStackTy &Self, bool Activate)
386 : Self(Self), Active(false) {
390 ~ParentDirectiveScope() { disable(); }
393 --Self.IgnoredStackElements;
399 ++Self.IgnoredStackElements;
405 /// Marks that we're started loop parsing.
407 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
408 "Expected loop-based directive.");
409 getTopOfStack().LoopStart = true;
411 /// Start capturing of the variables in the loop context.
413 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
414 "Expected loop-based directive.");
415 getTopOfStack().LoopStart = false;
417 /// true, if variables are captured, false otherwise.
418 bool isLoopStarted() const {
419 assert(isOpenMPLoopDirective(getCurrentDirective()) &&
420 "Expected loop-based directive.");
421 return !getTopOfStack().LoopStart;
423 /// Marks (or clears) declaration as possibly loop counter.
424 void resetPossibleLoopCounter(const Decl *D = nullptr) {
425 getTopOfStack().PossiblyLoopCounter =
426 D ? D->getCanonicalDecl() : D;
428 /// Gets the possible loop counter decl.
429 const Decl *getPossiblyLoopCunter() const {
430 return getTopOfStack().PossiblyLoopCounter;
432 /// Start new OpenMP region stack in new non-capturing function.
433 void pushFunction() {
434 assert(!IgnoredStackElements &&
435 "cannot change stack while ignoring elements");
436 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
437 assert(!isa<CapturingScopeInfo>(CurFnScope));
438 CurrentNonCapturingFunctionScope = CurFnScope;
440 /// Pop region stack for non-capturing function.
441 void popFunction(const FunctionScopeInfo *OldFSI) {
442 assert(!IgnoredStackElements &&
443 "cannot change stack while ignoring elements");
444 if (!Stack.empty() && Stack.back().second == OldFSI) {
445 assert(Stack.back().first.empty());
448 CurrentNonCapturingFunctionScope = nullptr;
449 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
450 if (!isa<CapturingScopeInfo>(FSI)) {
451 CurrentNonCapturingFunctionScope = FSI;
457 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
458 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
460 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
461 getCriticalWithHint(const DeclarationNameInfo &Name) const {
462 auto I = Criticals.find(Name.getAsString());
463 if (I != Criticals.end())
465 return std::make_pair(nullptr, llvm::APSInt());
467 /// If 'aligned' declaration for given variable \a D was not seen yet,
468 /// add it and return NULL; otherwise return previous occurrence's expression
470 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
471 /// If 'nontemporal' declaration for given variable \a D was not seen yet,
472 /// add it and return NULL; otherwise return previous occurrence's expression
474 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
476 /// Register specified variable as loop control variable.
477 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
478 /// Check if the specified variable is a loop control variable for
480 /// \return The index of the loop control variable in the list of associated
481 /// for-loops (from outer to inner).
482 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
483 /// Check if the specified variable is a loop control variable for
485 /// \return The index of the loop control variable in the list of associated
486 /// for-loops (from outer to inner).
487 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
488 /// Check if the specified variable is a loop control variable for
490 /// \return The index of the loop control variable in the list of associated
491 /// for-loops (from outer to inner).
492 const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
493 unsigned Level) const;
494 /// Get the loop control variable for the I-th loop (or nullptr) in
495 /// parent directive.
496 const ValueDecl *getParentLoopControlVariable(unsigned I) const;
498 /// Marks the specified decl \p D as used in scan directive.
499 void markDeclAsUsedInScanDirective(ValueDecl *D) {
500 if (SharingMapTy *Stack = getSecondOnStackOrNull())
501 Stack->UsedInScanDirective.insert(D);
504 /// Checks if the specified declaration was used in the inner scan directive.
505 bool isUsedInScanDirective(ValueDecl *D) const {
506 if (const SharingMapTy *Stack = getTopOfStackOrNull())
507 return Stack->UsedInScanDirective.count(D) > 0;
511 /// Adds explicit data sharing attribute to the specified declaration.
512 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
513 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0);
515 /// Adds additional information for the reduction items with the reduction id
516 /// represented as an operator.
517 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
518 BinaryOperatorKind BOK);
519 /// Adds additional information for the reduction items with the reduction id
520 /// represented as reduction identifier.
521 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
522 const Expr *ReductionRef);
523 /// Returns the location and reduction operation from the innermost parent
524 /// region for the given \p D.
526 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
527 BinaryOperatorKind &BOK,
528 Expr *&TaskgroupDescriptor) const;
529 /// Returns the location and reduction operation from the innermost parent
530 /// region for the given \p D.
532 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
533 const Expr *&ReductionRef,
534 Expr *&TaskgroupDescriptor) const;
535 /// Return reduction reference expression for the current taskgroup or
536 /// parallel/worksharing directives with task reductions.
537 Expr *getTaskgroupReductionRef() const {
538 assert((getTopOfStack().Directive == OMPD_taskgroup ||
539 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
540 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
541 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
542 "taskgroup reference expression requested for non taskgroup or "
543 "parallel/worksharing directive.");
544 return getTopOfStack().TaskgroupReductionRef;
546 /// Checks if the given \p VD declaration is actually a taskgroup reduction
547 /// descriptor variable at the \p Level of OpenMP regions.
548 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
549 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
550 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
554 /// Returns data sharing attributes from top of the stack for the
555 /// specified declaration.
556 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
557 /// Returns data-sharing attributes for the specified declaration.
558 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
559 /// Returns data-sharing attributes for the specified declaration.
560 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
561 /// Checks if the specified variables has data-sharing attributes which
562 /// match specified \a CPred predicate in any directive which matches \a DPred
565 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
566 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
567 bool FromParent) const;
568 /// Checks if the specified variables has data-sharing attributes which
569 /// match specified \a CPred predicate in any innermost directive which
570 /// matches \a DPred predicate.
572 hasInnermostDSA(ValueDecl *D,
573 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
574 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
575 bool FromParent) const;
576 /// Checks if the specified variables has explicit data-sharing
577 /// attributes which match specified \a CPred predicate at the specified
579 bool hasExplicitDSA(const ValueDecl *D,
580 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
581 unsigned Level, bool NotLastprivate = false) const;
583 /// Returns true if the directive at level \Level matches in the
584 /// specified \a DPred predicate.
585 bool hasExplicitDirective(
586 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
587 unsigned Level) const;
589 /// Finds a directive which matches specified \a DPred predicate.
591 const llvm::function_ref<bool(
592 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
594 bool FromParent) const;
596 /// Returns currently analyzed directive.
597 OpenMPDirectiveKind getCurrentDirective() const {
598 const SharingMapTy *Top = getTopOfStackOrNull();
599 return Top ? Top->Directive : OMPD_unknown;
601 /// Returns directive kind at specified level.
602 OpenMPDirectiveKind getDirective(unsigned Level) const {
603 assert(!isStackEmpty() && "No directive at specified level.");
604 return getStackElemAtLevel(Level).Directive;
606 /// Returns the capture region at the specified level.
607 OpenMPDirectiveKind getCaptureRegion(unsigned Level,
608 unsigned OpenMPCaptureLevel) const {
609 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
610 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
611 return CaptureRegions[OpenMPCaptureLevel];
613 /// Returns parent directive.
614 OpenMPDirectiveKind getParentDirective() const {
615 const SharingMapTy *Parent = getSecondOnStackOrNull();
616 return Parent ? Parent->Directive : OMPD_unknown;
619 /// Add requires decl to internal vector
620 void addRequiresDecl(OMPRequiresDecl *RD) {
621 RequiresDecls.push_back(RD);
624 /// Checks if the defined 'requires' directive has specified type of clause.
625 template <typename ClauseType>
626 bool hasRequiresDeclWithClause() const {
627 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
628 return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
629 return isa<ClauseType>(C);
634 /// Checks for a duplicate clause amongst previously declared requires
636 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
637 bool IsDuplicate = false;
638 for (OMPClause *CNew : ClauseList) {
639 for (const OMPRequiresDecl *D : RequiresDecls) {
640 for (const OMPClause *CPrev : D->clauselists()) {
641 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
642 SemaRef.Diag(CNew->getBeginLoc(),
643 diag::err_omp_requires_clause_redeclaration)
644 << getOpenMPClauseName(CNew->getClauseKind());
645 SemaRef.Diag(CPrev->getBeginLoc(),
646 diag::note_omp_requires_previous_clause)
647 << getOpenMPClauseName(CPrev->getClauseKind());
656 /// Add location of previously encountered target to internal vector
657 void addTargetDirLocation(SourceLocation LocStart) {
658 TargetLocations.push_back(LocStart);
661 /// Add location for the first encountered atomicc directive.
662 void addAtomicDirectiveLoc(SourceLocation Loc) {
663 if (AtomicLocation.isInvalid())
664 AtomicLocation = Loc;
667 /// Returns the location of the first encountered atomic directive in the
669 SourceLocation getAtomicDirectiveLoc() const {
670 return AtomicLocation;
673 // Return previously encountered target region locations.
674 ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
675 return TargetLocations;
678 /// Set default data sharing attribute to none.
679 void setDefaultDSANone(SourceLocation Loc) {
680 getTopOfStack().DefaultAttr = DSA_none;
681 getTopOfStack().DefaultAttrLoc = Loc;
683 /// Set default data sharing attribute to shared.
684 void setDefaultDSAShared(SourceLocation Loc) {
685 getTopOfStack().DefaultAttr = DSA_shared;
686 getTopOfStack().DefaultAttrLoc = Loc;
688 /// Set default data sharing attribute to firstprivate.
689 void setDefaultDSAFirstPrivate(SourceLocation Loc) {
690 getTopOfStack().DefaultAttr = DSA_firstprivate;
691 getTopOfStack().DefaultAttrLoc = Loc;
693 /// Set default data mapping attribute to Modifier:Kind
694 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
695 OpenMPDefaultmapClauseKind Kind,
696 SourceLocation Loc) {
697 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
698 DMI.ImplicitBehavior = M;
701 /// Check whether the implicit-behavior has been set in defaultmap
702 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
703 if (VariableCategory == OMPC_DEFAULTMAP_unknown)
704 return getTopOfStack()
705 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
706 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
708 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
709 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
711 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
712 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
713 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
714 OMPC_DEFAULTMAP_MODIFIER_unknown;
717 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
718 return getStackSize() <= Level ? DSA_unspecified
719 : getStackElemAtLevel(Level).DefaultAttr;
721 DefaultDataSharingAttributes getDefaultDSA() const {
722 return isStackEmpty() ? DSA_unspecified
723 : getTopOfStack().DefaultAttr;
725 SourceLocation getDefaultDSALocation() const {
726 return isStackEmpty() ? SourceLocation()
727 : getTopOfStack().DefaultAttrLoc;
729 OpenMPDefaultmapClauseModifier
730 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
731 return isStackEmpty()
732 ? OMPC_DEFAULTMAP_MODIFIER_unknown
733 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
735 OpenMPDefaultmapClauseModifier
736 getDefaultmapModifierAtLevel(unsigned Level,
737 OpenMPDefaultmapClauseKind Kind) const {
738 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
740 bool isDefaultmapCapturedByRef(unsigned Level,
741 OpenMPDefaultmapClauseKind Kind) const {
742 OpenMPDefaultmapClauseModifier M =
743 getDefaultmapModifierAtLevel(Level, Kind);
744 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
745 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
746 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
747 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
748 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
752 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
753 OpenMPDefaultmapClauseKind Kind) {
755 case OMPC_DEFAULTMAP_scalar:
756 case OMPC_DEFAULTMAP_pointer:
757 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
758 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
759 (M == OMPC_DEFAULTMAP_MODIFIER_default);
760 case OMPC_DEFAULTMAP_aggregate:
761 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
765 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
767 bool mustBeFirstprivateAtLevel(unsigned Level,
768 OpenMPDefaultmapClauseKind Kind) const {
769 OpenMPDefaultmapClauseModifier M =
770 getDefaultmapModifierAtLevel(Level, Kind);
771 return mustBeFirstprivateBase(M, Kind);
773 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
774 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
775 return mustBeFirstprivateBase(M, Kind);
778 /// Checks if the specified variable is a threadprivate.
779 bool isThreadPrivate(VarDecl *D) {
780 const DSAVarData DVar = getTopDSA(D, false);
781 return isOpenMPThreadPrivate(DVar.CKind);
784 /// Marks current region as ordered (it has an 'ordered' clause).
785 void setOrderedRegion(bool IsOrdered, const Expr *Param,
786 OMPOrderedClause *Clause) {
788 getTopOfStack().OrderedRegion.emplace(Param, Clause);
790 getTopOfStack().OrderedRegion.reset();
792 /// Returns true, if region is ordered (has associated 'ordered' clause),
793 /// false - otherwise.
794 bool isOrderedRegion() const {
795 if (const SharingMapTy *Top = getTopOfStackOrNull())
796 return Top->OrderedRegion.hasValue();
799 /// Returns optional parameter for the ordered region.
800 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
801 if (const SharingMapTy *Top = getTopOfStackOrNull())
802 if (Top->OrderedRegion.hasValue())
803 return Top->OrderedRegion.getValue();
804 return std::make_pair(nullptr, nullptr);
806 /// Returns true, if parent region is ordered (has associated
807 /// 'ordered' clause), false - otherwise.
808 bool isParentOrderedRegion() const {
809 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
810 return Parent->OrderedRegion.hasValue();
813 /// Returns optional parameter for the ordered region.
814 std::pair<const Expr *, OMPOrderedClause *>
815 getParentOrderedRegionParam() const {
816 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
817 if (Parent->OrderedRegion.hasValue())
818 return Parent->OrderedRegion.getValue();
819 return std::make_pair(nullptr, nullptr);
821 /// Marks current region as nowait (it has a 'nowait' clause).
822 void setNowaitRegion(bool IsNowait = true) {
823 getTopOfStack().NowaitRegion = IsNowait;
825 /// Returns true, if parent region is nowait (has associated
826 /// 'nowait' clause), false - otherwise.
827 bool isParentNowaitRegion() const {
828 if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829 return Parent->NowaitRegion;
832 /// Marks parent region as cancel region.
833 void setParentCancelRegion(bool Cancel = true) {
834 if (SharingMapTy *Parent = getSecondOnStackOrNull())
835 Parent->CancelRegion |= Cancel;
837 /// Return true if current region has inner cancel construct.
838 bool isCancelRegion() const {
839 const SharingMapTy *Top = getTopOfStackOrNull();
840 return Top ? Top->CancelRegion : false;
843 /// Mark that parent region already has scan directive.
844 void setParentHasScanDirective(SourceLocation Loc) {
845 if (SharingMapTy *Parent = getSecondOnStackOrNull())
846 Parent->PrevScanLocation = Loc;
848 /// Return true if current region has inner cancel construct.
849 bool doesParentHasScanDirective() const {
850 const SharingMapTy *Top = getSecondOnStackOrNull();
851 return Top ? Top->PrevScanLocation.isValid() : false;
853 /// Return true if current region has inner cancel construct.
854 SourceLocation getParentScanDirectiveLoc() const {
855 const SharingMapTy *Top = getSecondOnStackOrNull();
856 return Top ? Top->PrevScanLocation : SourceLocation();
858 /// Mark that parent region already has ordered directive.
859 void setParentHasOrderedDirective(SourceLocation Loc) {
860 if (SharingMapTy *Parent = getSecondOnStackOrNull())
861 Parent->PrevOrderedLocation = Loc;
863 /// Return true if current region has inner ordered construct.
864 bool doesParentHasOrderedDirective() const {
865 const SharingMapTy *Top = getSecondOnStackOrNull();
866 return Top ? Top->PrevOrderedLocation.isValid() : false;
868 /// Returns the location of the previously specified ordered directive.
869 SourceLocation getParentOrderedDirectiveLoc() const {
870 const SharingMapTy *Top = getSecondOnStackOrNull();
871 return Top ? Top->PrevOrderedLocation : SourceLocation();
874 /// Set collapse value for the region.
875 void setAssociatedLoops(unsigned Val) {
876 getTopOfStack().AssociatedLoops = Val;
878 getTopOfStack().HasMutipleLoops = true;
880 /// Return collapse value for region.
881 unsigned getAssociatedLoops() const {
882 const SharingMapTy *Top = getTopOfStackOrNull();
883 return Top ? Top->AssociatedLoops : 0;
885 /// Returns true if the construct is associated with multiple loops.
886 bool hasMutipleLoops() const {
887 const SharingMapTy *Top = getTopOfStackOrNull();
888 return Top ? Top->HasMutipleLoops : false;
891 /// Marks current target region as one with closely nested teams
893 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
894 if (SharingMapTy *Parent = getSecondOnStackOrNull())
895 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
897 /// Returns true, if current region has closely nested teams region.
898 bool hasInnerTeamsRegion() const {
899 return getInnerTeamsRegionLoc().isValid();
901 /// Returns location of the nested teams region (if any).
902 SourceLocation getInnerTeamsRegionLoc() const {
903 const SharingMapTy *Top = getTopOfStackOrNull();
904 return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
907 Scope *getCurScope() const {
908 const SharingMapTy *Top = getTopOfStackOrNull();
909 return Top ? Top->CurScope : nullptr;
911 SourceLocation getConstructLoc() const {
912 const SharingMapTy *Top = getTopOfStackOrNull();
913 return Top ? Top->ConstructLoc : SourceLocation();
916 /// Do the check specified in \a Check to all component lists and return true
917 /// if any issue is found.
918 bool checkMappableExprComponentListsForDecl(
919 const ValueDecl *VD, bool CurrentRegionOnly,
920 const llvm::function_ref<
921 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
932 if (CurrentRegionOnly)
937 for (; SI != SE; ++SI) {
938 auto MI = SI->MappedExprComponents.find(VD);
939 if (MI != SI->MappedExprComponents.end())
940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
941 MI->second.Components)
942 if (Check(L, MI->second.Kind))
948 /// Do the check specified in \a Check to all component lists at a given level
949 /// and return true if any issue is found.
950 bool checkMappableExprComponentListsForDeclAtLevel(
951 const ValueDecl *VD, unsigned Level,
952 const llvm::function_ref<
953 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
956 if (getStackSize() <= Level)
959 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
960 auto MI = StackElem.MappedExprComponents.find(VD);
961 if (MI != StackElem.MappedExprComponents.end())
962 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
963 MI->second.Components)
964 if (Check(L, MI->second.Kind))
969 /// Create a new mappable expression component list associated with a given
970 /// declaration and initialize it with the provided list of components.
971 void addMappableExpressionComponents(
973 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
974 OpenMPClauseKind WhereFoundClauseKind) {
975 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
976 // Create new entry and append the new components there.
977 MEC.Components.resize(MEC.Components.size() + 1);
978 MEC.Components.back().append(Components.begin(), Components.end());
979 MEC.Kind = WhereFoundClauseKind;
982 unsigned getNestingLevel() const {
983 assert(!isStackEmpty());
984 return getStackSize() - 1;
986 void addDoacrossDependClause(OMPDependClause *C,
987 const OperatorOffsetTy &OpsOffs) {
988 SharingMapTy *Parent = getSecondOnStackOrNull();
989 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
990 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
992 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
993 getDoacrossDependClauses() const {
994 const SharingMapTy &StackElem = getTopOfStack();
995 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
996 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
997 return llvm::make_range(Ref.begin(), Ref.end());
999 return llvm::make_range(StackElem.DoacrossDepends.end(),
1000 StackElem.DoacrossDepends.end());
1003 // Store types of classes which have been explicitly mapped
1004 void addMappedClassesQualTypes(QualType QT) {
1005 SharingMapTy &StackElem = getTopOfStack();
1006 StackElem.MappedClassesQualTypes.insert(QT);
1009 // Return set of mapped classes types
1010 bool isClassPreviouslyMapped(QualType QT) const {
1011 const SharingMapTy &StackElem = getTopOfStack();
1012 return StackElem.MappedClassesQualTypes.count(QT) != 0;
1015 /// Adds global declare target to the parent target region.
1016 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1017 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1018 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1019 "Expected declare target link global.");
1020 for (auto &Elem : *this) {
1021 if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1022 Elem.DeclareTargetLinkVarDecls.push_back(E);
1028 /// Returns the list of globals with declare target link if current directive
1030 ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1031 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1032 "Expected target executable directive.");
1033 return getTopOfStack().DeclareTargetLinkVarDecls;
1036 /// Adds list of allocators expressions.
1037 void addInnerAllocatorExpr(Expr *E) {
1038 getTopOfStack().InnerUsedAllocators.push_back(E);
1040 /// Return list of used allocators.
1041 ArrayRef<Expr *> getInnerAllocators() const {
1042 return getTopOfStack().InnerUsedAllocators;
1044 /// Marks the declaration as implicitly firstprivate nin the task-based
1046 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1047 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1049 /// Checks if the decl is implicitly firstprivate in the task-based region.
1050 bool isImplicitTaskFirstprivate(Decl *D) const {
1051 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1054 /// Marks decl as used in uses_allocators clause as the allocator.
1055 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1056 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1058 /// Checks if specified decl is used in uses allocator clause as the
1060 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1061 const Decl *D) const {
1062 const SharingMapTy &StackElem = getTopOfStack();
1063 auto I = StackElem.UsesAllocatorsDecls.find(D);
1064 if (I == StackElem.UsesAllocatorsDecls.end())
1066 return I->getSecond();
1068 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1069 const SharingMapTy &StackElem = getTopOfStack();
1070 auto I = StackElem.UsesAllocatorsDecls.find(D);
1071 if (I == StackElem.UsesAllocatorsDecls.end())
1073 return I->getSecond();
1077 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1078 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1081 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1082 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1083 DKind == OMPD_unknown;
1088 static const Expr *getExprAsWritten(const Expr *E) {
1089 if (const auto *FE = dyn_cast<FullExpr>(E))
1090 E = FE->getSubExpr();
1092 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1093 E = MTE->getSubExpr();
1095 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1096 E = Binder->getSubExpr();
1098 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1099 E = ICE->getSubExprAsWritten();
1100 return E->IgnoreParens();
1103 static Expr *getExprAsWritten(Expr *E) {
1104 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1107 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1108 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1109 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1110 D = ME->getMemberDecl();
1111 const auto *VD = dyn_cast<VarDecl>(D);
1112 const auto *FD = dyn_cast<FieldDecl>(D);
1113 if (VD != nullptr) {
1114 VD = VD->getCanonicalDecl();
1118 FD = FD->getCanonicalDecl();
1124 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1125 return const_cast<ValueDecl *>(
1126 getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1129 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1130 ValueDecl *D) const {
1131 D = getCanonicalDecl(D);
1132 auto *VD = dyn_cast<VarDecl>(D);
1133 const auto *FD = dyn_cast<FieldDecl>(D);
1135 if (Iter == end()) {
1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1137 // in a region but not in construct]
1138 // File-scope or namespace-scope variables referenced in called routines
1139 // in the region are shared unless they appear in a threadprivate
1141 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1142 DVar.CKind = OMPC_shared;
1144 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1145 // in a region but not in construct]
1146 // Variables with static storage duration that are declared in called
1147 // routines in the region are shared.
1148 if (VD && VD->hasGlobalStorage())
1149 DVar.CKind = OMPC_shared;
1151 // Non-static data members are shared by default.
1153 DVar.CKind = OMPC_shared;
1158 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159 // in a Construct, C/C++, predetermined, p.1]
1160 // Variables with automatic storage duration that are declared in a scope
1161 // inside the construct are private.
1162 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1163 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1164 DVar.CKind = OMPC_private;
1168 DVar.DKind = Iter->Directive;
1169 // Explicitly specified attributes and local variables with predetermined
1171 if (Iter->SharingMap.count(D)) {
1172 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1173 DVar.RefExpr = Data.RefExpr.getPointer();
1174 DVar.PrivateCopy = Data.PrivateCopy;
1175 DVar.CKind = Data.Attributes;
1176 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1177 DVar.Modifier = Data.Modifier;
1181 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1182 // in a Construct, C/C++, implicitly determined, p.1]
1183 // In a parallel or task construct, the data-sharing attributes of these
1184 // variables are determined by the default clause, if present.
1185 switch (Iter->DefaultAttr) {
1187 DVar.CKind = OMPC_shared;
1188 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1192 case DSA_firstprivate:
1193 if (VD->getStorageDuration() == SD_Static &&
1194 VD->getDeclContext()->isFileContext()) {
1195 DVar.CKind = OMPC_unknown;
1197 DVar.CKind = OMPC_firstprivate;
1199 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1201 case DSA_unspecified:
1202 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1203 // in a Construct, implicitly determined, p.2]
1204 // In a parallel construct, if no default clause is present, these
1205 // variables are shared.
1206 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1207 if ((isOpenMPParallelDirective(DVar.DKind) &&
1208 !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1209 isOpenMPTeamsDirective(DVar.DKind)) {
1210 DVar.CKind = OMPC_shared;
1214 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1215 // in a Construct, implicitly determined, p.4]
1216 // In a task construct, if no default clause is present, a variable that in
1217 // the enclosing context is determined to be shared by all implicit tasks
1218 // bound to the current team is shared.
1219 if (isOpenMPTaskingDirective(DVar.DKind)) {
1220 DSAVarData DVarTemp;
1221 const_iterator I = Iter, E = end();
1224 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1225 // Referenced in a Construct, implicitly determined, p.6]
1226 // In a task construct, if no default clause is present, a variable
1227 // whose data-sharing attribute is not determined by the rules above is
1229 DVarTemp = getDSA(I, D);
1230 if (DVarTemp.CKind != OMPC_shared) {
1231 DVar.RefExpr = nullptr;
1232 DVar.CKind = OMPC_firstprivate;
1235 } while (I != E && !isImplicitTaskingRegion(I->Directive));
1237 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1241 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1242 // in a Construct, implicitly determined, p.3]
1243 // For constructs other than task, if no default clause is present, these
1244 // variables inherit their data-sharing attributes from the enclosing
1246 return getDSA(++Iter, D);
1249 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1250 const Expr *NewDE) {
1251 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1252 D = getCanonicalDecl(D);
1253 SharingMapTy &StackElem = getTopOfStack();
1254 auto It = StackElem.AlignedMap.find(D);
1255 if (It == StackElem.AlignedMap.end()) {
1256 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1257 StackElem.AlignedMap[D] = NewDE;
1260 assert(It->second && "Unexpected nullptr expr in the aligned map");
1264 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1265 const Expr *NewDE) {
1266 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1267 D = getCanonicalDecl(D);
1268 SharingMapTy &StackElem = getTopOfStack();
1269 auto It = StackElem.NontemporalMap.find(D);
1270 if (It == StackElem.NontemporalMap.end()) {
1271 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1272 StackElem.NontemporalMap[D] = NewDE;
1275 assert(It->second && "Unexpected nullptr expr in the aligned map");
1279 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1280 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1281 D = getCanonicalDecl(D);
1282 SharingMapTy &StackElem = getTopOfStack();
1283 StackElem.LCVMap.try_emplace(
1284 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1287 const DSAStackTy::LCDeclInfo
1288 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1289 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1290 D = getCanonicalDecl(D);
1291 const SharingMapTy &StackElem = getTopOfStack();
1292 auto It = StackElem.LCVMap.find(D);
1293 if (It != StackElem.LCVMap.end())
1295 return {0, nullptr};
1298 const DSAStackTy::LCDeclInfo
1299 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1300 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1301 D = getCanonicalDecl(D);
1302 for (unsigned I = Level + 1; I > 0; --I) {
1303 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1304 auto It = StackElem.LCVMap.find(D);
1305 if (It != StackElem.LCVMap.end())
1308 return {0, nullptr};
1311 const DSAStackTy::LCDeclInfo
1312 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1313 const SharingMapTy *Parent = getSecondOnStackOrNull();
1314 assert(Parent && "Data-sharing attributes stack is empty");
1315 D = getCanonicalDecl(D);
1316 auto It = Parent->LCVMap.find(D);
1317 if (It != Parent->LCVMap.end())
1319 return {0, nullptr};
1322 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1323 const SharingMapTy *Parent = getSecondOnStackOrNull();
1324 assert(Parent && "Data-sharing attributes stack is empty");
1325 if (Parent->LCVMap.size() < I)
1327 for (const auto &Pair : Parent->LCVMap)
1328 if (Pair.second.first == I)
1333 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1334 DeclRefExpr *PrivateCopy, unsigned Modifier) {
1335 D = getCanonicalDecl(D);
1336 if (A == OMPC_threadprivate) {
1337 DSAInfo &Data = Threadprivates[D];
1338 Data.Attributes = A;
1339 Data.RefExpr.setPointer(E);
1340 Data.PrivateCopy = nullptr;
1341 Data.Modifier = Modifier;
1343 DSAInfo &Data = getTopOfStack().SharingMap[D];
1344 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1345 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1346 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1347 (isLoopControlVariable(D).first && A == OMPC_private));
1348 Data.Modifier = Modifier;
1349 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1350 Data.RefExpr.setInt(/*IntVal=*/true);
1353 const bool IsLastprivate =
1354 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1355 Data.Attributes = A;
1356 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1357 Data.PrivateCopy = PrivateCopy;
1359 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1360 Data.Modifier = Modifier;
1361 Data.Attributes = A;
1362 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1363 Data.PrivateCopy = nullptr;
1368 /// Build a variable declaration for OpenMP loop iteration variable.
1369 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1370 StringRef Name, const AttrVec *Attrs = nullptr,
1371 DeclRefExpr *OrigRef = nullptr) {
1372 DeclContext *DC = SemaRef.CurContext;
1373 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1374 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1376 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1378 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1382 Decl->setImplicit();
1385 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1390 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1392 bool RefersToCapture = false) {
1394 D->markUsed(S.Context);
1395 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1396 SourceLocation(), D, RefersToCapture, Loc, Ty,
1400 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1401 BinaryOperatorKind BOK) {
1402 D = getCanonicalDecl(D);
1403 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1405 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1406 "Additional reduction info may be specified only for reduction items.");
1407 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1408 assert(ReductionData.ReductionRange.isInvalid() &&
1409 (getTopOfStack().Directive == OMPD_taskgroup ||
1410 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1411 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1412 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1413 "Additional reduction info may be specified only once for reduction "
1415 ReductionData.set(BOK, SR);
1416 Expr *&TaskgroupReductionRef =
1417 getTopOfStack().TaskgroupReductionRef;
1418 if (!TaskgroupReductionRef) {
1419 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1420 SemaRef.Context.VoidPtrTy, ".task_red.");
1421 TaskgroupReductionRef =
1422 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427 const Expr *ReductionRef) {
1428 D = getCanonicalDecl(D);
1429 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1431 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1432 "Additional reduction info may be specified only for reduction items.");
1433 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434 assert(ReductionData.ReductionRange.isInvalid() &&
1435 (getTopOfStack().Directive == OMPD_taskgroup ||
1436 ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1437 isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1438 !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1439 "Additional reduction info may be specified only once for reduction "
1441 ReductionData.set(ReductionRef, SR);
1442 Expr *&TaskgroupReductionRef =
1443 getTopOfStack().TaskgroupReductionRef;
1444 if (!TaskgroupReductionRef) {
1445 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446 SemaRef.Context.VoidPtrTy, ".task_red.");
1447 TaskgroupReductionRef =
1448 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1452 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1453 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1454 Expr *&TaskgroupDescriptor) const {
1455 D = getCanonicalDecl(D);
1456 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1457 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1458 const DSAInfo &Data = I->SharingMap.lookup(D);
1459 if (Data.Attributes != OMPC_reduction ||
1460 Data.Modifier != OMPC_REDUCTION_task)
1462 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1463 if (!ReductionData.ReductionOp ||
1464 ReductionData.ReductionOp.is<const Expr *>())
1465 return DSAVarData();
1466 SR = ReductionData.ReductionRange;
1467 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1468 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1469 "expression for the descriptor is not "
1471 TaskgroupDescriptor = I->TaskgroupReductionRef;
1472 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1473 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1475 return DSAVarData();
1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1480 Expr *&TaskgroupDescriptor) const {
1481 D = getCanonicalDecl(D);
1482 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1483 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484 const DSAInfo &Data = I->SharingMap.lookup(D);
1485 if (Data.Attributes != OMPC_reduction ||
1486 Data.Modifier != OMPC_REDUCTION_task)
1488 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489 if (!ReductionData.ReductionOp ||
1490 !ReductionData.ReductionOp.is<const Expr *>())
1491 return DSAVarData();
1492 SR = ReductionData.ReductionRange;
1493 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1494 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1495 "expression for the descriptor is not "
1497 TaskgroupDescriptor = I->TaskgroupReductionRef;
1498 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task);
1501 return DSAVarData();
1504 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1505 D = D->getCanonicalDecl();
1506 for (const_iterator E = end(); I != E; ++I) {
1507 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1508 isOpenMPTargetExecutionDirective(I->Directive)) {
1509 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1510 Scope *CurScope = getCurScope();
1511 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1512 CurScope = CurScope->getParent();
1513 return CurScope != TopScope;
1519 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1520 bool AcceptIfMutable = true,
1521 bool *IsClassType = nullptr) {
1522 ASTContext &Context = SemaRef.getASTContext();
1523 Type = Type.getNonReferenceType().getCanonicalType();
1524 bool IsConstant = Type.isConstant(Context);
1525 Type = Context.getBaseElementType(Type);
1526 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1527 ? Type->getAsCXXRecordDecl()
1529 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1530 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1531 RD = CTD->getTemplatedDecl();
1534 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1535 RD->hasDefinition() && RD->hasMutableFields());
1538 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1539 QualType Type, OpenMPClauseKind CKind,
1540 SourceLocation ELoc,
1541 bool AcceptIfMutable = true,
1542 bool ListItemNotVar = false) {
1543 ASTContext &Context = SemaRef.getASTContext();
1545 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1546 unsigned Diag = ListItemNotVar
1547 ? diag::err_omp_const_list_item
1548 : IsClassType ? diag::err_omp_const_not_mutable_variable
1549 : diag::err_omp_const_variable;
1550 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1551 if (!ListItemNotVar && D) {
1552 const VarDecl *VD = dyn_cast<VarDecl>(D);
1553 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1554 VarDecl::DeclarationOnly;
1555 SemaRef.Diag(D->getLocation(),
1556 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1564 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1566 D = getCanonicalDecl(D);
1569 auto *VD = dyn_cast<VarDecl>(D);
1570 auto TI = Threadprivates.find(D);
1571 if (TI != Threadprivates.end()) {
1572 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1573 DVar.CKind = OMPC_threadprivate;
1574 DVar.Modifier = TI->getSecond().Modifier;
1577 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1578 DVar.RefExpr = buildDeclRefExpr(
1579 SemaRef, VD, D->getType().getNonReferenceType(),
1580 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1581 DVar.CKind = OMPC_threadprivate;
1582 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1585 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1586 // in a Construct, C/C++, predetermined, p.1]
1587 // Variables appearing in threadprivate directives are threadprivate.
1588 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1589 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1590 SemaRef.getLangOpts().OpenMPUseTLS &&
1591 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1592 (VD && VD->getStorageClass() == SC_Register &&
1593 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1594 DVar.RefExpr = buildDeclRefExpr(
1595 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1596 DVar.CKind = OMPC_threadprivate;
1597 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1600 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1601 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1602 !isLoopControlVariable(D).first) {
1603 const_iterator IterTarget =
1604 std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1605 return isOpenMPTargetExecutionDirective(Data.Directive);
1607 if (IterTarget != end()) {
1608 const_iterator ParentIterTarget = IterTarget + 1;
1609 for (const_iterator Iter = begin();
1610 Iter != ParentIterTarget; ++Iter) {
1611 if (isOpenMPLocal(VD, Iter)) {
1613 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1615 DVar.CKind = OMPC_threadprivate;
1619 if (!isClauseParsingMode() || IterTarget != begin()) {
1620 auto DSAIter = IterTarget->SharingMap.find(D);
1621 if (DSAIter != IterTarget->SharingMap.end() &&
1622 isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1623 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1624 DVar.CKind = OMPC_threadprivate;
1627 const_iterator End = end();
1628 if (!SemaRef.isOpenMPCapturedByRef(
1629 D, std::distance(ParentIterTarget, End),
1630 /*OpenMPCaptureLevel=*/0)) {
1632 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1633 IterTarget->ConstructLoc);
1634 DVar.CKind = OMPC_threadprivate;
1642 // Not in OpenMP execution region and top scope was already checked.
1645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1646 // in a Construct, C/C++, predetermined, p.4]
1647 // Static data members are shared.
1648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1649 // in a Construct, C/C++, predetermined, p.7]
1650 // Variables with static storage duration that are declared in a scope
1651 // inside the construct are shared.
1652 if (VD && VD->isStaticDataMember()) {
1653 // Check for explicitly specified attributes.
1654 const_iterator I = begin();
1655 const_iterator EndI = end();
1656 if (FromParent && I != EndI)
1659 auto It = I->SharingMap.find(D);
1660 if (It != I->SharingMap.end()) {
1661 const DSAInfo &Data = It->getSecond();
1662 DVar.RefExpr = Data.RefExpr.getPointer();
1663 DVar.PrivateCopy = Data.PrivateCopy;
1664 DVar.CKind = Data.Attributes;
1665 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1666 DVar.DKind = I->Directive;
1667 DVar.Modifier = Data.Modifier;
1672 DVar.CKind = OMPC_shared;
1676 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1677 // The predetermined shared attribute for const-qualified types having no
1678 // mutable members was removed after OpenMP 3.1.
1679 if (SemaRef.LangOpts.OpenMP <= 31) {
1680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1681 // in a Construct, C/C++, predetermined, p.6]
1682 // Variables with const qualified type having no mutable member are
1684 if (isConstNotMutableType(SemaRef, D->getType())) {
1685 // Variables with const-qualified type having no mutable member may be
1686 // listed in a firstprivate clause, even if they are static data members.
1687 DSAVarData DVarTemp = hasInnermostDSA(
1689 [](OpenMPClauseKind C) {
1690 return C == OMPC_firstprivate || C == OMPC_shared;
1692 MatchesAlways, FromParent);
1693 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1696 DVar.CKind = OMPC_shared;
1701 // Explicitly specified attributes and local variables with predetermined
1703 const_iterator I = begin();
1704 const_iterator EndI = end();
1705 if (FromParent && I != EndI)
1709 auto It = I->SharingMap.find(D);
1710 if (It != I->SharingMap.end()) {
1711 const DSAInfo &Data = It->getSecond();
1712 DVar.RefExpr = Data.RefExpr.getPointer();
1713 DVar.PrivateCopy = Data.PrivateCopy;
1714 DVar.CKind = Data.Attributes;
1715 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716 DVar.DKind = I->Directive;
1717 DVar.Modifier = Data.Modifier;
1723 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1724 bool FromParent) const {
1725 if (isStackEmpty()) {
1727 return getDSA(I, D);
1729 D = getCanonicalDecl(D);
1730 const_iterator StartI = begin();
1731 const_iterator EndI = end();
1732 if (FromParent && StartI != EndI)
1734 return getDSA(StartI, D);
1737 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1738 unsigned Level) const {
1739 if (getStackSize() <= Level)
1740 return DSAVarData();
1741 D = getCanonicalDecl(D);
1742 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1743 return getDSA(StartI, D);
1746 const DSAStackTy::DSAVarData
1747 DSAStackTy::hasDSA(ValueDecl *D,
1748 const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1749 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1750 bool FromParent) const {
1753 D = getCanonicalDecl(D);
1754 const_iterator I = begin();
1755 const_iterator EndI = end();
1756 if (FromParent && I != EndI)
1758 for (; I != EndI; ++I) {
1759 if (!DPred(I->Directive) &&
1760 !isImplicitOrExplicitTaskingRegion(I->Directive))
1762 const_iterator NewI = I;
1763 DSAVarData DVar = getDSA(NewI, D);
1764 if (I == NewI && CPred(DVar.CKind))
1770 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1771 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1772 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1773 bool FromParent) const {
1776 D = getCanonicalDecl(D);
1777 const_iterator StartI = begin();
1778 const_iterator EndI = end();
1779 if (FromParent && StartI != EndI)
1781 if (StartI == EndI || !DPred(StartI->Directive))
1783 const_iterator NewI = StartI;
1784 DSAVarData DVar = getDSA(NewI, D);
1785 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1788 bool DSAStackTy::hasExplicitDSA(
1789 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1790 unsigned Level, bool NotLastprivate) const {
1791 if (getStackSize() <= Level)
1793 D = getCanonicalDecl(D);
1794 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1795 auto I = StackElem.SharingMap.find(D);
1796 if (I != StackElem.SharingMap.end() &&
1797 I->getSecond().RefExpr.getPointer() &&
1798 CPred(I->getSecond().Attributes) &&
1799 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1801 // Check predetermined rules for the loop control variables.
1802 auto LI = StackElem.LCVMap.find(D);
1803 if (LI != StackElem.LCVMap.end())
1804 return CPred(OMPC_private);
1808 bool DSAStackTy::hasExplicitDirective(
1809 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1810 unsigned Level) const {
1811 if (getStackSize() <= Level)
1813 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1814 return DPred(StackElem.Directive);
1817 bool DSAStackTy::hasDirective(
1818 const llvm::function_ref<bool(OpenMPDirectiveKind,
1819 const DeclarationNameInfo &, SourceLocation)>
1821 bool FromParent) const {
1822 // We look only in the enclosing region.
1823 size_t Skip = FromParent ? 2 : 1;
1824 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1826 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1832 void Sema::InitDataSharingAttributesStack() {
1833 VarDataSharingAttributesStack = new DSAStackTy(*this);
1836 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1838 void Sema::pushOpenMPFunctionRegion() {
1839 DSAStack->pushFunction();
1842 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1843 DSAStack->popFunction(OldFSI);
1846 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1847 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1848 "Expected OpenMP device compilation.");
1849 return !S.isInOpenMPTargetExecutionDirective() &&
1850 !S.isInOpenMPDeclareTargetContext();
1854 /// Status of the function emission on the host/device.
1855 enum class FunctionEmissionStatus {
1860 } // anonymous namespace
1862 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1864 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1865 "Expected OpenMP device compilation.");
1867 FunctionDecl *FD = getCurFunctionDecl();
1868 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1870 FunctionEmissionStatus FES = getEmissionStatus(FD);
1872 case FunctionEmissionStatus::Emitted:
1873 Kind = DeviceDiagBuilder::K_Immediate;
1875 case FunctionEmissionStatus::Unknown:
1876 Kind = isOpenMPDeviceDelayedContext(*this)
1877 ? DeviceDiagBuilder::K_Deferred
1878 : DeviceDiagBuilder::K_Immediate;
1880 case FunctionEmissionStatus::TemplateDiscarded:
1881 case FunctionEmissionStatus::OMPDiscarded:
1882 Kind = DeviceDiagBuilder::K_Nop;
1884 case FunctionEmissionStatus::CUDADiscarded:
1885 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1890 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1893 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1895 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1896 "Expected OpenMP host compilation.");
1897 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1898 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1900 case FunctionEmissionStatus::Emitted:
1901 Kind = DeviceDiagBuilder::K_Immediate;
1903 case FunctionEmissionStatus::Unknown:
1904 Kind = DeviceDiagBuilder::K_Deferred;
1906 case FunctionEmissionStatus::TemplateDiscarded:
1907 case FunctionEmissionStatus::OMPDiscarded:
1908 case FunctionEmissionStatus::CUDADiscarded:
1909 Kind = DeviceDiagBuilder::K_Nop;
1913 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1916 static OpenMPDefaultmapClauseKind
1917 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1918 if (LO.OpenMP <= 45) {
1919 if (VD->getType().getNonReferenceType()->isScalarType())
1920 return OMPC_DEFAULTMAP_scalar;
1921 return OMPC_DEFAULTMAP_aggregate;
1923 if (VD->getType().getNonReferenceType()->isAnyPointerType())
1924 return OMPC_DEFAULTMAP_pointer;
1925 if (VD->getType().getNonReferenceType()->isScalarType())
1926 return OMPC_DEFAULTMAP_scalar;
1927 return OMPC_DEFAULTMAP_aggregate;
1930 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1931 unsigned OpenMPCaptureLevel) const {
1932 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1934 ASTContext &Ctx = getASTContext();
1935 bool IsByRef = true;
1937 // Find the directive that is associated with the provided scope.
1938 D = cast<ValueDecl>(D->getCanonicalDecl());
1939 QualType Ty = D->getType();
1941 bool IsVariableUsedInMapClause = false;
1942 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1943 // This table summarizes how a given variable should be passed to the device
1944 // given its type and the clauses where it appears. This table is based on
1945 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1946 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1948 // =========================================================================
1949 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1950 // | |(tofrom:scalar)| | pvt | | | |
1951 // =========================================================================
1952 // | scl | | | | - | | bycopy|
1953 // | scl | | - | x | - | - | bycopy|
1954 // | scl | | x | - | - | - | null |
1955 // | scl | x | | | - | | byref |
1956 // | scl | x | - | x | - | - | bycopy|
1957 // | scl | x | x | - | - | - | null |
1958 // | scl | | - | - | - | x | byref |
1959 // | scl | x | - | - | - | x | byref |
1961 // | agg | n.a. | | | - | | byref |
1962 // | agg | n.a. | - | x | - | - | byref |
1963 // | agg | n.a. | x | - | - | - | null |
1964 // | agg | n.a. | - | - | - | x | byref |
1965 // | agg | n.a. | - | - | - | x[] | byref |
1967 // | ptr | n.a. | | | - | | bycopy|
1968 // | ptr | n.a. | - | x | - | - | bycopy|
1969 // | ptr | n.a. | x | - | - | - | null |
1970 // | ptr | n.a. | - | - | - | x | byref |
1971 // | ptr | n.a. | - | - | - | x[] | bycopy|
1972 // | ptr | n.a. | - | - | x | | bycopy|
1973 // | ptr | n.a. | - | - | x | x | bycopy|
1974 // | ptr | n.a. | - | - | x | x[] | bycopy|
1975 // =========================================================================
1981 // - - invalid in this combination
1982 // [] - mapped with an array section
1983 // byref - should be mapped by reference
1984 // byval - should be mapped by value
1985 // null - initialize a local variable to null on the device
1988 // - All scalar declarations that show up in a map clause have to be passed
1989 // by reference, because they may have been mapped in the enclosing data
1991 // - If the scalar value does not fit the size of uintptr, it has to be
1992 // passed by reference, regardless the result in the table above.
1993 // - For pointers mapped by value that have either an implicit map or an
1994 // array section, the runtime library may pass the NULL value to the
1995 // device instead of the value passed to it by the compiler.
1997 if (Ty->isReferenceType())
1998 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2000 // Locate map clauses and see if the variable being captured is referred to
2001 // in any of those clauses. Here we only care about variables, not fields,
2002 // because fields are part of aggregates.
2003 bool IsVariableAssociatedWithSection = false;
2005 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2007 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2008 OMPClauseMappableExprCommon::MappableExprComponentListRef
2010 OpenMPClauseKind WhereFoundClauseKind) {
2011 // Only the map clause information influences how a variable is
2012 // captured. E.g. is_device_ptr does not require changing the default
2014 if (WhereFoundClauseKind != OMPC_map)
2017 auto EI = MapExprComponents.rbegin();
2018 auto EE = MapExprComponents.rend();
2020 assert(EI != EE && "Invalid map expression!");
2022 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2023 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2029 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2030 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2031 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2032 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2033 IsVariableAssociatedWithSection = true;
2034 // There is nothing more we need to know about this variable.
2038 // Keep looking for more map info.
2042 if (IsVariableUsedInMapClause) {
2043 // If variable is identified in a map clause it is always captured by
2044 // reference except if it is a pointer that is dereferenced somehow.
2045 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2047 // By default, all the data that has a scalar type is mapped by copy
2048 // (except for reduction variables).
2049 // Defaultmap scalar is mutual exclusive to defaultmap pointer
2051 (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2052 !Ty->isAnyPointerType()) ||
2053 !Ty->isScalarType() ||
2054 DSAStack->isDefaultmapCapturedByRef(
2055 Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2056 DSAStack->hasExplicitDSA(
2057 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
2061 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2063 ((IsVariableUsedInMapClause &&
2064 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2066 !(DSAStack->hasExplicitDSA(
2068 [](OpenMPClauseKind K) -> bool {
2069 return K == OMPC_firstprivate;
2071 Level, /*NotLastprivate=*/true) ||
2072 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2073 // If the variable is artificial and must be captured by value - try to
2074 // capture by value.
2075 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2076 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2077 // If the variable is implicitly firstprivate and scalar - capture by
2079 !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2080 !DSAStack->hasExplicitDSA(
2081 D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) &&
2082 !DSAStack->isLoopControlVariable(D, Level).first);
2085 // When passing data by copy, we need to make sure it fits the uintptr size
2086 // and alignment, because the runtime library only deals with uintptr types.
2087 // If it does not fit the uintptr size, we need to pass the data by reference
2090 (Ctx.getTypeSizeInChars(Ty) >
2091 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2092 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2099 unsigned Sema::getOpenMPNestingLevel() const {
2100 assert(getLangOpts().OpenMP);
2101 return DSAStack->getNestingLevel();
2104 bool Sema::isInOpenMPTargetExecutionDirective() const {
2105 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2106 !DSAStack->isClauseParsingMode()) ||
2107 DSAStack->hasDirective(
2108 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2109 SourceLocation) -> bool {
2110 return isOpenMPTargetExecutionDirective(K);
2115 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2117 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2118 D = getCanonicalDecl(D);
2120 auto *VD = dyn_cast<VarDecl>(D);
2121 // Do not capture constexpr variables.
2122 if (VD && VD->isConstexpr())
2125 // If we want to determine whether the variable should be captured from the
2126 // perspective of the current capturing scope, and we've already left all the
2127 // capturing scopes of the top directive on the stack, check from the
2128 // perspective of its parent directive (if any) instead.
2129 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2130 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2132 // If we are attempting to capture a global variable in a directive with
2133 // 'target' we return true so that this global is also mapped to the device.
2135 if (VD && !VD->hasLocalStorage() &&
2136 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2137 if (isInOpenMPDeclareTargetContext()) {
2138 // Try to mark variable as declare target if it is used in capturing
2140 if (LangOpts.OpenMP <= 45 &&
2141 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2142 checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2144 } else if (isInOpenMPTargetExecutionDirective()) {
2145 // If the declaration is enclosed in a 'declare target' directive,
2146 // then it should not be captured.
2148 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2150 CapturedRegionScopeInfo *CSI = nullptr;
2151 for (FunctionScopeInfo *FSI : llvm::drop_begin(
2152 llvm::reverse(FunctionScopes),
2153 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2154 if (!isa<CapturingScopeInfo>(FSI))
2156 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2157 if (RSI->CapRegionKind == CR_OpenMP) {
2162 SmallVector<OpenMPDirectiveKind, 4> Regions;
2163 getOpenMPCaptureRegions(Regions,
2164 DSAStack->getDirective(CSI->OpenMPLevel));
2165 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2170 if (CheckScopeInfo) {
2171 bool OpenMPFound = false;
2172 for (unsigned I = StopAt + 1; I > 0; --I) {
2173 FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2174 if(!isa<CapturingScopeInfo>(FSI))
2176 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2177 if (RSI->CapRegionKind == CR_OpenMP) {
2186 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2187 (!DSAStack->isClauseParsingMode() ||
2188 DSAStack->getParentDirective() != OMPD_unknown)) {
2189 auto &&Info = DSAStack->isLoopControlVariable(D);
2191 (VD && VD->hasLocalStorage() &&
2192 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2193 (VD && DSAStack->isForceVarCapturing()))
2194 return VD ? VD : Info.second;
2195 DSAStackTy::DSAVarData DVarTop =
2196 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2197 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind))
2198 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2199 // Threadprivate variables must not be captured.
2200 if (isOpenMPThreadPrivate(DVarTop.CKind))
2202 // The variable is not private or it is the variable in the directive with
2203 // default(none) clause and not used in any clause.
2204 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2205 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
2206 DSAStack->isClauseParsingMode());
2207 // Global shared must not be captured.
2208 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2209 ((DSAStack->getDefaultDSA() != DSA_none &&
2210 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2211 DVarTop.CKind == OMPC_shared))
2213 if (DVarPrivate.CKind != OMPC_unknown ||
2214 (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2215 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2216 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2221 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2222 unsigned Level) const {
2223 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2226 void Sema::startOpenMPLoop() {
2227 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2228 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2229 DSAStack->loopInit();
2232 void Sema::startOpenMPCXXRangeFor() {
2233 assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2234 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2235 DSAStack->resetPossibleLoopCounter();
2236 DSAStack->loopStart();
2240 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2241 unsigned CapLevel) const {
2242 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2243 if (DSAStack->hasExplicitDirective(
2244 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2246 bool IsTriviallyCopyable =
2247 D->getType().getNonReferenceType().isTriviallyCopyableType(Context);
2248 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2249 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2250 getOpenMPCaptureRegions(CaptureRegions, DKind);
2251 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2252 (IsTriviallyCopyable ||
2253 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2254 if (DSAStack->hasExplicitDSA(
2255 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; },
2256 Level, /*NotLastprivate=*/true))
2257 return OMPC_firstprivate;
2258 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2259 if (DVar.CKind != OMPC_shared &&
2260 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2261 DSAStack->addImplicitTaskFirstprivate(Level, D);
2262 return OMPC_firstprivate;
2266 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2267 if (DSAStack->getAssociatedLoops() > 0 &&
2268 !DSAStack->isLoopStarted()) {
2269 DSAStack->resetPossibleLoopCounter(D);
2270 DSAStack->loopStart();
2271 return OMPC_private;
2273 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2274 DSAStack->isLoopControlVariable(D).first) &&
2275 !DSAStack->hasExplicitDSA(
2276 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2277 !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2278 return OMPC_private;
2280 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2281 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2282 DSAStack->isForceVarCapturing() &&
2283 !DSAStack->hasExplicitDSA(
2284 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2285 return OMPC_private;
2287 // User-defined allocators are private since they must be defined in the
2288 // context of target region.
2289 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2290 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2291 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2292 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2293 return OMPC_private;
2294 return (DSAStack->hasExplicitDSA(
2295 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2296 (DSAStack->isClauseParsingMode() &&
2297 DSAStack->getClauseParsingMode() == OMPC_private) ||
2298 // Consider taskgroup reduction descriptor variable a private
2299 // to avoid possible capture in the region.
2300 (DSAStack->hasExplicitDirective(
2301 [](OpenMPDirectiveKind K) {
2302 return K == OMPD_taskgroup ||
2303 ((isOpenMPParallelDirective(K) ||
2304 isOpenMPWorksharingDirective(K)) &&
2305 !isOpenMPSimdDirective(K));
2308 DSAStack->isTaskgroupReductionRef(D, Level)))
2313 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2315 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2316 D = getCanonicalDecl(D);
2317 OpenMPClauseKind OMPC = OMPC_unknown;
2318 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2319 const unsigned NewLevel = I - 1;
2320 if (DSAStack->hasExplicitDSA(D,
2321 [&OMPC](const OpenMPClauseKind K) {
2322 if (isOpenMPPrivate(K)) {
2330 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2332 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2333 OpenMPClauseKind) { return true; })) {
2337 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2340 if (DSAStack->mustBeFirstprivateAtLevel(
2341 NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2342 OMPC = OMPC_firstprivate;
2346 if (OMPC != OMPC_unknown)
2347 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2350 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2351 unsigned CaptureLevel) const {
2352 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2353 // Return true if the current level is no longer enclosed in a target region.
2355 SmallVector<OpenMPDirectiveKind, 4> Regions;
2356 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2357 const auto *VD = dyn_cast<VarDecl>(D);
2358 return VD && !VD->hasLocalStorage() &&
2359 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2361 Regions[CaptureLevel] != OMPD_task;
2364 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2365 unsigned CaptureLevel) const {
2366 assert(LangOpts.OpenMP && "OpenMP is not allowed");
2367 // Return true if the current level is no longer enclosed in a target region.
2369 if (const auto *VD = dyn_cast<VarDecl>(D)) {
2370 if (!VD->hasLocalStorage()) {
2371 DSAStackTy::DSAVarData TopDVar =
2372 DSAStack->getTopDSA(D, /*FromParent=*/false);
2373 unsigned NumLevels =
2374 getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2376 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2377 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1);
2378 return DVar.CKind != OMPC_shared ||
2379 isOpenMPGlobalCapturedDecl(
2381 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1);
2387 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2389 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2391 if (!OMPDeclareVariantScopes.empty()) {
2392 Diag(Loc, diag::warn_nested_declare_variant);
2395 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2398 void Sema::ActOnOpenMPEndDeclareVariant() {
2399 assert(isInOpenMPDeclareVariantScope() &&
2400 "Not in OpenMP declare variant scope!");
2402 OMPDeclareVariantScopes.pop_back();
2405 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2406 const FunctionDecl *Callee,
2407 SourceLocation Loc) {
2408 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2409 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2410 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2411 // Ignore host functions during device analyzis.
2412 if (LangOpts.OpenMPIsDevice && DevTy &&
2413 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2415 // Ignore nohost functions during host analyzis.
2416 if (!LangOpts.OpenMPIsDevice && DevTy &&
2417 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2419 const FunctionDecl *FD = Callee->getMostRecentDecl();
2420 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2421 if (LangOpts.OpenMPIsDevice && DevTy &&
2422 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2423 // Diagnose host function called during device codegen.
2424 StringRef HostDevTy =
2425 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2426 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2427 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2428 diag::note_omp_marked_device_type_here)
2432 if (!LangOpts.OpenMPIsDevice && DevTy &&
2433 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2434 // Diagnose nohost function called during host codegen.
2435 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2436 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2437 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2438 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2439 diag::note_omp_marked_device_type_here)
2444 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2445 const DeclarationNameInfo &DirName,
2446 Scope *CurScope, SourceLocation Loc) {
2447 DSAStack->push(DKind, DirName, CurScope, Loc);
2448 PushExpressionEvaluationContext(
2449 ExpressionEvaluationContext::PotentiallyEvaluated);
2452 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2453 DSAStack->setClauseParsingMode(K);
2456 void Sema::EndOpenMPClause() {
2457 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2460 static std::pair<ValueDecl *, bool>
2461 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2462 SourceRange &ERange, bool AllowArraySection = false);
2464 /// Check consistency of the reduction clauses.
2465 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2466 ArrayRef<OMPClause *> Clauses) {
2467 bool InscanFound = false;
2468 SourceLocation InscanLoc;
2469 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2470 // A reduction clause without the inscan reduction-modifier may not appear on
2471 // a construct on which a reduction clause with the inscan reduction-modifier
2473 for (OMPClause *C : Clauses) {
2474 if (C->getClauseKind() != OMPC_reduction)
2476 auto *RC = cast<OMPReductionClause>(C);
2477 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2479 InscanLoc = RC->getModifierLoc();
2482 if (RC->getModifier() == OMPC_REDUCTION_task) {
2483 // OpenMP 5.0, 2.19.5.4 reduction Clause.
2484 // A reduction clause with the task reduction-modifier may only appear on
2485 // a parallel construct, a worksharing construct or a combined or
2486 // composite construct for which any of the aforementioned constructs is a
2487 // constituent construct and simd or loop are not constituent constructs.
2488 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2489 if (!(isOpenMPParallelDirective(CurDir) ||
2490 isOpenMPWorksharingDirective(CurDir)) ||
2491 isOpenMPSimdDirective(CurDir))
2492 S.Diag(RC->getModifierLoc(),
2493 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2498 for (OMPClause *C : Clauses) {
2499 if (C->getClauseKind() != OMPC_reduction)
2501 auto *RC = cast<OMPReductionClause>(C);
2502 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2503 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2505 : RC->getModifierLoc(),
2506 diag::err_omp_inscan_reduction_expected);
2507 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2510 for (Expr *Ref : RC->varlists()) {
2511 assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2512 SourceLocation ELoc;
2514 Expr *SimpleRefExpr = Ref;
2515 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2516 /*AllowArraySection=*/true);
2517 ValueDecl *D = Res.first;
2520 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2521 S.Diag(Ref->getExprLoc(),
2522 diag::err_omp_reduction_not_inclusive_exclusive)
2523 << Ref->getSourceRange();
2530 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2531 ArrayRef<OMPClause *> Clauses);
2532 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2535 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2537 const DSAStackTy::DSAVarData &DVar,
2538 bool IsLoopIterVar = false);
2540 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2541 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2542 // A variable of class type (or array thereof) that appears in a lastprivate
2543 // clause requires an accessible, unambiguous default constructor for the
2544 // class type, unless the list item is also specified in a firstprivate
2546 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2547 for (OMPClause *C : D->clauses()) {
2548 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2549 SmallVector<Expr *, 8> PrivateCopies;
2550 for (Expr *DE : Clause->varlists()) {
2551 if (DE->isValueDependent() || DE->isTypeDependent()) {
2552 PrivateCopies.push_back(nullptr);
2555 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2556 auto *VD = cast<VarDecl>(DRE->getDecl());
2557 QualType Type = VD->getType().getNonReferenceType();
2558 const DSAStackTy::DSAVarData DVar =
2559 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2560 if (DVar.CKind == OMPC_lastprivate) {
2561 // Generate helper private variable and initialize it with the
2562 // default value. The address of the original variable is replaced
2563 // by the address of the new private variable in CodeGen. This new
2564 // variable is not added to IdResolver, so the code in the OpenMP
2565 // region uses original variable for proper diagnostics.
2566 VarDecl *VDPrivate = buildVarDecl(
2567 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2568 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2569 ActOnUninitializedDecl(VDPrivate);
2570 if (VDPrivate->isInvalidDecl()) {
2571 PrivateCopies.push_back(nullptr);
2574 PrivateCopies.push_back(buildDeclRefExpr(
2575 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2577 // The variable is also a firstprivate, so initialization sequence
2578 // for private copy is generated already.
2579 PrivateCopies.push_back(nullptr);
2582 Clause->setPrivateCopies(PrivateCopies);
2585 // Finalize nontemporal clause by handling private copies, if any.
2586 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2587 SmallVector<Expr *, 8> PrivateRefs;
2588 for (Expr *RefExpr : Clause->varlists()) {
2589 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2590 SourceLocation ELoc;
2592 Expr *SimpleRefExpr = RefExpr;
2593 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2595 // It will be analyzed later.
2596 PrivateRefs.push_back(RefExpr);
2597 ValueDecl *D = Res.first;
2601 const DSAStackTy::DSAVarData DVar =
2602 DSAStack->getTopDSA(D, /*FromParent=*/false);
2603 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2606 Clause->setPrivateRefs(PrivateRefs);
2609 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2610 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2611 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2612 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2615 ValueDecl *VD = DRE->getDecl();
2616 if (!VD || !isa<VarDecl>(VD))
2618 DSAStackTy::DSAVarData DVar =
2619 DSAStack->getTopDSA(VD, /*FromParent=*/false);
2620 // OpenMP [2.12.5, target Construct]
2621 // Memory allocators that appear in a uses_allocators clause cannot
2622 // appear in other data-sharing attribute clauses or data-mapping
2623 // attribute clauses in the same construct.
2624 Expr *MapExpr = nullptr;
2626 DSAStack->checkMappableExprComponentListsForDecl(
2627 VD, /*CurrentRegionOnly=*/true,
2629 OMPClauseMappableExprCommon::MappableExprComponentListRef
2631 OpenMPClauseKind C) {
2632 auto MI = MapExprComponents.rbegin();
2633 auto ME = MapExprComponents.rend();
2635 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2636 VD->getCanonicalDecl()) {
2637 MapExpr = MI->getAssociatedExpression();
2642 Diag(D.Allocator->getExprLoc(),
2643 diag::err_omp_allocator_used_in_clauses)
2644 << D.Allocator->getSourceRange();
2646 reportOriginalDsa(*this, DSAStack, VD, DVar);
2648 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2649 << MapExpr->getSourceRange();
2655 // Check allocate clauses.
2656 if (!CurContext->isDependentContext())
2657 checkAllocateClauses(*this, DSAStack, D->clauses());
2658 checkReductionClauses(*this, DSAStack, D->clauses());
2662 DiscardCleanupsInEvaluationContext();
2663 PopExpressionEvaluationContext();
2666 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2667 Expr *NumIterations, Sema &SemaRef,
2668 Scope *S, DSAStackTy *Stack);
2672 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2677 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2678 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2679 NamedDecl *ND = Candidate.getCorrectionDecl();
2680 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2681 return VD->hasGlobalStorage() &&
2682 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2683 SemaRef.getCurScope());
2688 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2689 return std::make_unique<VarDeclFilterCCC>(*this);
2694 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2699 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2700 bool ValidateCandidate(const TypoCorrection &Candidate) override {
2701 NamedDecl *ND = Candidate.getCorrectionDecl();
2702 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2703 isa<FunctionDecl>(ND))) {
2704 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2705 SemaRef.getCurScope());
2710 std::unique_ptr<CorrectionCandidateCallback> clone() override {
2711 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2717 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2718 CXXScopeSpec &ScopeSpec,
2719 const DeclarationNameInfo &Id,
2720 OpenMPDirectiveKind Kind) {
2721 LookupResult Lookup(*this, Id, LookupOrdinaryName);
2722 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2724 if (Lookup.isAmbiguous())
2728 if (!Lookup.isSingleResult()) {
2729 VarDeclFilterCCC CCC(*this);
2730 if (TypoCorrection Corrected =
2731 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2732 CTK_ErrorRecovery)) {
2733 diagnoseTypo(Corrected,
2734 PDiag(Lookup.empty()
2735 ? diag::err_undeclared_var_use_suggest
2736 : diag::err_omp_expected_var_arg_suggest)
2738 VD = Corrected.getCorrectionDeclAs<VarDecl>();
2740 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2741 : diag::err_omp_expected_var_arg)
2745 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2746 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2747 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2750 Lookup.suppressDiagnostics();
2752 // OpenMP [2.9.2, Syntax, C/C++]
2753 // Variables must be file-scope, namespace-scope, or static block-scope.
2754 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2755 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2756 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2758 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2759 Diag(VD->getLocation(),
2760 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2765 VarDecl *CanonicalVD = VD->getCanonicalDecl();
2766 NamedDecl *ND = CanonicalVD;
2767 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2768 // A threadprivate directive for file-scope variables must appear outside
2769 // any definition or declaration.
2770 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2771 !getCurLexicalContext()->isTranslationUnit()) {
2772 Diag(Id.getLoc(), diag::err_omp_var_scope)
2773 << getOpenMPDirectiveName(Kind) << VD;
2775 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2776 Diag(VD->getLocation(),
2777 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2781 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2782 // A threadprivate directive for static class member variables must appear
2783 // in the class definition, in the same scope in which the member
2784 // variables are declared.
2785 if (CanonicalVD->isStaticDataMember() &&
2786 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2787 Diag(Id.getLoc(), diag::err_omp_var_scope)
2788 << getOpenMPDirectiveName(Kind) << VD;
2790 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2791 Diag(VD->getLocation(),
2792 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2796 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2797 // A threadprivate directive for namespace-scope variables must appear
2798 // outside any definition or declaration other than the namespace
2799 // definition itself.
2800 if (CanonicalVD->getDeclContext()->isNamespace() &&
2801 (!getCurLexicalContext()->isFileContext() ||
2802 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2803 Diag(Id.getLoc(), diag::err_omp_var_scope)
2804 << getOpenMPDirectiveName(Kind) << VD;
2806 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2807 Diag(VD->getLocation(),
2808 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2812 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2813 // A threadprivate directive for static block-scope variables must appear
2814 // in the scope of the variable and not in a nested scope.
2815 if (CanonicalVD->isLocalVarDecl() && CurScope &&
2816 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2817 Diag(Id.getLoc(), diag::err_omp_var_scope)
2818 << getOpenMPDirectiveName(Kind) << VD;
2820 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2821 Diag(VD->getLocation(),
2822 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2827 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2828 // A threadprivate directive must lexically precede all references to any
2829 // of the variables in its list.
2830 if (Kind == OMPD_threadprivate && VD->isUsed() &&
2831 !DSAStack->isThreadPrivate(VD)) {
2832 Diag(Id.getLoc(), diag::err_omp_var_used)
2833 << getOpenMPDirectiveName(Kind) << VD;
2837 QualType ExprType = VD->getType().getNonReferenceType();
2838 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2839 SourceLocation(), VD,
2840 /*RefersToEnclosingVariableOrCapture=*/false,
2841 Id.getLoc(), ExprType, VK_LValue);
2844 Sema::DeclGroupPtrTy
2845 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2846 ArrayRef<Expr *> VarList) {
2847 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2848 CurContext->addDecl(D);
2849 return DeclGroupPtrTy::make(DeclGroupRef(D));
2855 class LocalVarRefChecker final
2856 : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2860 bool VisitDeclRefExpr(const DeclRefExpr *E) {
2861 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2862 if (VD->hasLocalStorage()) {
2863 SemaRef.Diag(E->getBeginLoc(),
2864 diag::err_omp_local_var_in_threadprivate_init)
2865 << E->getSourceRange();
2866 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2867 << VD << VD->getSourceRange();
2873 bool VisitStmt(const Stmt *S) {
2874 for (const Stmt *Child : S->children()) {
2875 if (Child && Visit(Child))
2880 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2884 OMPThreadPrivateDecl *
2885 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2886 SmallVector<Expr *, 8> Vars;
2887 for (Expr *RefExpr : VarList) {
2888 auto *DE = cast<DeclRefExpr>(RefExpr);
2889 auto *VD = cast<VarDecl>(DE->getDecl());
2890 SourceLocation ILoc = DE->getExprLoc();
2892 // Mark variable as used.
2893 VD->setReferenced();
2894 VD->markUsed(Context);
2896 QualType QType = VD->getType();
2897 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2898 // It will be analyzed later.
2903 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2904 // A threadprivate variable must not have an incomplete type.
2905 if (RequireCompleteType(ILoc, VD->getType(),
2906 diag::err_omp_threadprivate_incomplete_type)) {
2910 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2911 // A threadprivate variable must not have a reference type.
2912 if (VD->getType()->isReferenceType()) {
2913 Diag(ILoc, diag::err_omp_ref_type_arg)
2914 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2916 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2917 Diag(VD->getLocation(),
2918 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2923 // Check if this is a TLS variable. If TLS is not being supported, produce
2924 // the corresponding diagnostic.
2925 if ((VD->getTLSKind() != VarDecl::TLS_None &&
2926 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2927 getLangOpts().OpenMPUseTLS &&
2928 getASTContext().getTargetInfo().isTLSSupported())) ||
2929 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2930 !VD->isLocalVarDecl())) {
2931 Diag(ILoc, diag::err_omp_var_thread_local)
2932 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2934 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2935 Diag(VD->getLocation(),
2936 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2941 // Check if initial value of threadprivate variable reference variable with
2942 // local storage (it is not supported by runtime).
2943 if (const Expr *Init = VD->getAnyInitializer()) {
2944 LocalVarRefChecker Checker(*this);
2945 if (Checker.Visit(Init))
2949 Vars.push_back(RefExpr);
2950 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2951 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2952 Context, SourceRange(Loc, Loc)));
2953 if (ASTMutationListener *ML = Context.getASTMutationListener())
2954 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2956 OMPThreadPrivateDecl *D = nullptr;
2957 if (!Vars.empty()) {
2958 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2960 D->setAccess(AS_public);
2965 static OMPAllocateDeclAttr::AllocatorTypeTy
2966 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2968 return OMPAllocateDeclAttr::OMPNullMemAlloc;
2969 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2970 Allocator->isInstantiationDependent() ||
2971 Allocator->containsUnexpandedParameterPack())
2972 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2973 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2974 const Expr *AE = Allocator->IgnoreParenImpCasts();
2975 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2976 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2977 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2978 llvm::FoldingSetNodeID AEId, DAEId;
2979 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2980 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2981 if (AEId == DAEId) {
2982 AllocatorKindRes = AllocatorKind;
2986 return AllocatorKindRes;
2989 static bool checkPreviousOMPAllocateAttribute(
2990 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2991 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2992 if (!VD->hasAttr<OMPAllocateDeclAttr>())
2994 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2995 Expr *PrevAllocator = A->getAllocator();
2996 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2997 getAllocatorKind(S, Stack, PrevAllocator);
2998 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2999 if (AllocatorsMatch &&
3000 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3001 Allocator && PrevAllocator) {
3002 const Expr *AE = Allocator->IgnoreParenImpCasts();
3003 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3004 llvm::FoldingSetNodeID AEId, PAEId;
3005 AE->Profile(AEId, S.Context, /*Canonical=*/true);
3006 PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3007 AllocatorsMatch = AEId == PAEId;
3009 if (!AllocatorsMatch) {
3010 SmallString<256> AllocatorBuffer;
3011 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3013 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3014 SmallString<256> PrevAllocatorBuffer;
3015 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3017 PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3018 S.getPrintingPolicy());
3020 SourceLocation AllocatorLoc =
3021 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3022 SourceRange AllocatorRange =
3023 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3024 SourceLocation PrevAllocatorLoc =
3025 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3026 SourceRange PrevAllocatorRange =
3027 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3028 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3029 << (Allocator ? 1 : 0) << AllocatorStream.str()
3030 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3032 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3033 << PrevAllocatorRange;
3040 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3041 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3042 Expr *Allocator, SourceRange SR) {
3043 if (VD->hasAttr<OMPAllocateDeclAttr>())
3046 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3047 Allocator->isInstantiationDependent() ||
3048 Allocator->containsUnexpandedParameterPack()))
3050 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3053 if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3054 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3057 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3058 SourceLocation Loc, ArrayRef<Expr *> VarList,
3059 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3060 assert(Clauses.size() <= 1 && "Expected at most one clause.");
3061 Expr *Allocator = nullptr;
3062 if (Clauses.empty()) {
3063 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3064 // allocate directives that appear in a target region must specify an
3065 // allocator clause unless a requires directive with the dynamic_allocators
3066 // clause is present in the same compilation unit.
3067 if (LangOpts.OpenMPIsDevice &&
3068 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3069 targetDiag(Loc, diag::err_expected_allocator_clause);
3071 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3073 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3074 getAllocatorKind(*this, DSAStack, Allocator);
3075 SmallVector<Expr *, 8> Vars;
3076 for (Expr *RefExpr : VarList) {
3077 auto *DE = cast<DeclRefExpr>(RefExpr);
3078 auto *VD = cast<VarDecl>(DE->getDecl());
3080 // Check if this is a TLS variable or global register.
3081 if (VD->getTLSKind() != VarDecl::TLS_None ||
3082 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3083 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3084 !VD->isLocalVarDecl()))
3087 // If the used several times in the allocate directive, the same allocator
3089 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3090 AllocatorKind, Allocator))
3093 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3094 // If a list item has a static storage type, the allocator expression in the
3095 // allocator clause must be a constant expression that evaluates to one of
3096 // the predefined memory allocator values.
3097 if (Allocator && VD->hasGlobalStorage()) {
3098 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3099 Diag(Allocator->getExprLoc(),
3100 diag::err_omp_expected_predefined_allocator)
3101 << Allocator->getSourceRange();
3102 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3103 VarDecl::DeclarationOnly;
3104 Diag(VD->getLocation(),
3105 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3111 Vars.push_back(RefExpr);
3112 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3113 DE->getSourceRange());
3118 Owner = getCurLexicalContext();
3119 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3120 D->setAccess(AS_public);
3122 return DeclGroupPtrTy::make(DeclGroupRef(D));
3125 Sema::DeclGroupPtrTy
3126 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3127 ArrayRef<OMPClause *> ClauseList) {
3128 OMPRequiresDecl *D = nullptr;
3129 if (!CurContext->isFileContext()) {
3130 Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3132 D = CheckOMPRequiresDecl(Loc, ClauseList);
3134 CurContext->addDecl(D);
3135 DSAStack->addRequiresDecl(D);
3138 return DeclGroupPtrTy::make(DeclGroupRef(D));
3141 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3142 ArrayRef<OMPClause *> ClauseList) {
3143 /// For target specific clauses, the requires directive cannot be
3144 /// specified after the handling of any of the target regions in the
3145 /// current compilation unit.
3146 ArrayRef<SourceLocation> TargetLocations =
3147 DSAStack->getEncounteredTargetLocs();
3148 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3149 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3150 for (const OMPClause *CNew : ClauseList) {
3151 // Check if any of the requires clauses affect target regions.
3152 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3153 isa<OMPUnifiedAddressClause>(CNew) ||
3154 isa<OMPReverseOffloadClause>(CNew) ||
3155 isa<OMPDynamicAllocatorsClause>(CNew)) {
3156 Diag(Loc, diag::err_omp_directive_before_requires)
3157 << "target" << getOpenMPClauseName(CNew->getClauseKind());
3158 for (SourceLocation TargetLoc : TargetLocations) {
3159 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3162 } else if (!AtomicLoc.isInvalid() &&
3163 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3164 Diag(Loc, diag::err_omp_directive_before_requires)
3165 << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3166 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3172 if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3173 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3178 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3180 const DSAStackTy::DSAVarData &DVar,
3181 bool IsLoopIterVar) {
3183 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3184 << getOpenMPClauseName(DVar.CKind);
3188 PDSA_StaticMemberShared,
3189 PDSA_StaticLocalVarShared,
3190 PDSA_LoopIterVarPrivate,
3191 PDSA_LoopIterVarLinear,
3192 PDSA_LoopIterVarLastprivate,
3193 PDSA_ConstVarShared,
3194 PDSA_GlobalVarShared,
3195 PDSA_TaskVarFirstprivate,
3196 PDSA_LocalVarPrivate,
3198 } Reason = PDSA_Implicit;
3199 bool ReportHint = false;
3200 auto ReportLoc = D->getLocation();
3201 auto *VD = dyn_cast<VarDecl>(D);
3202 if (IsLoopIterVar) {
3203 if (DVar.CKind == OMPC_private)
3204 Reason = PDSA_LoopIterVarPrivate;
3205 else if (DVar.CKind == OMPC_lastprivate)
3206 Reason = PDSA_LoopIterVarLastprivate;
3208 Reason = PDSA_LoopIterVarLinear;
3209 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3210 DVar.CKind == OMPC_firstprivate) {
3211 Reason = PDSA_TaskVarFirstprivate;
3212 ReportLoc = DVar.ImplicitDSALoc;
3213 } else if (VD && VD->isStaticLocal())
3214 Reason = PDSA_StaticLocalVarShared;
3215 else if (VD && VD->isStaticDataMember())
3216 Reason = PDSA_StaticMemberShared;
3217 else if (VD && VD->isFileVarDecl())
3218 Reason = PDSA_GlobalVarShared;
3219 else if (D->getType().isConstant(SemaRef.getASTContext()))
3220 Reason = PDSA_ConstVarShared;
3221 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3223 Reason = PDSA_LocalVarPrivate;
3225 if (Reason != PDSA_Implicit) {
3226 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3227 << Reason << ReportHint
3228 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3229 } else if (DVar.ImplicitDSALoc.isValid()) {
3230 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3231 << getOpenMPClauseName(DVar.CKind);
3235 static OpenMPMapClauseKind
3236 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3237 bool IsAggregateOrDeclareTarget) {
3238 OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3240 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3241 Kind = OMPC_MAP_alloc;
3243 case OMPC_DEFAULTMAP_MODIFIER_to:
3246 case OMPC_DEFAULTMAP_MODIFIER_from:
3247 Kind = OMPC_MAP_from;
3249 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3250 Kind = OMPC_MAP_tofrom;
3252 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3253 case OMPC_DEFAULTMAP_MODIFIER_last:
3254 llvm_unreachable("Unexpected defaultmap implicit behavior");
3255 case OMPC_DEFAULTMAP_MODIFIER_none:
3256 case OMPC_DEFAULTMAP_MODIFIER_default:
3257 case OMPC_DEFAULTMAP_MODIFIER_unknown:
3258 // IsAggregateOrDeclareTarget could be true if:
3259 // 1. the implicit behavior for aggregate is tofrom
3260 // 2. it's a declare target link
3261 if (IsAggregateOrDeclareTarget) {
3262 Kind = OMPC_MAP_tofrom;
3265 llvm_unreachable("Unexpected defaultmap implicit behavior");
3267 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3272 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3275 bool ErrorFound = false;
3276 bool TryCaptureCXXThisMembers = false;
3277 CapturedStmt *CS = nullptr;
3278 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3279 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
3280 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3281 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3283 void VisitSubCaptures(OMPExecutableDirective *S) {
3284 // Check implicitly captured variables.
3285 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3287 visitSubCaptures(S->getInnermostCapturedStmt());
3288 // Try to capture inner this->member references to generate correct mappings
3290 if (TryCaptureCXXThisMembers ||
3291 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3292 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3293 [](const CapturedStmt::Capture &C) {
3294 return C.capturesThis();
3296 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3297 TryCaptureCXXThisMembers = true;
3298 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3299 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3301 // In tasks firstprivates are not captured anymore, need to analyze them
3303 if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3304 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3305 for (OMPClause *C : S->clauses())
3306 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3307 for (Expr *Ref : FC->varlists())
3314 void VisitDeclRefExpr(DeclRefExpr *E) {
3315 if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3316 E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3317 E->isInstantiationDependent())
3319 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3320 // Check the datasharing rules for the expressions in the clauses.
3322 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3323 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3324 Visit(CED->getInit());
3327 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3328 // Do not analyze internal variables and do not enclose them into
3329 // implicit clauses.
3331 VD = VD->getCanonicalDecl();
3332 // Skip internally declared variables.
3333 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3334 !Stack->isImplicitTaskFirstprivate(VD))
3336 // Skip allocators in uses_allocators clauses.
3337 if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3340 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3341 // Check if the variable has explicit DSA set and stop analysis if it so.
3342 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3345 // Skip internally declared static variables.
3346 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3347 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3348 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3349 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3350 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3351 !Stack->isImplicitTaskFirstprivate(VD))
3354 SourceLocation ELoc = E->getExprLoc();
3355 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3356 // The default(none) clause requires that each variable that is referenced
3357 // in the construct, and does not have a predetermined data-sharing
3358 // attribute, must have its data-sharing attribute explicitly determined
3359 // by being listed in a data-sharing attribute clause.
3360 if (DVar.CKind == OMPC_unknown &&
3361 (Stack->getDefaultDSA() == DSA_none ||
3362 Stack->getDefaultDSA() == DSA_firstprivate) &&
3363 isImplicitOrExplicitTaskingRegion(DKind) &&
3364 VarsWithInheritedDSA.count(VD) == 0) {
3365 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3366 if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3367 DSAStackTy::DSAVarData DVar =
3368 Stack->getImplicitDSA(VD, /*FromParent=*/false);
3369 InheritedDSA = DVar.CKind == OMPC_unknown;
3372 VarsWithInheritedDSA[VD] = E;
3376 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3377 // If implicit-behavior is none, each variable referenced in the
3378 // construct that does not have a predetermined data-sharing attribute
3379 // and does not appear in a to or link clause on a declare target
3380 // directive must be listed in a data-mapping attribute clause, a
3381 // data-haring attribute clause (including a data-sharing attribute
3382 // clause on a combined construct where target. is one of the
3383 // constituent constructs), or an is_device_ptr clause.
3384 OpenMPDefaultmapClauseKind ClauseKind =
3385 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3386 if (SemaRef.getLangOpts().OpenMP >= 50) {
3387 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3388 OMPC_DEFAULTMAP_MODIFIER_none;
3389 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3390 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3391 // Only check for data-mapping attribute and is_device_ptr here
3392 // since we have already make sure that the declaration does not
3393 // have a data-sharing attribute above
3394 if (!Stack->checkMappableExprComponentListsForDecl(
3395 VD, /*CurrentRegionOnly=*/true,
3396 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3399 auto MI = MapExprComponents.rbegin();
3400 auto ME = MapExprComponents.rend();
3401 return MI != ME && MI->getAssociatedDeclaration() == VD;
3403 VarsWithInheritedDSA[VD] = E;
3409 if (isOpenMPTargetExecutionDirective(DKind) &&
3410 !Stack->isLoopControlVariable(VD).first) {
3411 if (!Stack->checkMappableExprComponentListsForDecl(
3412 VD, /*CurrentRegionOnly=*/true,
3413 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3416 // Variable is used if it has been marked as an array, array
3417 // section, array shaping or the variable iself.
3418 return StackComponents.size() == 1 ||
3420 std::next(StackComponents.rbegin()),
3421 StackComponents.rend(),
3422 [](const OMPClauseMappableExprCommon::
3423 MappableComponent &MC) {
3424 return MC.getAssociatedDeclaration() ==
3426 (isa<OMPArraySectionExpr>(
3427 MC.getAssociatedExpression()) ||
3428 isa<OMPArrayShapingExpr>(
3429 MC.getAssociatedExpression()) ||
3430 isa<ArraySubscriptExpr>(
3431 MC.getAssociatedExpression()));
3434 bool IsFirstprivate = false;
3435 // By default lambdas are captured as firstprivates.
3436 if (const auto *RD =
3437 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3438 IsFirstprivate = RD->isLambda();
3440 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3441 if (IsFirstprivate) {
3442 ImplicitFirstprivate.emplace_back(E);
3444 OpenMPDefaultmapClauseModifier M =
3445 Stack->getDefaultmapModifier(ClauseKind);
3446 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3447 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3448 ImplicitMap[Kind].emplace_back(E);
3454 // OpenMP [2.9.3.6, Restrictions, p.2]
3455 // A list item that appears in a reduction clause of the innermost
3456 // enclosing worksharing or parallel construct may not be accessed in an
3458 DVar = Stack->hasInnermostDSA(
3459 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3460 [](OpenMPDirectiveKind K) {
3461 return isOpenMPParallelDirective(K) ||
3462 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3464 /*FromParent=*/true);
3465 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3467 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3468 reportOriginalDsa(SemaRef, Stack, VD, DVar);
3472 // Define implicit data-sharing attributes for task.
3473 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3474 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3475 (Stack->getDefaultDSA() == DSA_firstprivate &&
3476 DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3477 !Stack->isLoopControlVariable(VD).first) {
3478 ImplicitFirstprivate.push_back(E);
3482 // Store implicitly used globals with declare target link for parent
3484 if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3485 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3486 Stack->addToParentTargetRegionLinkGlobals(E);
3491 void VisitMemberExpr(MemberExpr *E) {
3492 if (E->isTypeDependent() || E->isValueDependent() ||
3493 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3495 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3496 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3497 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3500 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3501 // Check if the variable has explicit DSA set and stop analysis if it
3503 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3506 if (isOpenMPTargetExecutionDirective(DKind) &&
3507 !Stack->isLoopControlVariable(FD).first &&
3508 !Stack->checkMappableExprComponentListsForDecl(
3509 FD, /*CurrentRegionOnly=*/true,
3510 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3513 return isa<CXXThisExpr>(
3515 StackComponents.back().getAssociatedExpression())
3519 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3520 // A bit-field cannot appear in a map clause.
3522 if (FD->isBitField())
3525 // Check to see if the member expression is referencing a class that
3526 // has already been explicitly mapped
3527 if (Stack->isClassPreviouslyMapped(TE->getType()))
3530 OpenMPDefaultmapClauseModifier Modifier =
3531 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3532 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3533 Modifier, /*IsAggregateOrDeclareTarget*/ true);
3534 ImplicitMap[Kind].emplace_back(E);
3538 SourceLocation ELoc = E->getExprLoc();
3539 // OpenMP [2.9.3.6, Restrictions, p.2]
3540 // A list item that appears in a reduction clause of the innermost
3541 // enclosing worksharing or parallel construct may not be accessed in
3542 // an explicit task.
3543 DVar = Stack->hasInnermostDSA(
3544 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3545 [](OpenMPDirectiveKind K) {
3546 return isOpenMPParallelDirective(K) ||
3547 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3549 /*FromParent=*/true);
3550 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3552 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3553 reportOriginalDsa(SemaRef, Stack, FD, DVar);
3557 // Define implicit data-sharing attributes for task.
3558 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3559 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3560 !Stack->isLoopControlVariable(FD).first) {
3561 // Check if there is a captured expression for the current field in the
3562 // region. Do not mark it as firstprivate unless there is no captured
3564 // TODO: try to make it firstprivate.
3565 if (DVar.CKind != OMPC_unknown)
3566 ImplicitFirstprivate.push_back(E);
3570 if (isOpenMPTargetExecutionDirective(DKind)) {
3571 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3572 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3573 /*NoDiagnose=*/true))
3575 const auto *VD = cast<ValueDecl>(
3576 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3577 if (!Stack->checkMappableExprComponentListsForDecl(
3578 VD, /*CurrentRegionOnly=*/true,
3580 OMPClauseMappableExprCommon::MappableExprComponentListRef
3583 auto CCI = CurComponents.rbegin();
3584 auto CCE = CurComponents.rend();
3585 for (const auto &SC : llvm::reverse(StackComponents)) {
3586 // Do both expressions have the same kind?
3587 if (CCI->getAssociatedExpression()->getStmtClass() !=
3588 SC.getAssociatedExpression()->getStmtClass())
3589 if (!((isa<OMPArraySectionExpr>(
3590 SC.getAssociatedExpression()) ||
3591 isa<OMPArrayShapingExpr>(
3592 SC.getAssociatedExpression())) &&
3593 isa<ArraySubscriptExpr>(
3594 CCI->getAssociatedExpression())))
3597 const Decl *CCD = CCI->getAssociatedDeclaration();
3598 const Decl *SCD = SC.getAssociatedDeclaration();
3599 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3600 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3603 std::advance(CCI, 1);
3609 Visit(E->getBase());
3611 } else if (!TryCaptureCXXThisMembers) {
3612 Visit(E->getBase());
3615 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3616 for (OMPClause *C : S->clauses()) {
3617 // Skip analysis of arguments of implicitly defined firstprivate clause
3618 // for task|target directives.
3619 // Skip analysis of arguments of implicitly defined map clause for target
3621 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3623 for (Stmt *CC : C->children()) {
3629 // Check implicitly captured variables.
3630 VisitSubCaptures(S);
3632 void VisitStmt(Stmt *S) {
3633 for (Stmt *C : S->children()) {
3635 // Check implicitly captured variables in the task-based directives to
3636 // check if they must be firstprivatized.
3642 void visitSubCaptures(CapturedStmt *S) {
3643 for (const CapturedStmt::Capture &Cap : S->captures()) {
3644 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3646 VarDecl *VD = Cap.getCapturedVar();
3647 // Do not try to map the variable if it or its sub-component was mapped
3649 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3650 Stack->checkMappableExprComponentListsForDecl(
3651 VD, /*CurrentRegionOnly=*/true,
3652 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3653 OpenMPClauseKind) { return true; }))
3655 DeclRefExpr *DRE = buildDeclRefExpr(
3656 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3657 Cap.getLocation(), /*RefersToCapture=*/true);
3661 bool isErrorFound() const { return ErrorFound; }
3662 ArrayRef<Expr *> getImplicitFirstprivate() const {
3663 return ImplicitFirstprivate;
3665 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3666 return ImplicitMap[Kind];
3668 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3669 return VarsWithInheritedDSA;
3672 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3673 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3674 // Process declare target link variables for the target directives.
3675 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3676 for (DeclRefExpr *E : Stack->getLinkGlobals())
3683 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3686 case OMPD_parallel_for:
3687 case OMPD_parallel_for_simd:
3688 case OMPD_parallel_sections:
3689 case OMPD_parallel_master:
3691 case OMPD_teams_distribute:
3692 case OMPD_teams_distribute_simd: {
3693 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3694 QualType KmpInt32PtrTy =
3695 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3696 Sema::CapturedParamNameType Params[] = {
3697 std::make_pair(".global_tid.", KmpInt32PtrTy),
3698 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3699 std::make_pair(StringRef(), QualType()) // __context with shared vars
3701 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3705 case OMPD_target_teams:
3706 case OMPD_target_parallel:
3707 case OMPD_target_parallel_for:
3708 case OMPD_target_parallel_for_simd:
3709 case OMPD_target_teams_distribute:
3710 case OMPD_target_teams_distribute_simd: {
3711 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3712 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3713 QualType KmpInt32PtrTy =
3714 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3715 QualType Args[] = {VoidPtrTy};
3716 FunctionProtoType::ExtProtoInfo EPI;
3717 EPI.Variadic = true;
3718 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3719 Sema::CapturedParamNameType Params[] = {
3720 std::make_pair(".global_tid.", KmpInt32Ty),
3721 std::make_pair(".part_id.", KmpInt32PtrTy),
3722 std::make_pair(".privates.", VoidPtrTy),
3725 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3726 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3727 std::make_pair(StringRef(), QualType()) // __context with shared vars
3729 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3730 Params, /*OpenMPCaptureLevel=*/0);
3731 // Mark this captured region as inlined, because we don't use outlined
3732 // function directly.
3733 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3734 AlwaysInlineAttr::CreateImplicit(
3735 Context, {}, AttributeCommonInfo::AS_Keyword,
3736 AlwaysInlineAttr::Keyword_forceinline));
3737 Sema::CapturedParamNameType ParamsTarget[] = {
3738 std::make_pair(StringRef(), QualType()) // __context with shared vars
3740 // Start a captured region for 'target' with no implicit parameters.
3741 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3742 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3743 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3744 std::make_pair(".global_tid.", KmpInt32PtrTy),
3745 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3746 std::make_pair(StringRef(), QualType()) // __context with shared vars
3748 // Start a captured region for 'teams' or 'parallel'. Both regions have
3749 // the same implicit parameters.
3750 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3751 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3755 case OMPD_target_simd: {
3756 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3757 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3758 QualType KmpInt32PtrTy =
3759 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3760 QualType Args[] = {VoidPtrTy};
3761 FunctionProtoType::ExtProtoInfo EPI;
3762 EPI.Variadic = true;
3763 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3764 Sema::CapturedParamNameType Params[] = {
3765 std::make_pair(".global_tid.", KmpInt32Ty),
3766 std::make_pair(".part_id.", KmpInt32PtrTy),
3767 std::make_pair(".privates.", VoidPtrTy),
3770 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3771 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3772 std::make_pair(StringRef(), QualType()) // __context with shared vars
3774 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3775 Params, /*OpenMPCaptureLevel=*/0);
3776 // Mark this captured region as inlined, because we don't use outlined
3777 // function directly.
3778 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3779 AlwaysInlineAttr::CreateImplicit(
3780 Context, {}, AttributeCommonInfo::AS_Keyword,
3781 AlwaysInlineAttr::Keyword_forceinline));
3782 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3783 std::make_pair(StringRef(), QualType()),
3784 /*OpenMPCaptureLevel=*/1);
3795 case OMPD_taskgroup:
3796 case OMPD_distribute:
3797 case OMPD_distribute_simd:
3800 case OMPD_target_data: {
3801 Sema::CapturedParamNameType Params[] = {
3802 std::make_pair(StringRef(), QualType()) // __context with shared vars
3804 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3809 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3810 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3811 QualType KmpInt32PtrTy =
3812 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3813 QualType Args[] = {VoidPtrTy};
3814 FunctionProtoType::ExtProtoInfo EPI;
3815 EPI.Variadic = true;
3816 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3817 Sema::CapturedParamNameType Params[] = {
3818 std::make_pair(".global_tid.", KmpInt32Ty),
3819 std::make_pair(".part_id.", KmpInt32PtrTy),
3820 std::make_pair(".privates.", VoidPtrTy),
3823 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3824 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3825 std::make_pair(StringRef(), QualType()) // __context with shared vars
3827 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3829 // Mark this captured region as inlined, because we don't use outlined
3830 // function directly.
3831 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3832 AlwaysInlineAttr::CreateImplicit(
3833 Context, {}, AttributeCommonInfo::AS_Keyword,
3834 AlwaysInlineAttr::Keyword_forceinline));
3838 case OMPD_taskloop_simd:
3839 case OMPD_master_taskloop:
3840 case OMPD_master_taskloop_simd: {
3841 QualType KmpInt32Ty =
3842 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3844 QualType KmpUInt64Ty =
3845 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3847 QualType KmpInt64Ty =
3848 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3850 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3851 QualType KmpInt32PtrTy =
3852 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3853 QualType Args[] = {VoidPtrTy};
3854 FunctionProtoType::ExtProtoInfo EPI;
3855 EPI.Variadic = true;
3856 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3857 Sema::CapturedParamNameType Params[] = {
3858 std::make_pair(".global_tid.", KmpInt32Ty),
3859 std::make_pair(".part_id.", KmpInt32PtrTy),
3860 std::make_pair(".privates.", VoidPtrTy),
3863 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3864 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3865 std::make_pair(".lb.", KmpUInt64Ty),
3866 std::make_pair(".ub.", KmpUInt64Ty),
3867 std::make_pair(".st.", KmpInt64Ty),
3868 std::make_pair(".liter.", KmpInt32Ty),
3869 std::make_pair(".reductions.", VoidPtrTy),
3870 std::make_pair(StringRef(), QualType()) // __context with shared vars
3872 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3874 // Mark this captured region as inlined, because we don't use outlined
3875 // function directly.
3876 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3877 AlwaysInlineAttr::CreateImplicit(
3878 Context, {}, AttributeCommonInfo::AS_Keyword,
3879 AlwaysInlineAttr::Keyword_forceinline));
3882 case OMPD_parallel_master_taskloop:
3883 case OMPD_parallel_master_taskloop_simd: {
3884 QualType KmpInt32Ty =
3885 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3887 QualType KmpUInt64Ty =
3888 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3890 QualType KmpInt64Ty =
3891 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3893 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3894 QualType KmpInt32PtrTy =
3895 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3896 Sema::CapturedParamNameType ParamsParallel[] = {
3897 std::make_pair(".global_tid.", KmpInt32PtrTy),
3898 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3899 std::make_pair(StringRef(), QualType()) // __context with shared vars
3901 // Start a captured region for 'parallel'.
3902 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3903 ParamsParallel, /*OpenMPCaptureLevel=*/0);
3904 QualType Args[] = {VoidPtrTy};
3905 FunctionProtoType::ExtProtoInfo EPI;
3906 EPI.Variadic = true;
3907 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3908 Sema::CapturedParamNameType Params[] = {
3909 std::make_pair(".global_tid.", KmpInt32Ty),
3910 std::make_pair(".part_id.", KmpInt32PtrTy),
3911 std::make_pair(".privates.", VoidPtrTy),
3914 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3915 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3916 std::make_pair(".lb.", KmpUInt64Ty),
3917 std::make_pair(".ub.", KmpUInt64Ty),
3918 std::make_pair(".st.", KmpInt64Ty),
3919 std::make_pair(".liter.", KmpInt32Ty),
3920 std::make_pair(".reductions.", VoidPtrTy),
3921 std::make_pair(StringRef(), QualType()) // __context with shared vars
3923 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3924 Params, /*OpenMPCaptureLevel=*/1);
3925 // Mark this captured region as inlined, because we don't use outlined
3926 // function directly.
3927 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3928 AlwaysInlineAttr::CreateImplicit(
3929 Context, {}, AttributeCommonInfo::AS_Keyword,
3930 AlwaysInlineAttr::Keyword_forceinline));
3933 case OMPD_distribute_parallel_for_simd:
3934 case OMPD_distribute_parallel_for: {
3935 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3936 QualType KmpInt32PtrTy =
3937 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3938 Sema::CapturedParamNameType Params[] = {
3939 std::make_pair(".global_tid.", KmpInt32PtrTy),
3940 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3941 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3942 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3943 std::make_pair(StringRef(), QualType()) // __context with shared vars
3945 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3949 case OMPD_target_teams_distribute_parallel_for:
3950 case OMPD_target_teams_distribute_parallel_for_simd: {
3951 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3952 QualType KmpInt32PtrTy =
3953 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3954 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3956 QualType Args[] = {VoidPtrTy};
3957 FunctionProtoType::ExtProtoInfo EPI;
3958 EPI.Variadic = true;
3959 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3960 Sema::CapturedParamNameType Params[] = {
3961 std::make_pair(".global_tid.", KmpInt32Ty),
3962 std::make_pair(".part_id.", KmpInt32PtrTy),
3963 std::make_pair(".privates.", VoidPtrTy),
3966 Context.getPointerType(CopyFnType).withConst().withRestrict()),
3967 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3968 std::make_pair(StringRef(), QualType()) // __context with shared vars
3970 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3971 Params, /*OpenMPCaptureLevel=*/0);
3972 // Mark this captured region as inlined, because we don't use outlined
3973 // function directly.
3974 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3975 AlwaysInlineAttr::CreateImplicit(
3976 Context, {}, AttributeCommonInfo::AS_Keyword,
3977 AlwaysInlineAttr::Keyword_forceinline));
3978 Sema::CapturedParamNameType ParamsTarget[] = {
3979 std::make_pair(StringRef(), QualType()) // __context with shared vars
3981 // Start a captured region for 'target' with no implicit parameters.
3982 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3983 ParamsTarget, /*OpenMPCaptureLevel=*/1);
3985 Sema::CapturedParamNameType ParamsTeams[] = {
3986 std::make_pair(".global_tid.", KmpInt32PtrTy),
3987 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3988 std::make_pair(StringRef(), QualType()) // __context with shared vars
3990 // Start a captured region for 'target' with no implicit parameters.
3991 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3992 ParamsTeams, /*OpenMPCaptureLevel=*/2);
3994 Sema::CapturedParamNameType ParamsParallel[] = {
3995 std::make_pair(".global_tid.", KmpInt32PtrTy),
3996 std::make_pair(".bound_tid.", KmpInt32PtrTy),
3997 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3998 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3999 std::make_pair(StringRef(), QualType()) // __context with shared vars
4001 // Start a captured region for 'teams' or 'parallel'. Both regions have
4002 // the same implicit parameters.
4003 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4004 ParamsParallel, /*OpenMPCaptureLevel=*/3);
4008 case OMPD_teams_distribute_parallel_for:
4009 case OMPD_teams_distribute_parallel_for_simd: {
4010 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4011 QualType KmpInt32PtrTy =
4012 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4014 Sema::CapturedParamNameType ParamsTeams[] = {
4015 std::make_pair(".global_tid.", KmpInt32PtrTy),
4016 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4017 std::make_pair(StringRef(), QualType()) // __context with shared vars
4019 // Start a captured region for 'target' with no implicit parameters.
4020 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4021 ParamsTeams, /*OpenMPCaptureLevel=*/0);
4023 Sema::CapturedParamNameType ParamsParallel[] = {
4024 std::make_pair(".global_tid.", KmpInt32PtrTy),
4025 std::make_pair(".bound_tid.", KmpInt32PtrTy),
4026 std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4027 std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4028 std::make_pair(StringRef(), QualType()) // __context with shared vars
4030 // Start a captured region for 'teams' or 'parallel'. Both regions have
4031 // the same implicit parameters.
4032 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4033 ParamsParallel, /*OpenMPCaptureLevel=*/1);
4036 case OMPD_target_update:
4037 case OMPD_target_enter_data:
4038 case OMPD_target_exit_data: {
4039 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4040 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4041 QualType KmpInt32PtrTy =
4042 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4043 QualType Args[] = {VoidPtrTy};
4044 FunctionProtoType::ExtProtoInfo EPI;
4045 EPI.Variadic = true;
4046 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4047 Sema::CapturedParamNameType Params[] = {
4048 std::make_pair(".global_tid.", KmpInt32Ty),
4049 std::make_pair(".part_id.", KmpInt32PtrTy),
4050 std::make_pair(".privates.", VoidPtrTy),
4053 Context.getPointerType(CopyFnType).withConst().withRestrict()),
4054 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4055 std::make_pair(StringRef(), QualType()) // __context with shared vars
4057 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4059 // Mark this captured region as inlined, because we don't use outlined
4060 // function directly.
4061 getCurCapturedRegion()->TheCapturedDecl->addAttr(
4062 AlwaysInlineAttr::CreateImplicit(
4063 Context, {}, AttributeCommonInfo::AS_Keyword,
4064 AlwaysInlineAttr::Keyword_forceinline));
4067 case OMPD_threadprivate:
4069 case OMPD_taskyield:
4072 case OMPD_cancellation_point:
4077 case OMPD_declare_reduction:
4078 case OMPD_declare_mapper:
4079 case OMPD_declare_simd:
4080 case OMPD_declare_target:
4081 case OMPD_end_declare_target:
4083 case OMPD_declare_variant:
4084 case OMPD_begin_declare_variant:
4085 case OMPD_end_declare_variant:
4086 llvm_unreachable("OpenMP Directive is not allowed");
4089 llvm_unreachable("Unknown OpenMP directive");
4093 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4094 return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4097 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4098 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4099 getOpenMPCaptureRegions(CaptureRegions, DKind);
4100 return CaptureRegions.size();
4103 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4104 Expr *CaptureExpr, bool WithInit,
4105 bool AsExpression) {
4106 assert(CaptureExpr);
4107 ASTContext &C = S.getASTContext();
4108 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4109 QualType Ty = Init->getType();
4110 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4111 if (S.getLangOpts().CPlusPlus) {
4112 Ty = C.getLValueReferenceType(Ty);
4114 Ty = C.getPointerType(Ty);
4116 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4117 if (!Res.isUsable())
4123 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4124 CaptureExpr->getBeginLoc());
4126 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4127 S.CurContext->addHiddenDecl(CED);
4128 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4132 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4134 OMPCapturedExprDecl *CD;
4135 if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4136 CD = cast<OMPCapturedExprDecl>(VD);
4138 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4139 /*AsExpression=*/false);
4140 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4141 CaptureExpr->getExprLoc());
4144 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4145 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4147 OMPCapturedExprDecl *CD = buildCaptureDecl(
4148 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4149 /*WithInit=*/true, /*AsExpression=*/true);
4150 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4151 CaptureExpr->getExprLoc());
4153 ExprResult Res = Ref;
4154 if (!S.getLangOpts().CPlusPlus &&
4155 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4156 Ref->getType()->isPointerType()) {
4157 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4158 if (!Res.isUsable())
4161 return S.DefaultLvalueConversion(Res.get());
4165 // OpenMP directives parsed in this section are represented as a
4166 // CapturedStatement with an associated statement. If a syntax error
4167 // is detected during the parsing of the associated statement, the
4168 // compiler must abort processing and close the CapturedStatement.
4170 // Combined directives such as 'target parallel' have more than one
4171 // nested CapturedStatements. This RAII ensures that we unwind out
4172 // of all the nested CapturedStatements when an error is found.
4173 class CaptureRegionUnwinderRAII {
4177 OpenMPDirectiveKind DKind = OMPD_unknown;
4180 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4181 OpenMPDirectiveKind DKind)
4182 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4183 ~CaptureRegionUnwinderRAII() {
4185 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4186 while (--ThisCaptureLevel >= 0)
4187 S.ActOnCapturedRegionError();
4193 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4194 // Capture variables captured by reference in lambdas for target-based
4196 if (!CurContext->isDependentContext() &&
4197 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4198 isOpenMPTargetDataManagementDirective(
4199 DSAStack->getCurrentDirective()))) {
4200 QualType Type = V->getType();
4201 if (const auto *RD = Type.getCanonicalType()
4202 .getNonReferenceType()
4203 ->getAsCXXRecordDecl()) {
4204 bool SavedForceCaptureByReferenceInTargetExecutable =
4205 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4206 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4208 if (RD->isLambda()) {
4209 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4210 FieldDecl *ThisCapture;
4211 RD->getCaptureFields(Captures, ThisCapture);
4212 for (const LambdaCapture &LC : RD->captures()) {
4213 if (LC.getCaptureKind() == LCK_ByRef) {
4214 VarDecl *VD = LC.getCapturedVar();
4215 DeclContext *VDC = VD->getDeclContext();
4216 if (!VDC->Encloses(CurContext))
4218 MarkVariableReferenced(LC.getLocation(), VD);
4219 } else if (LC.getCaptureKind() == LCK_This) {
4220 QualType ThisTy = getCurrentThisType();
4221 if (!ThisTy.isNull() &&
4222 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4223 CheckCXXThisCapture(LC.getLocation());
4227 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4228 SavedForceCaptureByReferenceInTargetExecutable);
4233 static bool checkOrderedOrderSpecified(Sema &S,
4234 const ArrayRef<OMPClause *> Clauses) {
4235 const OMPOrderedClause *Ordered = nullptr;
4236 const OMPOrderClause *Order = nullptr;
4238 for (const OMPClause *Clause : Clauses) {
4239 if (Clause->getClauseKind() == OMPC_ordered)
4240 Ordered = cast<OMPOrderedClause>(Clause);
4241 else if (Clause->getClauseKind() == OMPC_order) {
4242 Order = cast<OMPOrderClause>(Clause);
4243 if (Order->getKind() != OMPC_ORDER_concurrent)
4246 if (Ordered && Order)
4250 if (Ordered && Order) {
4251 S.Diag(Order->getKindKwLoc(),
4252 diag::err_omp_simple_clause_incompatible_with_ordered)
4253 << getOpenMPClauseName(OMPC_order)
4254 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4255 << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4256 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4257 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4263 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4264 ArrayRef<OMPClause *> Clauses) {
4265 bool ErrorFound = false;
4266 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4267 *this, ErrorFound, DSAStack->getCurrentDirective());
4268 if (!S.isUsable()) {
4273 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4274 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4275 OMPOrderedClause *OC = nullptr;
4276 OMPScheduleClause *SC = nullptr;
4277 SmallVector<const OMPLinearClause *, 4> LCs;
4278 SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4279 // This is required for proper codegen.
4280 for (OMPClause *Clause : Clauses) {
4281 if (!LangOpts.OpenMPSimd &&
4282 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4283 Clause->getClauseKind() == OMPC_in_reduction) {
4284 // Capture taskgroup task_reduction descriptors inside the tasking regions
4285 // with the corresponding in_reduction items.
4286 auto *IRC = cast<OMPInReductionClause>(Clause);
4287 for (Expr *E : IRC->taskgroup_descriptors())
4289 MarkDeclarationsReferencedInExpr(E);
4291 if (isOpenMPPrivate(Clause->getClauseKind()) ||
4292 Clause->getClauseKind() == OMPC_copyprivate ||
4293 (getLangOpts().OpenMPUseTLS &&
4294 getASTContext().getTargetInfo().isTLSSupported() &&
4295 Clause->getClauseKind() == OMPC_copyin)) {
4296 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4297 // Mark all variables in private list clauses as used in inner region.
4298 for (Stmt *VarRef : Clause->children()) {
4299 if (auto *E = cast_or_null<Expr>(VarRef)) {
4300 MarkDeclarationsReferencedInExpr(E);
4303 DSAStack->setForceVarCapturing(/*V=*/false);
4304 } else if (CaptureRegions.size() > 1 ||
4305 CaptureRegions.back() != OMPD_unknown) {
4306 if (auto *C = OMPClauseWithPreInit::get(Clause))
4308 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4309 if (Expr *E = C->getPostUpdateExpr())
4310 MarkDeclarationsReferencedInExpr(E);
4313 if (Clause->getClauseKind() == OMPC_schedule)
4314 SC = cast<OMPScheduleClause>(Clause);
4315 else if (Clause->getClauseKind() == OMPC_ordered)
4316 OC = cast<OMPOrderedClause>(Clause);
4317 else if (Clause->getClauseKind() == OMPC_linear)
4318 LCs.push_back(cast<OMPLinearClause>(Clause));
4320 // Capture allocator expressions if used.
4321 for (Expr *E : DSAStack->getInnerAllocators())
4322 MarkDeclarationsReferencedInExpr(E);
4323 // OpenMP, 2.7.1 Loop Construct, Restrictions
4324 // The nonmonotonic modifier cannot be specified if an ordered clause is
4327 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4328 SC->getSecondScheduleModifier() ==
4329 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4331 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4332 ? SC->getFirstScheduleModifierLoc()
4333 : SC->getSecondScheduleModifierLoc(),
4334 diag::err_omp_simple_clause_incompatible_with_ordered)
4335 << getOpenMPClauseName(OMPC_schedule)
4336 << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4337 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4338 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4341 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4342 // If an order(concurrent) clause is present, an ordered clause may not appear
4343 // on the same directive.
4344 if (checkOrderedOrderSpecified(*this, Clauses))
4346 if (!LCs.empty() && OC && OC->getNumForLoops()) {
4347 for (const OMPLinearClause *C : LCs) {
4348 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4349 << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4353 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4354 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4355 OC->getNumForLoops()) {
4356 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4357 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4364 unsigned CompletedRegions = 0;
4365 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4366 // Mark all variables in private list clauses as used in inner region.
4367 // Required for proper codegen of combined directives.
4368 // TODO: add processing for other clauses.
4369 if (ThisCaptureRegion != OMPD_unknown) {
4370 for (const clang::OMPClauseWithPreInit *C : PICs) {
4371 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4372 // Find the particular capture region for the clause if the
4373 // directive is a combined one with multiple capture regions.
4374 // If the directive is not a combined one, the capture region
4375 // associated with the clause is OMPD_unknown and is generated
4377 if (CaptureRegion == ThisCaptureRegion ||
4378 CaptureRegion == OMPD_unknown) {
4379 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4380 for (Decl *D : DS->decls())
4381 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4386 if (ThisCaptureRegion == OMPD_target) {
4387 // Capture allocator traits in the target region. They are used implicitly
4388 // and, thus, are not captured by default.
4389 for (OMPClause *C : Clauses) {
4390 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4391 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4393 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4394 if (Expr *E = D.AllocatorTraits)
4395 MarkDeclarationsReferencedInExpr(E);
4401 if (++CompletedRegions == CaptureRegions.size())
4402 DSAStack->setBodyComplete();
4403 SR = ActOnCapturedRegionEnd(SR.get());
4408 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4409 OpenMPDirectiveKind CancelRegion,
4410 SourceLocation StartLoc) {
4411 // CancelRegion is only needed for cancel and cancellation_point.
4412 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4415 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4416 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4419 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4420 << getOpenMPDirectiveName(CancelRegion);
4424 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4425 OpenMPDirectiveKind CurrentRegion,
4426 const DeclarationNameInfo &CurrentName,
4427 OpenMPDirectiveKind CancelRegion,
4428 SourceLocation StartLoc) {
4429 if (Stack->getCurScope()) {
4430 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4431 OpenMPDirectiveKind OffendingRegion = ParentRegion;
4432 bool NestingProhibited = false;
4433 bool CloseNesting = true;
4434 bool OrphanSeen = false;
4437 ShouldBeInParallelRegion,
4438 ShouldBeInOrderedRegion,
4439 ShouldBeInTargetRegion,
4440 ShouldBeInTeamsRegion,
4441 ShouldBeInLoopSimdRegion,
4442 } Recommend = NoRecommend;
4443 if (isOpenMPSimdDirective(ParentRegion) &&
4444 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4445 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4446 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4447 CurrentRegion != OMPD_scan))) {
4448 // OpenMP [2.16, Nesting of Regions]
4449 // OpenMP constructs may not be nested inside a simd region.
4450 // OpenMP [2.8.1,simd Construct, Restrictions]
4451 // An ordered construct with the simd clause is the only OpenMP
4452 // construct that can appear in the simd region.
4453 // Allowing a SIMD construct nested in another SIMD construct is an
4454 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4456 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4457 // The only OpenMP constructs that can be encountered during execution of
4458 // a simd region are the atomic construct, the loop construct, the simd
4459 // construct and the ordered construct with the simd clause.
4460 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4461 ? diag::err_omp_prohibited_region_simd
4462 : diag::warn_omp_nesting_simd)
4463 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4464 return CurrentRegion != OMPD_simd;
4466 if (ParentRegion == OMPD_atomic) {
4467 // OpenMP [2.16, Nesting of Regions]
4468 // OpenMP constructs may not be nested inside an atomic region.
4469 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4472 if (CurrentRegion == OMPD_section) {
4473 // OpenMP [2.7.2, sections Construct, Restrictions]
4474 // Orphaned section directives are prohibited. That is, the section
4475 // directives must appear within the sections construct and must not be
4476 // encountered elsewhere in the sections region.
4477 if (ParentRegion != OMPD_sections &&
4478 ParentRegion != OMPD_parallel_sections) {
4479 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4480 << (ParentRegion != OMPD_unknown)
4481 << getOpenMPDirectiveName(ParentRegion);
4486 // Allow some constructs (except teams and cancellation constructs) to be
4487 // orphaned (they could be used in functions, called from OpenMP regions
4488 // with the required preconditions).
4489 if (ParentRegion == OMPD_unknown &&
4490 !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4491 CurrentRegion != OMPD_cancellation_point &&
4492 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4494 if (CurrentRegion == OMPD_cancellation_point ||
4495 CurrentRegion == OMPD_cancel) {
4496 // OpenMP [2.16, Nesting of Regions]
4497 // A cancellation point construct for which construct-type-clause is
4498 // taskgroup must be nested inside a task construct. A cancellation
4499 // point construct for which construct-type-clause is not taskgroup must
4500 // be closely nested inside an OpenMP construct that matches the type
4501 // specified in construct-type-clause.
4502 // A cancel construct for which construct-type-clause is taskgroup must be
4503 // nested inside a task construct. A cancel construct for which
4504 // construct-type-clause is not taskgroup must be closely nested inside an
4505 // OpenMP construct that matches the type specified in
4506 // construct-type-clause.
4508 !((CancelRegion == OMPD_parallel &&
4509 (ParentRegion == OMPD_parallel ||
4510 ParentRegion == OMPD_target_parallel)) ||
4511 (CancelRegion == OMPD_for &&
4512 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4513 ParentRegion == OMPD_target_parallel_for ||
4514 ParentRegion == OMPD_distribute_parallel_for ||
4515 ParentRegion == OMPD_teams_distribute_parallel_for ||
4516 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4517 (CancelRegion == OMPD_taskgroup &&
4518 (ParentRegion == OMPD_task ||
4519 (SemaRef.getLangOpts().OpenMP >= 50 &&
4520 (ParentRegion == OMPD_taskloop ||
4521 ParentRegion == OMPD_master_taskloop ||
4522 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4523 (CancelRegion == OMPD_sections &&
4524 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4525 ParentRegion == OMPD_parallel_sections)));
4526 OrphanSeen = ParentRegion == OMPD_unknown;
4527 } else if (CurrentRegion == OMPD_master) {
4528 // OpenMP [2.16, Nesting of Regions]
4529 // A master region may not be closely nested inside a worksharing,
4530 // atomic, or explicit task region.
4531 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4532 isOpenMPTaskingDirective(ParentRegion);
4533 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4534 // OpenMP [2.16, Nesting of Regions]
4535 // A critical region may not be nested (closely or otherwise) inside a
4536 // critical region with the same name. Note that this restriction is not
4537 // sufficient to prevent deadlock.
4538 SourceLocation PreviousCriticalLoc;
4539 bool DeadLock = Stack->hasDirective(
4540 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4541 const DeclarationNameInfo &DNI,
4542 SourceLocation Loc) {
4543 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4544 PreviousCriticalLoc = Loc;
4549 false /* skip top directive */);
4551 SemaRef.Diag(StartLoc,
4552 diag::err_omp_prohibited_region_critical_same_name)
4553 << CurrentName.getName();
4554 if (PreviousCriticalLoc.isValid())
4555 SemaRef.Diag(PreviousCriticalLoc,
4556 diag::note_omp_previous_critical_region);
4559 } else if (CurrentRegion == OMPD_barrier) {
4560 // OpenMP [2.16, Nesting of Regions]
4561 // A barrier region may not be closely nested inside a worksharing,
4562 // explicit task, critical, ordered, atomic, or master region.
4563 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4564 isOpenMPTaskingDirective(ParentRegion) ||
4565 ParentRegion == OMPD_master ||
4566 ParentRegion == OMPD_parallel_master ||
4567 ParentRegion == OMPD_critical ||
4568 ParentRegion == OMPD_ordered;
4569 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4570 !isOpenMPParallelDirective(CurrentRegion) &&
4571 !isOpenMPTeamsDirective(CurrentRegion)) {
4572 // OpenMP [2.16, Nesting of Regions]
4573 // A worksharing region may not be closely nested inside a worksharing,
4574 // explicit task, critical, ordered, atomic, or master region.
4575 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4576 isOpenMPTaskingDirective(ParentRegion) ||
4577 ParentRegion == OMPD_master ||
4578 ParentRegion == OMPD_parallel_master ||
4579 ParentRegion == OMPD_critical ||
4580 ParentRegion == OMPD_ordered;
4581 Recommend = ShouldBeInParallelRegion;
4582 } else if (CurrentRegion == OMPD_ordered) {
4583 // OpenMP [2.16, Nesting of Regions]
4584 // An ordered region may not be closely nested inside a critical,
4585 // atomic, or explicit task region.
4586 // An ordered region must be closely nested inside a loop region (or
4587 // parallel loop region) with an ordered clause.
4588 // OpenMP [2.8.1,simd Construct, Restrictions]
4589 // An ordered construct with the simd clause is the only OpenMP construct
4590 // that can appear in the simd region.
4591 NestingProhibited = ParentRegion == OMPD_critical ||
4592 isOpenMPTaskingDirective(ParentRegion) ||
4593 !(isOpenMPSimdDirective(ParentRegion) ||
4594 Stack->isParentOrderedRegion());
4595 Recommend = ShouldBeInOrderedRegion;
4596 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4597 // OpenMP [2.16, Nesting of Regions]
4598 // If specified, a teams construct must be contained within a target
4601 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4602 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4603 ParentRegion != OMPD_target);
4604 OrphanSeen = ParentRegion == OMPD_unknown;
4605 Recommend = ShouldBeInTargetRegion;
4606 } else if (CurrentRegion == OMPD_scan) {
4607 // OpenMP [2.16, Nesting of Regions]
4608 // If specified, a teams construct must be contained within a target
4611 SemaRef.LangOpts.OpenMP < 50 ||
4612 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4613 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4614 ParentRegion != OMPD_parallel_for_simd);
4615 OrphanSeen = ParentRegion == OMPD_unknown;
4616 Recommend = ShouldBeInLoopSimdRegion;
4618 if (!NestingProhibited &&
4619 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4620 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4621 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4622 // OpenMP [2.16, Nesting of Regions]
4623 // distribute, parallel, parallel sections, parallel workshare, and the
4624 // parallel loop and parallel loop SIMD constructs are the only OpenMP
4625 // constructs that can be closely nested in the teams region.
4626 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4627 !isOpenMPDistributeDirective(CurrentRegion);
4628 Recommend = ShouldBeInParallelRegion;
4630 if (!NestingProhibited &&
4631 isOpenMPNestingDistributeDirective(CurrentRegion)) {
4632 // OpenMP 4.5 [2.17 Nesting of Regions]
4633 // The region associated with the distribute construct must be strictly
4634 // nested inside a teams region
4636 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4637 Recommend = ShouldBeInTeamsRegion;
4639 if (!NestingProhibited &&
4640 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4641 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4642 // OpenMP 4.5 [2.17 Nesting of Regions]
4643 // If a target, target update, target data, target enter data, or
4644 // target exit data construct is encountered during execution of a
4645 // target region, the behavior is unspecified.
4646 NestingProhibited = Stack->hasDirective(
4647 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4649 if (isOpenMPTargetExecutionDirective(K)) {
4650 OffendingRegion = K;
4655 false /* don't skip top directive */);
4656 CloseNesting = false;
4658 if (NestingProhibited) {
4660 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4661 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4663 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4664 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4665 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4673 struct Kind2Unsigned {
4674 using argument_type = OpenMPDirectiveKind;
4675 unsigned operator()(argument_type DK) { return unsigned(DK); }
4677 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4678 ArrayRef<OMPClause *> Clauses,
4679 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4680 bool ErrorFound = false;
4681 unsigned NamedModifiersNumber = 0;
4682 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4683 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4684 SmallVector<SourceLocation, 4> NameModifierLoc;
4685 for (const OMPClause *C : Clauses) {
4686 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4687 // At most one if clause without a directive-name-modifier can appear on
4689 OpenMPDirectiveKind CurNM = IC->getNameModifier();
4690 if (FoundNameModifiers[CurNM]) {
4691 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4692 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4693 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4695 } else if (CurNM != OMPD_unknown) {
4696 NameModifierLoc.push_back(IC->getNameModifierLoc());
4697 ++NamedModifiersNumber;
4699 FoundNameModifiers[CurNM] = IC;
4700 if (CurNM == OMPD_unknown)
4702 // Check if the specified name modifier is allowed for the current
4704 // At most one if clause with the particular directive-name-modifier can
4705 // appear on the directive.
4706 bool MatchFound = false;
4707 for (auto NM : AllowedNameModifiers) {
4714 S.Diag(IC->getNameModifierLoc(),
4715 diag::err_omp_wrong_if_directive_name_modifier)
4716 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4721 // If any if clause on the directive includes a directive-name-modifier then
4722 // all if clauses on the directive must include a directive-name-modifier.
4723 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4724 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4725 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4726 diag::err_omp_no_more_if_clause);
4729 std::string Sep(", ");
4730 unsigned AllowedCnt = 0;
4731 unsigned TotalAllowedNum =
4732 AllowedNameModifiers.size() - NamedModifiersNumber;
4733 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4735 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4736 if (!FoundNameModifiers[NM]) {
4738 Values += getOpenMPDirectiveName(NM);
4740 if (AllowedCnt + 2 == TotalAllowedNum)
4742 else if (AllowedCnt + 1 != TotalAllowedNum)
4747 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4748 diag::err_omp_unnamed_if_clause)
4749 << (TotalAllowedNum > 1) << Values;
4751 for (SourceLocation Loc : NameModifierLoc) {
4752 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4759 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4760 SourceLocation &ELoc,
4761 SourceRange &ERange,
4762 bool AllowArraySection) {
4763 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4764 RefExpr->containsUnexpandedParameterPack())
4765 return std::make_pair(nullptr, true);
4767 // OpenMP [3.1, C/C++]
4768 // A list item is a variable name.
4769 // OpenMP [2.9.3.3, Restrictions, p.1]
4770 // A variable that is part of another variable (as an array or
4771 // structure element) cannot appear in a private clause.
4772 RefExpr = RefExpr->IgnoreParens();
4777 } IsArrayExpr = NoArrayExpr;
4778 if (AllowArraySection) {
4779 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4780 Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4781 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4782 Base = TempASE->getBase()->IgnoreParenImpCasts();
4784 IsArrayExpr = ArraySubscript;
4785 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4786 Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4787 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4788 Base = TempOASE->getBase()->IgnoreParenImpCasts();
4789 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4790 Base = TempASE->getBase()->IgnoreParenImpCasts();
4792 IsArrayExpr = OMPArraySection;
4795 ELoc = RefExpr->getExprLoc();
4796 ERange = RefExpr->getSourceRange();
4797 RefExpr = RefExpr->IgnoreParenImpCasts();
4798 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4799 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4800 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4801 (S.getCurrentThisType().isNull() || !ME ||
4802 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4803 !isa<FieldDecl>(ME->getMemberDecl()))) {
4804 if (IsArrayExpr != NoArrayExpr) {
4805 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4810 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4811 : diag::err_omp_expected_var_name_member_expr)
4812 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4814 return std::make_pair(nullptr, false);
4816 return std::make_pair(
4817 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4821 /// Checks if the allocator is used in uses_allocators clause to be allowed in
4823 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
4824 DSAStackTy *S = nullptr;
4827 bool VisitDeclRefExpr(const DeclRefExpr *E) {
4828 return S->isUsesAllocatorsDecl(E->getDecl())
4830 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
4831 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
4833 bool VisitStmt(const Stmt *S) {
4834 for (const Stmt *Child : S->children()) {
4835 if (Child && Visit(Child))
4840 explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
4844 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4845 ArrayRef<OMPClause *> Clauses) {
4846 assert(!S.CurContext->isDependentContext() &&
4847 "Expected non-dependent context.");
4848 auto AllocateRange =
4849 llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4850 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4852 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4853 return isOpenMPPrivate(C->getClauseKind());
4855 for (OMPClause *Cl : PrivateRange) {
4856 MutableArrayRef<Expr *>::iterator I, It, Et;
4857 if (Cl->getClauseKind() == OMPC_private) {
4858 auto *PC = cast<OMPPrivateClause>(Cl);
4859 I = PC->private_copies().begin();
4860 It = PC->varlist_begin();
4861 Et = PC->varlist_end();
4862 } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4863 auto *PC = cast<OMPFirstprivateClause>(Cl);
4864 I = PC->private_copies().begin();
4865 It = PC->varlist_begin();
4866 Et = PC->varlist_end();
4867 } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4868 auto *PC = cast<OMPLastprivateClause>(Cl);
4869 I = PC->private_copies().begin();
4870 It = PC->varlist_begin();
4871 Et = PC->varlist_end();
4872 } else if (Cl->getClauseKind() == OMPC_linear) {
4873 auto *PC = cast<OMPLinearClause>(Cl);
4874 I = PC->privates().begin();
4875 It = PC->varlist_begin();
4876 Et = PC->varlist_end();
4877 } else if (Cl->getClauseKind() == OMPC_reduction) {
4878 auto *PC = cast<OMPReductionClause>(Cl);
4879 I = PC->privates().begin();
4880 It = PC->varlist_begin();
4881 Et = PC->varlist_end();
4882 } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4883 auto *PC = cast<OMPTaskReductionClause>(Cl);
4884 I = PC->privates().begin();
4885 It = PC->varlist_begin();
4886 Et = PC->varlist_end();
4887 } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4888 auto *PC = cast<OMPInReductionClause>(Cl);
4889 I = PC->privates().begin();
4890 It = PC->varlist_begin();
4891 Et = PC->varlist_end();
4893 llvm_unreachable("Expected private clause.");
4895 for (Expr *E : llvm::make_range(It, Et)) {
4900 SourceLocation ELoc;
4902 Expr *SimpleRefExpr = E;
4903 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4904 /*AllowArraySection=*/true);
4905 DeclToCopy.try_emplace(Res.first,
4906 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4910 for (OMPClause *C : AllocateRange) {
4911 auto *AC = cast<OMPAllocateClause>(C);
4912 if (S.getLangOpts().OpenMP >= 50 &&
4913 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
4914 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4915 AC->getAllocator()) {
4916 Expr *Allocator = AC->getAllocator();
4917 // OpenMP, 2.12.5 target Construct
4918 // Memory allocators that do not appear in a uses_allocators clause cannot
4919 // appear as an allocator in an allocate clause or be used in the target
4920 // region unless a requires directive with the dynamic_allocators clause
4921 // is present in the same compilation unit.
4922 AllocatorChecker Checker(Stack);
4923 if (Checker.Visit(Allocator))
4924 S.Diag(Allocator->getExprLoc(),
4925 diag::err_omp_allocator_not_in_uses_allocators)
4926 << Allocator->getSourceRange();
4928 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4929 getAllocatorKind(S, Stack, AC->getAllocator());
4930 // OpenMP, 2.11.4 allocate Clause, Restrictions.
4931 // For task, taskloop or target directives, allocation requests to memory
4932 // allocators with the trait access set to thread result in unspecified
4934 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4935 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4936 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4937 S.Diag(AC->getAllocator()->getExprLoc(),
4938 diag::warn_omp_allocate_thread_on_task_target_directive)
4939 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4941 for (Expr *E : AC->varlists()) {
4942 SourceLocation ELoc;
4944 Expr *SimpleRefExpr = E;
4945 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4946 ValueDecl *VD = Res.first;
4947 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4948 if (!isOpenMPPrivate(Data.CKind)) {
4949 S.Diag(E->getExprLoc(),
4950 diag::err_omp_expected_private_copy_for_allocate);
4953 VarDecl *PrivateVD = DeclToCopy[VD];
4954 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4955 AllocatorKind, AC->getAllocator()))
4957 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4958 E->getSourceRange());
4963 StmtResult Sema::ActOnOpenMPExecutableDirective(
4964 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
4965 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4966 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4967 StmtResult Res = StmtError();
4968 // First check CancelRegion which is then used in checkNestingOfRegions.
4969 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4970 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
4974 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4975 VarsWithInheritedDSAType VarsWithInheritedDSA;
4976 bool ErrorFound = false;
4977 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4978 if (AStmt && !CurContext->isDependentContext()) {
4979 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4981 // Check default data sharing attributes for referenced variables.
4982 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
4983 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4985 while (--ThisCaptureLevel >= 0)
4986 S = cast<CapturedStmt>(S)->getCapturedStmt();
4987 DSAChecker.Visit(S);
4988 if (!isOpenMPTargetDataManagementDirective(Kind) &&
4989 !isOpenMPTaskingDirective(Kind)) {
4990 // Visit subcaptures to generate implicit clauses for captured vars.
4991 auto *CS = cast<CapturedStmt>(AStmt);
4992 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4993 getOpenMPCaptureRegions(CaptureRegions, Kind);
4994 // Ignore outer tasking regions for target directives.
4995 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4996 CS = cast<CapturedStmt>(CS->getCapturedStmt());
4997 DSAChecker.visitSubCaptures(CS);
4999 if (DSAChecker.isErrorFound())
5001 // Generate list of implicitly defined firstprivate variables.
5002 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5004 SmallVector<Expr *, 4> ImplicitFirstprivates(
5005 DSAChecker.getImplicitFirstprivate().begin(),
5006 DSAChecker.getImplicitFirstprivate().end());
5007 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
5008 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5009 ArrayRef<Expr *> ImplicitMap =
5010 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
5011 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
5013 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5014 for (OMPClause *C : Clauses) {
5015 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5016 for (Expr *E : IRC->taskgroup_descriptors())
5018 ImplicitFirstprivates.emplace_back(E);
5020 // OpenMP 5.0, 2.10.1 task Construct
5021 // [detach clause]... The event-handle will be considered as if it was
5022 // specified on a firstprivate clause.
5023 if (auto *DC = dyn_cast<OMPDetachClause>(C))
5024 ImplicitFirstprivates.push_back(DC->getEventHandler());
5026 if (!ImplicitFirstprivates.empty()) {
5027 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5028 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5029 SourceLocation())) {
5030 ClausesWithImplicit.push_back(Implicit);
5031 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5032 ImplicitFirstprivates.size();
5037 int ClauseKindCnt = -1;
5038 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
5040 if (ImplicitMap.empty())
5042 CXXScopeSpec MapperIdScopeSpec;
5043 DeclarationNameInfo MapperId;
5044 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5045 if (OMPClause *Implicit = ActOnOpenMPMapClause(
5046 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
5047 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5048 ImplicitMap, OMPVarListLocTy())) {
5049 ClausesWithImplicit.emplace_back(Implicit);
5051 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
5058 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5061 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5063 AllowedNameModifiers.push_back(OMPD_parallel);
5066 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5067 VarsWithInheritedDSA);
5068 if (LangOpts.OpenMP >= 50)
5069 AllowedNameModifiers.push_back(OMPD_simd);
5072 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5073 VarsWithInheritedDSA);
5076 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5077 EndLoc, VarsWithInheritedDSA);
5078 if (LangOpts.OpenMP >= 50)
5079 AllowedNameModifiers.push_back(OMPD_simd);
5082 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5086 assert(ClausesWithImplicit.empty() &&
5087 "No clauses are allowed for 'omp section' directive");
5088 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5091 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5095 assert(ClausesWithImplicit.empty() &&
5096 "No clauses are allowed for 'omp master' directive");
5097 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5100 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5103 case OMPD_parallel_for:
5104 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5105 EndLoc, VarsWithInheritedDSA);
5106 AllowedNameModifiers.push_back(OMPD_parallel);
5108 case OMPD_parallel_for_simd:
5109 Res = ActOnOpenMPParallelForSimdDirective(
5110 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5111 AllowedNameModifiers.push_back(OMPD_parallel);
5112 if (LangOpts.OpenMP >= 50)
5113 AllowedNameModifiers.push_back(OMPD_simd);
5115 case OMPD_parallel_master:
5116 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5118 AllowedNameModifiers.push_back(OMPD_parallel);
5120 case OMPD_parallel_sections:
5121 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5123 AllowedNameModifiers.push_back(OMPD_parallel);
5127 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5128 AllowedNameModifiers.push_back(OMPD_task);
5130 case OMPD_taskyield:
5131 assert(ClausesWithImplicit.empty() &&
5132 "No clauses are allowed for 'omp taskyield' directive");
5133 assert(AStmt == nullptr &&
5134 "No associated statement allowed for 'omp taskyield' directive");
5135 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5138 assert(ClausesWithImplicit.empty() &&
5139 "No clauses are allowed for 'omp barrier' directive");
5140 assert(AStmt == nullptr &&
5141 "No associated statement allowed for 'omp barrier' directive");
5142 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5145 assert(ClausesWithImplicit.empty() &&
5146 "No clauses are allowed for 'omp taskwait' directive");
5147 assert(AStmt == nullptr &&
5148 "No associated statement allowed for 'omp taskwait' directive");
5149 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5151 case OMPD_taskgroup:
5152 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5156 assert(AStmt == nullptr &&
5157 "No associated statement allowed for 'omp flush' directive");
5158 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5161 assert(AStmt == nullptr &&
5162 "No associated statement allowed for 'omp depobj' directive");
5163 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5166 assert(AStmt == nullptr &&
5167 "No associated statement allowed for 'omp scan' directive");
5168 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5171 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5175 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5180 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5183 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5185 AllowedNameModifiers.push_back(OMPD_target);
5187 case OMPD_target_parallel:
5188 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5190 AllowedNameModifiers.push_back(OMPD_target);
5191 AllowedNameModifiers.push_back(OMPD_parallel);
5193 case OMPD_target_parallel_for:
5194 Res = ActOnOpenMPTargetParallelForDirective(
5195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5196 AllowedNameModifiers.push_back(OMPD_target);
5197 AllowedNameModifiers.push_back(OMPD_parallel);
5199 case OMPD_cancellation_point:
5200 assert(ClausesWithImplicit.empty() &&
5201 "No clauses are allowed for 'omp cancellation point' directive");
5202 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5203 "cancellation point' directive");
5204 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5207 assert(AStmt == nullptr &&
5208 "No associated statement allowed for 'omp cancel' directive");
5209 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5211 AllowedNameModifiers.push_back(OMPD_cancel);
5213 case OMPD_target_data:
5214 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5216 AllowedNameModifiers.push_back(OMPD_target_data);
5218 case OMPD_target_enter_data:
5219 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
5221 AllowedNameModifiers.push_back(OMPD_target_enter_data);
5223 case OMPD_target_exit_data:
5224 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
5226 AllowedNameModifiers.push_back(OMPD_target_exit_data);
5229 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
5230 EndLoc, VarsWithInheritedDSA);
5231 AllowedNameModifiers.push_back(OMPD_taskloop);
5233 case OMPD_taskloop_simd:
5234 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5235 EndLoc, VarsWithInheritedDSA);
5236 AllowedNameModifiers.push_back(OMPD_taskloop);
5237 if (LangOpts.OpenMP >= 50)
5238 AllowedNameModifiers.push_back(OMPD_simd);
5240 case OMPD_master_taskloop:
5241 Res = ActOnOpenMPMasterTaskLoopDirective(
5242 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5243 AllowedNameModifiers.push_back(OMPD_taskloop);
5245 case OMPD_master_taskloop_simd:
5246 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
5247 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5248 AllowedNameModifiers.push_back(OMPD_taskloop);
5249 if (LangOpts.OpenMP >= 50)
5250 AllowedNameModifiers.push_back(OMPD_simd);
5252 case OMPD_parallel_master_taskloop:
5253 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
5254 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5255 AllowedNameModifiers.push_back(OMPD_taskloop);
5256 AllowedNameModifiers.push_back(OMPD_parallel);
5258 case OMPD_parallel_master_taskloop_simd:
5259 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
5260 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5261 AllowedNameModifiers.push_back(OMPD_taskloop);
5262 AllowedNameModifiers.push_back(OMPD_parallel);
5263 if (LangOpts.OpenMP >= 50)
5264 AllowedNameModifiers.push_back(OMPD_simd);
5266 case OMPD_distribute:
5267 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
5268 EndLoc, VarsWithInheritedDSA);
5270 case OMPD_target_update:
5271 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
5273 AllowedNameModifiers.push_back(OMPD_target_update);
5275 case OMPD_distribute_parallel_for:
5276 Res = ActOnOpenMPDistributeParallelForDirective(
5277 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5278 AllowedNameModifiers.push_back(OMPD_parallel);
5280 case OMPD_distribute_parallel_for_simd:
5281 Res = ActOnOpenMPDistributeParallelForSimdDirective(
5282 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5283 AllowedNameModifiers.push_back(OMPD_parallel);
5284 if (LangOpts.OpenMP >= 50)
5285 AllowedNameModifiers.push_back(OMPD_simd);
5287 case OMPD_distribute_simd:
5288 Res = ActOnOpenMPDistributeSimdDirective(
5289 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5290 if (LangOpts.OpenMP >= 50)
5291 AllowedNameModifiers.push_back(OMPD_simd);
5293 case OMPD_target_parallel_for_simd:
5294 Res = ActOnOpenMPTargetParallelForSimdDirective(
5295 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5296 AllowedNameModifiers.push_back(OMPD_target);
5297 AllowedNameModifiers.push_back(OMPD_parallel);
5298 if (LangOpts.OpenMP >= 50)
5299 AllowedNameModifiers.push_back(OMPD_simd);
5301 case OMPD_target_simd:
5302 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5303 EndLoc, VarsWithInheritedDSA);
5304 AllowedNameModifiers.push_back(OMPD_target);
5305 if (LangOpts.OpenMP >= 50)
5306 AllowedNameModifiers.push_back(OMPD_simd);
5308 case OMPD_teams_distribute:
5309 Res = ActOnOpenMPTeamsDistributeDirective(
5310 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5312 case OMPD_teams_distribute_simd:
5313 Res = ActOnOpenMPTeamsDistributeSimdDirective(
5314 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5315 if (LangOpts.OpenMP >= 50)
5316 AllowedNameModifiers.push_back(OMPD_simd);
5318 case OMPD_teams_distribute_parallel_for_simd:
5319 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
5320 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5321 AllowedNameModifiers.push_back(OMPD_parallel);
5322 if (LangOpts.OpenMP >= 50)
5323 AllowedNameModifiers.push_back(OMPD_simd);
5325 case OMPD_teams_distribute_parallel_for:
5326 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
5327 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5328 AllowedNameModifiers.push_back(OMPD_parallel);
5330 case OMPD_target_teams:
5331 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
5333 AllowedNameModifiers.push_back(OMPD_target);
5335 case OMPD_target_teams_distribute:
5336 Res = ActOnOpenMPTargetTeamsDistributeDirective(
5337 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5338 AllowedNameModifiers.push_back(OMPD_target);
5340 case OMPD_target_teams_distribute_parallel_for:
5341 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
5342 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5343 AllowedNameModifiers.push_back(OMPD_target);
5344 AllowedNameModifiers.push_back(OMPD_parallel);
5346 case OMPD_target_teams_distribute_parallel_for_simd:
5347 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
5348 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5349 AllowedNameModifiers.push_back(OMPD_target);
5350 AllowedNameModifiers.push_back(OMPD_parallel);
5351 if (LangOpts.OpenMP >= 50)
5352 AllowedNameModifiers.push_back(OMPD_simd);
5354 case OMPD_target_teams_distribute_simd:
5355 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
5356 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5357 AllowedNameModifiers.push_back(OMPD_target);
5358 if (LangOpts.OpenMP >= 50)
5359 AllowedNameModifiers.push_back(OMPD_simd);
5361 case OMPD_declare_target:
5362 case OMPD_end_declare_target:
5363 case OMPD_threadprivate:
5365 case OMPD_declare_reduction:
5366 case OMPD_declare_mapper:
5367 case OMPD_declare_simd:
5369 case OMPD_declare_variant:
5370 case OMPD_begin_declare_variant:
5371 case OMPD_end_declare_variant:
5372 llvm_unreachable("OpenMP Directive is not allowed");
5375 llvm_unreachable("Unknown OpenMP directive");
5378 ErrorFound = Res.isInvalid() || ErrorFound;
5380 // Check variables in the clauses if default(none) or
5381 // default(firstprivate) was specified.
5382 if (DSAStack->getDefaultDSA() == DSA_none ||
5383 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5384 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
5385 for (OMPClause *C : Clauses) {
5386 switch (C->getClauseKind()) {
5387 case OMPC_num_threads:
5388 case OMPC_dist_schedule:
5389 // Do not analyse if no parent teams directive.
5390 if (isOpenMPTeamsDirective(Kind))
5394 if (isOpenMPTeamsDirective(Kind) &&
5395 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
5397 if (isOpenMPParallelDirective(Kind) &&
5398 isOpenMPTaskLoopDirective(Kind) &&
5399 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
5405 case OMPC_grainsize:
5406 case OMPC_num_tasks:
5409 // Do not analyze if no parent parallel directive.
5410 if (isOpenMPParallelDirective(Kind))
5415 case OMPC_num_teams:
5416 case OMPC_thread_limit:
5422 case OMPC_proc_bind:
5424 case OMPC_firstprivate:
5425 case OMPC_lastprivate:
5427 case OMPC_reduction:
5428 case OMPC_task_reduction:
5429 case OMPC_in_reduction:
5433 case OMPC_copyprivate:
5436 case OMPC_mergeable:
5452 case OMPC_defaultmap:
5455 case OMPC_use_device_ptr:
5456 case OMPC_use_device_addr:
5457 case OMPC_is_device_ptr:
5458 case OMPC_nontemporal:
5461 case OMPC_inclusive:
5462 case OMPC_exclusive:
5463 case OMPC_uses_allocators:
5466 case OMPC_allocator:
5469 case OMPC_threadprivate:
5472 case OMPC_unified_address:
5473 case OMPC_unified_shared_memory:
5474 case OMPC_reverse_offload:
5475 case OMPC_dynamic_allocators:
5476 case OMPC_atomic_default_mem_order:
5477 case OMPC_device_type:
5480 llvm_unreachable("Unexpected clause");
5482 for (Stmt *CC : C->children()) {
5484 DSAChecker.Visit(CC);
5487 for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
5488 VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
5490 for (const auto &P : VarsWithInheritedDSA) {
5491 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
5494 if (DSAStack->getDefaultDSA() == DSA_none ||
5495 DSAStack->getDefaultDSA() == DSA_firstprivate) {
5496 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
5497 << P.first << P.second->getSourceRange();
5498 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
5499 } else if (getLangOpts().OpenMP >= 50) {
5500 Diag(P.second->getExprLoc(),
5501 diag::err_omp_defaultmap_no_attr_for_variable)
5502 << P.first << P.second->getSourceRange();
5503 Diag(DSAStack->getDefaultDSALocation(),
5504 diag::note_omp_defaultmap_attr_none);
5508 if (!AllowedNameModifiers.empty())
5509 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
5515 if (!CurContext->isDependentContext() &&
5516 isOpenMPTargetExecutionDirective(Kind) &&
5517 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
5518 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
5519 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
5520 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
5521 // Register target to DSA Stack.
5522 DSAStack->addTargetDirLocation(StartLoc);
5528 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
5529 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
5530 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
5531 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
5532 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5533 assert(Aligneds.size() == Alignments.size());
5534 assert(Linears.size() == LinModifiers.size());
5535 assert(Linears.size() == Steps.size());
5536 if (!DG || DG.get().isNull())
5537 return DeclGroupPtrTy();
5539 const int SimdId = 0;
5540 if (!DG.get().isSingleDecl()) {
5541 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5545 Decl *ADecl = DG.get().getSingleDecl();
5546 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5547 ADecl = FTD->getTemplatedDecl();
5549 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5551 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5552 return DeclGroupPtrTy();
5555 // OpenMP [2.8.2, declare simd construct, Description]
5556 // The parameter of the simdlen clause must be a constant positive integer
5560 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5561 // OpenMP [2.8.2, declare simd construct, Description]
5562 // The special this pointer can be used as if was one of the arguments to the
5563 // function in any of the linear, aligned, or uniform clauses.
5564 // The uniform clause declares one or more arguments to have an invariant
5565 // value for all concurrent invocations of the function in the execution of a
5566 // single SIMD loop.
5567 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5568 const Expr *UniformedLinearThis = nullptr;
5569 for (const Expr *E : Uniforms) {
5570 E = E->IgnoreParenImpCasts();
5571 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5572 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5573 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5574 FD->getParamDecl(PVD->getFunctionScopeIndex())
5575 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5576 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5579 if (isa<CXXThisExpr>(E)) {
5580 UniformedLinearThis = E;
5583 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5584 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5586 // OpenMP [2.8.2, declare simd construct, Description]
5587 // The aligned clause declares that the object to which each list item points
5588 // is aligned to the number of bytes expressed in the optional parameter of
5589 // the aligned clause.
5590 // The special this pointer can be used as if was one of the arguments to the
5591 // function in any of the linear, aligned, or uniform clauses.
5592 // The type of list items appearing in the aligned clause must be array,
5593 // pointer, reference to array, or reference to pointer.
5594 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5595 const Expr *AlignedThis = nullptr;
5596 for (const Expr *E : Aligneds) {
5597 E = E->IgnoreParenImpCasts();
5598 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5599 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5600 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5601 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5602 FD->getParamDecl(PVD->getFunctionScopeIndex())
5603 ->getCanonicalDecl() == CanonPVD) {
5604 // OpenMP [2.8.1, simd construct, Restrictions]
5605 // A list-item cannot appear in more than one aligned clause.
5606 if (AlignedArgs.count(CanonPVD) > 0) {
5607 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5608 << 1 << getOpenMPClauseName(OMPC_aligned)
5609 << E->getSourceRange();
5610 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5611 diag::note_omp_explicit_dsa)
5612 << getOpenMPClauseName(OMPC_aligned);
5615 AlignedArgs[CanonPVD] = E;
5616 QualType QTy = PVD->getType()
5617 .getNonReferenceType()
5618 .getUnqualifiedType()
5619 .getCanonicalType();
5620 const Type *Ty = QTy.getTypePtrOrNull();
5621 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5622 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5623 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5624 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5629 if (isa<CXXThisExpr>(E)) {
5631 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5632 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5633 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5634 << getOpenMPClauseName(OMPC_aligned);
5639 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5640 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5642 // The optional parameter of the aligned clause, alignment, must be a constant
5643 // positive integer expression. If no optional parameter is specified,
5644 // implementation-defined default alignments for SIMD instructions on the
5645 // target platforms are assumed.
5646 SmallVector<const Expr *, 4> NewAligns;
5647 for (Expr *E : Alignments) {
5650 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5651 NewAligns.push_back(Align.get());
5653 // OpenMP [2.8.2, declare simd construct, Description]
5654 // The linear clause declares one or more list items to be private to a SIMD
5655 // lane and to have a linear relationship with respect to the iteration space
5657 // The special this pointer can be used as if was one of the arguments to the
5658 // function in any of the linear, aligned, or uniform clauses.
5659 // When a linear-step expression is specified in a linear clause it must be
5660 // either a constant integer expression or an integer-typed parameter that is
5661 // specified in a uniform clause on the directive.
5662 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5663 const bool IsUniformedThis = UniformedLinearThis != nullptr;
5664 auto MI = LinModifiers.begin();
5665 for (const Expr *E : Linears) {
5666 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5668 E = E->IgnoreParenImpCasts();
5669 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5670 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5671 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5672 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5673 FD->getParamDecl(PVD->getFunctionScopeIndex())
5674 ->getCanonicalDecl() == CanonPVD) {
5675 // OpenMP [2.15.3.7, linear Clause, Restrictions]
5676 // A list-item cannot appear in more than one linear clause.
5677 if (LinearArgs.count(CanonPVD) > 0) {
5678 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5679 << getOpenMPClauseName(OMPC_linear)
5680 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5681 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5682 diag::note_omp_explicit_dsa)
5683 << getOpenMPClauseName(OMPC_linear);
5686 // Each argument can appear in at most one uniform or linear clause.
5687 if (UniformedArgs.count(CanonPVD) > 0) {
5688 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5689 << getOpenMPClauseName(OMPC_linear)
5690 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
5691 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5692 diag::note_omp_explicit_dsa)
5693 << getOpenMPClauseName(OMPC_uniform);
5696 LinearArgs[CanonPVD] = E;
5697 if (E->isValueDependent() || E->isTypeDependent() ||
5698 E->isInstantiationDependent() ||
5699 E->containsUnexpandedParameterPack())
5701 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5702 PVD->getOriginalType(),
5703 /*IsDeclareSimd=*/true);
5707 if (isa<CXXThisExpr>(E)) {
5708 if (UniformedLinearThis) {
5709 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5710 << getOpenMPClauseName(OMPC_linear)
5711 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5712 << E->getSourceRange();
5713 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5714 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5718 UniformedLinearThis = E;
5719 if (E->isValueDependent() || E->isTypeDependent() ||
5720 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
5722 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5723 E->getType(), /*IsDeclareSimd=*/true);
5726 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5727 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5729 Expr *Step = nullptr;
5730 Expr *NewStep = nullptr;
5731 SmallVector<Expr *, 4> NewSteps;
5732 for (Expr *E : Steps) {
5733 // Skip the same step expression, it was checked already.
5734 if (Step == E || !E) {
5735 NewSteps.push_back(E ? NewStep : nullptr);
5739 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5740 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5741 const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5742 if (UniformedArgs.count(CanonPVD) == 0) {
5743 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5744 << Step->getSourceRange();
5745 } else if (E->isValueDependent() || E->isTypeDependent() ||
5746 E->isInstantiationDependent() ||
5747 E->containsUnexpandedParameterPack() ||
5748 CanonPVD->getType()->hasIntegerRepresentation()) {
5749 NewSteps.push_back(Step);
5751 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5752 << Step->getSourceRange();
5757 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5758 !Step->isInstantiationDependent() &&
5759 !Step->containsUnexpandedParameterPack()) {
5760 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5763 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5765 NewSteps.push_back(NewStep);
5767 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5768 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5769 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5770 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5771 const_cast<Expr **>(Linears.data()), Linears.size(),
5772 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5773 NewSteps.data(), NewSteps.size(), SR);
5774 ADecl->addAttr(NewAttr);
5778 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5780 assert(NewType->isFunctionProtoType() &&
5781 "Expected function type with prototype.");
5782 assert(FD->getType()->isFunctionNoProtoType() &&
5783 "Expected function with type with no prototype.");
5784 assert(FDWithProto->getType()->isFunctionProtoType() &&
5785 "Expected function with prototype.");
5786 // Synthesize parameters with the same types.
5787 FD->setType(NewType);
5788 SmallVector<ParmVarDecl *, 16> Params;
5789 for (const ParmVarDecl *P : FDWithProto->parameters()) {
5790 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5791 SourceLocation(), nullptr, P->getType(),
5792 /*TInfo=*/nullptr, SC_None, nullptr);
5793 Param->setScopeInfo(0, Params.size());
5794 Param->setImplicit();
5795 Params.push_back(Param);
5798 FD->setParams(Params);
5801 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
5802 : TI(&TI), NameSuffix(TI.getMangledName()) {}
5805 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S,
5807 IdentifierInfo *BaseII = D.getIdentifier();
5808 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
5809 LookupOrdinaryName);
5810 LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
5812 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
5813 QualType FType = TInfo->getType();
5815 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr;
5816 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval;
5818 FunctionDecl *BaseFD = nullptr;
5819 for (auto *Candidate : Lookup) {
5820 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl());
5824 // Don't specialize constexpr/consteval functions with
5825 // non-constexpr/consteval functions.
5826 if (UDecl->isConstexpr() && !IsConstexpr)
5828 if (UDecl->isConsteval() && !IsConsteval)
5831 QualType NewType = Context.mergeFunctionTypes(
5832 FType, UDecl->getType(), /* OfBlockPointer */ false,
5833 /* Unqualified */ false, /* AllowCXX */ true);
5834 if (NewType.isNull())
5842 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D));
5843 BaseFD->setImplicit(true);
5846 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5847 std::string MangledName;
5848 MangledName += D.getIdentifier()->getName();
5849 MangledName += getOpenMPVariantManglingSeparatorStr();
5850 MangledName += DVScope.NameSuffix;
5851 IdentifierInfo &VariantII = Context.Idents.get(MangledName);
5853 VariantII.setMangledOpenMPVariantName(true);
5854 D.SetIdentifier(&VariantII, D.getBeginLoc());
5858 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
5859 FunctionDecl *FD, FunctionDecl *BaseFD) {
5860 // Do not mark function as is used to prevent its emission if this is the
5861 // only place where it is used.
5862 EnterExpressionEvaluationContext Unevaluated(
5863 *this, Sema::ExpressionEvaluationContext::Unevaluated);
5865 Expr *VariantFuncRef = DeclRefExpr::Create(
5866 Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
5867 /* RefersToEnclosingVariableOrCapture */ false,
5868 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
5870 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
5871 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
5872 Context, VariantFuncRef, DVScope.TI);
5873 BaseFD->addAttr(OMPDeclareVariantA);
5876 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
5877 SourceLocation LParenLoc,
5878 MultiExprArg ArgExprs,
5879 SourceLocation RParenLoc, Expr *ExecConfig) {
5880 // The common case is a regular call we do not want to specialize at all. Try
5881 // to make that case fast by bailing early.
5882 CallExpr *CE = dyn_cast<CallExpr>(Call.get());
5886 FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
5890 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
5893 ASTContext &Context = getASTContext();
5894 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice,
5895 Context.getTargetInfo().getTriple());
5897 SmallVector<Expr *, 4> Exprs;
5898 SmallVector<VariantMatchInfo, 4> VMIs;
5899 while (CalleeFnDecl) {
5900 for (OMPDeclareVariantAttr *A :
5901 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
5902 Expr *VariantRef = A->getVariantFuncRef();
5904 VariantMatchInfo VMI;
5905 OMPTraitInfo &TI = A->getTraitInfo();
5906 TI.getAsVariantMatchInfo(Context, VMI);
5907 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false))
5910 VMIs.push_back(VMI);
5911 Exprs.push_back(VariantRef);
5914 CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
5919 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
5922 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
5923 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
5926 // Try to build a (member) call expression for the current best applicable
5927 // variant expression. We allow this to fail in which case we continue
5928 // with the next best variant expression. The fail case is part of the
5929 // implementation defined behavior in the OpenMP standard when it talks
5930 // about what differences in the function prototypes: "Any differences
5931 // that the specific OpenMP context requires in the prototype of the
5932 // variant from the base function prototype are implementation defined."
5933 // This wording is there to allow the specialized variant to have a
5934 // different type than the base function. This is intended and OK but if
5935 // we cannot create a call the difference is not in the "implementation
5936 // defined range" we allow.
5937 Sema::TentativeAnalysisScope Trap(*this);
5939 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
5940 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
5941 BestExpr = MemberExpr::CreateImplicit(
5942 Context, MemberCall->getImplicitObjectArgument(),
5943 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
5944 MemberCall->getValueKind(), MemberCall->getObjectKind());
5946 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
5948 if (NewCall.isUsable())
5952 VMIs.erase(VMIs.begin() + BestIdx);
5953 Exprs.erase(Exprs.begin() + BestIdx);
5954 } while (!VMIs.empty());
5956 if (!NewCall.isUsable())
5958 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
5961 Optional<std::pair<FunctionDecl *, Expr *>>
5962 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
5963 Expr *VariantRef, OMPTraitInfo &TI,
5965 if (!DG || DG.get().isNull())
5968 const int VariantId = 1;
5969 // Must be applied only to single decl.
5970 if (!DG.get().isSingleDecl()) {
5971 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5975 Decl *ADecl = DG.get().getSingleDecl();
5976 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5977 ADecl = FTD->getTemplatedDecl();
5979 // Decl must be a function.
5980 auto *FD = dyn_cast<FunctionDecl>(ADecl);
5982 Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5987 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
5988 return FD->hasAttrs() &&
5989 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5990 FD->hasAttr<TargetAttr>());
5992 // OpenMP is not compatible with CPU-specific attributes.
5993 if (HasMultiVersionAttributes(FD)) {
5994 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
5999 // Allow #pragma omp declare variant only if the function is not used.
6000 if (FD->isUsed(false))
6001 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6002 << FD->getLocation();
6004 // Check if the function was emitted already.
6005 const FunctionDecl *Definition;
6006 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6007 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6008 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6009 << FD->getLocation();
6011 // The VariantRef must point to function.
6013 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6017 auto ShouldDelayChecks = [](Expr *&E, bool) {
6018 return E && (E->isTypeDependent() || E->isValueDependent() ||
6019 E->containsUnexpandedParameterPack() ||
6020 E->isInstantiationDependent());
6022 // Do not check templates, wait until instantiation.
6023 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6024 TI.anyScoreOrCondition(ShouldDelayChecks))
6025 return std::make_pair(FD, VariantRef);
6027 // Deal with non-constant score and user condition expressions.
6028 auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6029 bool IsScore) -> bool {
6030 llvm::APSInt Result;
6031 if (!E || E->isIntegerConstantExpr(Result, Context))
6035 // We warn on non-constant scores and pretend they were not present.
6036 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6040 // We could replace a non-constant user condition with "false" but we
6041 // will soon need to handle these anyway for the dynamic version of
6042 // OpenMP context selectors.
6043 Diag(E->getExprLoc(),
6044 diag::err_omp_declare_variant_user_condition_not_constant)
6049 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6052 // Convert VariantRef expression to the type of the original function to
6053 // resolve possible conflicts.
6054 ExprResult VariantRefCast;
6055 if (LangOpts.CPlusPlus) {
6057 auto *Method = dyn_cast<CXXMethodDecl>(FD);
6058 if (Method && !Method->isStatic()) {
6059 const Type *ClassType =
6060 Context.getTypeDeclType(Method->getParent()).getTypePtr();
6061 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6064 // Build adrr_of unary op to correctly handle type checks for member
6066 Sema::TentativeAnalysisScope Trap(*this);
6067 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6070 if (!ER.isUsable()) {
6071 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6072 << VariantId << VariantRef->getSourceRange();
6075 VariantRef = ER.get();
6077 FnPtrType = Context.getPointerType(FD->getType());
6079 ImplicitConversionSequence ICS =
6080 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
6081 /*SuppressUserConversions=*/false,
6082 AllowedExplicit::None,
6083 /*InOverloadResolution=*/false,
6085 /*AllowObjCWritebackConversion=*/false);
6086 if (ICS.isFailure()) {
6087 Diag(VariantRef->getExprLoc(),
6088 diag::err_omp_declare_variant_incompat_types)
6089 << VariantRef->getType()
6090 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6091 << VariantRef->getSourceRange();
6094 VariantRefCast = PerformImplicitConversion(
6095 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6096 if (!VariantRefCast.isUsable())
6098 // Drop previously built artificial addr_of unary op for member functions.
6099 if (Method && !Method->isStatic()) {
6100 Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6101 if (auto *UO = dyn_cast<UnaryOperator>(
6102 PossibleAddrOfVariantRef->IgnoreImplicit()))
6103 VariantRefCast = UO->getSubExpr();
6106 VariantRefCast = VariantRef;
6109 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6110 if (!ER.isUsable() ||
6111 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6112 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6113 << VariantId << VariantRef->getSourceRange();
6117 // The VariantRef must point to function.
6118 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6120 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6121 << VariantId << VariantRef->getSourceRange();
6124 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6126 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6127 << VariantId << VariantRef->getSourceRange();
6131 // Check if function types are compatible in C.
6132 if (!LangOpts.CPlusPlus) {
6134 Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
6135 if (NewType.isNull()) {
6136 Diag(VariantRef->getExprLoc(),
6137 diag::err_omp_declare_variant_incompat_types)
6138 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
6141 if (NewType->isFunctionProtoType()) {
6142 if (FD->getType()->isFunctionNoProtoType())
6143 setPrototype(*this, FD, NewFD, NewType);
6144 else if (NewFD->getType()->isFunctionNoProtoType())
6145 setPrototype(*this, NewFD, FD, NewType);
6149 // Check if variant function is not marked with declare variant directive.
6150 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
6151 Diag(VariantRef->getExprLoc(),
6152 diag::warn_omp_declare_variant_marked_as_declare_variant)
6153 << VariantRef->getSourceRange();
6155 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
6156 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
6160 enum DoesntSupport {
6169 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
6170 if (CXXFD->isVirtual()) {
6171 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6176 if (isa<CXXConstructorDecl>(FD)) {
6177 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6182 if (isa<CXXDestructorDecl>(FD)) {
6183 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6189 if (FD->isDeleted()) {
6190 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6195 if (FD->isDefaulted()) {
6196 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6201 if (FD->isConstexpr()) {
6202 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
6203 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
6207 // Check general compatibility.
6208 if (areMultiversionVariantFunctionsCompatible(
6209 FD, NewFD, PartialDiagnostic::NullDiagnostic(),
6210 PartialDiagnosticAt(SourceLocation(),
6211 PartialDiagnostic::NullDiagnostic()),
6212 PartialDiagnosticAt(
6213 VariantRef->getExprLoc(),
6214 PDiag(diag::err_omp_declare_variant_doesnt_support)),
6215 PartialDiagnosticAt(VariantRef->getExprLoc(),
6216 PDiag(diag::err_omp_declare_variant_diff)
6217 << FD->getLocation()),
6218 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
6219 /*CLinkageMayDiffer=*/true))
6221 return std::make_pair(FD, cast<Expr>(DRE));
6224 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
6229 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
6230 FD->addAttr(NewAttr);
6233 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
6235 SourceLocation StartLoc,
6236 SourceLocation EndLoc) {
6240 auto *CS = cast<CapturedStmt>(AStmt);
6241 // 1.2.2 OpenMP Language Terminology
6242 // Structured block - An executable statement with a single entry at the
6243 // top and a single exit at the bottom.
6244 // The point of exit cannot be a branch out of the structured block.
6245 // longjmp() and throw() must not violate the entry/exit criteria.
6246 CS->getCapturedDecl()->setNothrow();
6248 setFunctionHasBranchProtectedScope();
6250 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6251 DSAStack->getTaskgroupReductionRef(),
6252 DSAStack->isCancelRegion());
6256 /// Iteration space of a single for loop.
6257 struct LoopIterationSpace final {
6258 /// True if the condition operator is the strict compare operator (<, > or
6260 bool IsStrictCompare = false;
6261 /// Condition of the loop.
6262 Expr *PreCond = nullptr;
6263 /// This expression calculates the number of iterations in the loop.
6264 /// It is always possible to calculate it before starting the loop.
6265 Expr *NumIterations = nullptr;
6266 /// The loop counter variable.
6267 Expr *CounterVar = nullptr;
6268 /// Private loop counter variable.
6269 Expr *PrivateCounterVar = nullptr;
6270 /// This is initializer for the initial value of #CounterVar.
6271 Expr *CounterInit = nullptr;
6272 /// This is step for the #CounterVar used to generate its update:
6273 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
6274 Expr *CounterStep = nullptr;
6275 /// Should step be subtracted?
6276 bool Subtract = false;
6277 /// Source range of the loop init.
6278 SourceRange InitSrcRange;
6279 /// Source range of the loop condition.
6280 SourceRange CondSrcRange;
6281 /// Source range of the loop increment.
6282 SourceRange IncSrcRange;
6283 /// Minimum value that can have the loop control variable. Used to support
6284 /// non-rectangular loops. Applied only for LCV with the non-iterator types,
6285 /// since only such variables can be used in non-loop invariant expressions.
6286 Expr *MinValue = nullptr;
6287 /// Maximum value that can have the loop control variable. Used to support
6288 /// non-rectangular loops. Applied only for LCV with the non-iterator type,
6289 /// since only such variables can be used in non-loop invariant expressions.
6290 Expr *MaxValue = nullptr;
6291 /// true, if the lower bound depends on the outer loop control var.
6292 bool IsNonRectangularLB = false;
6293 /// true, if the upper bound depends on the outer loop control var.
6294 bool IsNonRectangularUB = false;
6295 /// Index of the loop this loop depends on and forms non-rectangular loop
6297 unsigned LoopDependentIdx = 0;
6298 /// Final condition for the non-rectangular loop nest support. It is used to
6299 /// check that the number of iterations for this particular counter must be
6301 Expr *FinalCondition = nullptr;
6304 /// Helper class for checking canonical form of the OpenMP loops and
6305 /// extracting iteration space of each loop in the loop nest, that will be used
6306 /// for IR generation.
6307 class OpenMPIterationSpaceChecker {
6308 /// Reference to Sema.
6310 /// Data-sharing stack.
6312 /// A location for diagnostics (when there is no some better location).
6313 SourceLocation DefaultLoc;
6314 /// A location for diagnostics (when increment is not compatible).
6315 SourceLocation ConditionLoc;
6316 /// A source location for referring to loop init later.
6317 SourceRange InitSrcRange;
6318 /// A source location for referring to condition later.
6319 SourceRange ConditionSrcRange;
6320 /// A source location for referring to increment later.
6321 SourceRange IncrementSrcRange;
6323 ValueDecl *LCDecl = nullptr;
6324 /// Reference to loop variable.
6325 Expr *LCRef = nullptr;
6326 /// Lower bound (initializer for the var).
6330 /// Loop step (increment).
6331 Expr *Step = nullptr;
6332 /// This flag is true when condition is one of:
6337 /// This will have no value when the condition is !=
6338 llvm::Optional<bool> TestIsLessOp;
6339 /// This flag is true when condition is strict ( < or > ).
6340 bool TestIsStrictOp = false;
6341 /// This flag is true when step is subtracted on each iteration.
6342 bool SubtractStep = false;
6343 /// The outer loop counter this loop depends on (if any).
6344 const ValueDecl *DepDecl = nullptr;
6345 /// Contains number of loop (starts from 1) on which loop counter init
6346 /// expression of this loop depends on.
6347 Optional<unsigned> InitDependOnLC;
6348 /// Contains number of loop (starts from 1) on which loop counter condition
6349 /// expression of this loop depends on.
6350 Optional<unsigned> CondDependOnLC;
6351 /// Checks if the provide statement depends on the loop counter.
6352 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
6353 /// Original condition required for checking of the exit condition for
6354 /// non-rectangular loop.
6355 Expr *Condition = nullptr;
6358 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
6359 SourceLocation DefaultLoc)
6360 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
6361 ConditionLoc(DefaultLoc) {}
6362 /// Check init-expr for canonical loop form and save loop counter
6363 /// variable - #Var and its initialization value - #LB.
6364 bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
6365 /// Check test-expr for canonical form, save upper-bound (#UB), flags
6366 /// for less/greater and for strict/non-strict comparison.
6367 bool checkAndSetCond(Expr *S);
6368 /// Check incr-expr for canonical loop form and return true if it
6369 /// does not conform, otherwise save loop step (#Step).
6370 bool checkAndSetInc(Expr *S);
6371 /// Return the loop counter variable.
6372 ValueDecl *getLoopDecl() const { return LCDecl; }
6373 /// Return the reference expression to loop counter variable.
6374 Expr *getLoopDeclRefExpr() const { return LCRef; }
6375 /// Source range of the loop init.
6376 SourceRange getInitSrcRange() const { return InitSrcRange; }
6377 /// Source range of the loop condition.
6378 SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
6379 /// Source range of the loop increment.
6380 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
6381 /// True if the step should be subtracted.
6382 bool shouldSubtractStep() const { return SubtractStep; }
6383 /// True, if the compare operator is strict (<, > or !=).
6384 bool isStrictTestOp() const { return TestIsStrictOp; }
6385 /// Build the expression to calculate the number of iterations.
6386 Expr *buildNumIterations(
6387 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6388 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6389 /// Build the precondition expression for the loops.
6391 buildPreCond(Scope *S, Expr *Cond,
6392 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6393 /// Build reference expression to the counter be used for codegen.
6395 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6396 DSAStackTy &DSA) const;
6397 /// Build reference expression to the private counter be used for
6399 Expr *buildPrivateCounterVar() const;
6400 /// Build initialization of the counter be used for codegen.
6401 Expr *buildCounterInit() const;
6402 /// Build step of the counter be used for codegen.
6403 Expr *buildCounterStep() const;
6404 /// Build loop data with counter value for depend clauses in ordered
6407 buildOrderedLoopData(Scope *S, Expr *Counter,
6408 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6409 SourceLocation Loc, Expr *Inc = nullptr,
6410 OverloadedOperatorKind OOK = OO_Amp);
6411 /// Builds the minimum value for the loop counter.
6412 std::pair<Expr *, Expr *> buildMinMaxValues(
6413 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
6414 /// Builds final condition for the non-rectangular loops.
6415 Expr *buildFinalCondition(Scope *S) const;
6416 /// Return true if any expression is dependent.
6417 bool dependent() const;
6418 /// Returns true if the initializer forms non-rectangular loop.
6419 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
6420 /// Returns true if the condition forms non-rectangular loop.
6421 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
6422 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
6423 unsigned getLoopDependentIdx() const {
6424 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
6428 /// Check the right-hand side of an assignment in the increment
6430 bool checkAndSetIncRHS(Expr *RHS);
6431 /// Helper to set loop counter variable and its initializer.
6432 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
6434 /// Helper to set upper bound.
6435 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
6436 SourceRange SR, SourceLocation SL);
6437 /// Helper to set loop increment.
6438 bool setStep(Expr *NewStep, bool Subtract);
6441 bool OpenMPIterationSpaceChecker::dependent() const {
6443 assert(!LB && !UB && !Step);
6446 return LCDecl->getType()->isDependentType() ||
6447 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
6448 (Step && Step->isValueDependent());
6451 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
6453 Expr *NewLB, bool EmitDiags) {
6454 // State consistency checking to ensure correct usage.
6455 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
6456 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6457 if (!NewLCDecl || !NewLB)
6459 LCDecl = getCanonicalDecl(NewLCDecl);
6460 LCRef = NewLCRefExpr;
6461 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
6462 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6463 if ((Ctor->isCopyOrMoveConstructor() ||
6464 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6465 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6466 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
6469 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
6473 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
6474 llvm::Optional<bool> LessOp,
6475 bool StrictOp, SourceRange SR,
6476 SourceLocation SL) {
6477 // State consistency checking to ensure correct usage.
6478 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
6479 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
6484 TestIsLessOp = LessOp;
6485 TestIsStrictOp = StrictOp;
6486 ConditionSrcRange = SR;
6488 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
6492 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
6493 // State consistency checking to ensure correct usage.
6494 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
6497 if (!NewStep->isValueDependent()) {
6498 // Check that the step is integer expression.
6499 SourceLocation StepLoc = NewStep->getBeginLoc();
6500 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
6501 StepLoc, getExprAsWritten(NewStep));
6502 if (Val.isInvalid())
6504 NewStep = Val.get();
6506 // OpenMP [2.6, Canonical Loop Form, Restrictions]
6507 // If test-expr is of form var relational-op b and relational-op is < or
6508 // <= then incr-expr must cause var to increase on each iteration of the
6509 // loop. If test-expr is of form var relational-op b and relational-op is
6510 // > or >= then incr-expr must cause var to decrease on each iteration of
6512 // If test-expr is of form b relational-op var and relational-op is < or
6513 // <= then incr-expr must cause var to decrease on each iteration of the
6514 // loop. If test-expr is of form b relational-op var and relational-op is
6515 // > or >= then incr-expr must cause var to increase on each iteration of
6517 llvm::APSInt Result;
6518 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
6519 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
6521 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
6523 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
6524 bool IsConstZero = IsConstant && !Result.getBoolValue();
6526 // != with increment is treated as <; != with decrement is treated as >
6527 if (!TestIsLessOp.hasValue())
6528 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
6529 if (UB && (IsConstZero ||
6530 (TestIsLessOp.getValue() ?
6531 (IsConstNeg || (IsUnsigned && Subtract)) :
6532 (IsConstPos || (IsUnsigned && !Subtract))))) {
6533 SemaRef.Diag(NewStep->getExprLoc(),
6534 diag::err_omp_loop_incr_not_compatible)
6535 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
6536 SemaRef.Diag(ConditionLoc,
6537 diag::note_omp_loop_cond_requres_compatible_incr)
6538 << TestIsLessOp.getValue() << ConditionSrcRange;
6541 if (TestIsLessOp.getValue() == Subtract) {
6543 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
6545 Subtract = !Subtract;
6550 SubtractStep = Subtract;
6555 /// Checker for the non-rectangular loops. Checks if the initializer or
6556 /// condition expression references loop counter variable.
6557 class LoopCounterRefChecker final
6558 : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
6561 const ValueDecl *CurLCDecl = nullptr;
6562 const ValueDecl *DepDecl = nullptr;
6563 const ValueDecl *PrevDepDecl = nullptr;
6564 bool IsInitializer = true;
6565 unsigned BaseLoopId = 0;
6566 bool checkDecl(const Expr *E, const ValueDecl *VD) {
6567 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
6568 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
6569 << (IsInitializer ? 0 : 1);
6572 const auto &&Data = Stack.isLoopControlVariable(VD);
6573 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
6574 // The type of the loop iterator on which we depend may not have a random
6575 // access iterator type.
6576 if (Data.first && VD->getType()->isRecordType()) {
6577 SmallString<128> Name;
6578 llvm::raw_svector_ostream OS(Name);
6579 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6580 /*Qualified=*/true);
6581 SemaRef.Diag(E->getExprLoc(),
6582 diag::err_omp_wrong_dependency_iterator_type)
6584 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
6588 (DepDecl || (PrevDepDecl &&
6589 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
6590 if (!DepDecl && PrevDepDecl)
6591 DepDecl = PrevDepDecl;
6592 SmallString<128> Name;
6593 llvm::raw_svector_ostream OS(Name);
6594 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
6595 /*Qualified=*/true);
6596 SemaRef.Diag(E->getExprLoc(),
6597 diag::err_omp_invariant_or_linear_dependency)
6603 BaseLoopId = Data.first;
6609 bool VisitDeclRefExpr(const DeclRefExpr *E) {
6610 const ValueDecl *VD = E->getDecl();
6611 if (isa<VarDecl>(VD))
6612 return checkDecl(E, VD);
6615 bool VisitMemberExpr(const MemberExpr *E) {
6616 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
6617 const ValueDecl *VD = E->getMemberDecl();
6618 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
6619 return checkDecl(E, VD);
6623 bool VisitStmt(const Stmt *S) {
6625 for (const Stmt *Child : S->children())
6626 Res = (Child && Visit(Child)) || Res;
6629 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
6630 const ValueDecl *CurLCDecl, bool IsInitializer,
6631 const ValueDecl *PrevDepDecl = nullptr)
6632 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
6633 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
6634 unsigned getBaseLoopId() const {
6635 assert(CurLCDecl && "Expected loop dependency.");
6638 const ValueDecl *getDepDecl() const {
6639 assert(CurLCDecl && "Expected loop dependency.");
6646 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6647 bool IsInitializer) {
6648 // Check for the non-rectangular loops.
6649 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6651 if (LoopStmtChecker.Visit(S)) {
6652 DepDecl = LoopStmtChecker.getDepDecl();
6653 return LoopStmtChecker.getBaseLoopId();
6658 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6659 // Check init-expr for canonical loop form and save loop counter
6660 // variable - #Var and its initialization value - #LB.
6661 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6663 // integer-type var = lb
6664 // random-access-iterator-type var = lb
6665 // pointer-type var = lb
6669 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6673 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6674 if (!ExprTemp->cleanupsHaveSideEffects())
6675 S = ExprTemp->getSubExpr();
6677 InitSrcRange = S->getSourceRange();
6678 if (Expr *E = dyn_cast<Expr>(S))
6679 S = E->IgnoreParens();
6680 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6681 if (BO->getOpcode() == BO_Assign) {
6682 Expr *LHS = BO->getLHS()->IgnoreParens();
6683 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6684 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6685 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6686 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6688 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6690 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6691 if (ME->isArrow() &&
6692 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6693 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6697 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6698 if (DS->isSingleDecl()) {
6699 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6700 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6701 // Accept non-canonical init form here but emit ext. warning.
6702 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6703 SemaRef.Diag(S->getBeginLoc(),
6704 diag::ext_omp_loop_not_canonical_init)
6705 << S->getSourceRange();
6706 return setLCDeclAndLB(
6708 buildDeclRefExpr(SemaRef, Var,
6709 Var->getType().getNonReferenceType(),
6711 Var->getInit(), EmitDiags);
6715 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6716 if (CE->getOperator() == OO_Equal) {
6717 Expr *LHS = CE->getArg(0);
6718 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6719 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6720 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6721 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6723 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6725 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6726 if (ME->isArrow() &&
6727 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6728 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6734 if (dependent() || SemaRef.CurContext->isDependentContext())
6737 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6738 << S->getSourceRange();
6743 /// Ignore parenthesizes, implicit casts, copy constructor and return the
6744 /// variable (which may be the loop variable) if possible.
6745 static const ValueDecl *getInitLCDecl(const Expr *E) {
6748 E = getExprAsWritten(E);
6749 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6750 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6751 if ((Ctor->isCopyOrMoveConstructor() ||
6752 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6753 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6754 E = CE->getArg(0)->IgnoreParenImpCasts();
6755 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6756 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6757 return getCanonicalDecl(VD);
6759 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6760 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6761 return getCanonicalDecl(ME->getMemberDecl());
6765 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6766 // Check test-expr for canonical form, save upper-bound UB, flags for
6767 // less/greater and for strict/non-strict comparison.
6768 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6769 // var relational-op b
6770 // b relational-op var
6772 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6774 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6775 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6779 S = getExprAsWritten(S);
6780 SourceLocation CondLoc = S->getBeginLoc();
6781 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6782 if (BO->isRelationalOp()) {
6783 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6784 return setUB(BO->getRHS(),
6785 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6786 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6787 BO->getSourceRange(), BO->getOperatorLoc());
6788 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6789 return setUB(BO->getLHS(),
6790 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6791 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6792 BO->getSourceRange(), BO->getOperatorLoc());
6793 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6795 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6796 /*LessOp=*/llvm::None,
6797 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6798 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6799 if (CE->getNumArgs() == 2) {
6800 auto Op = CE->getOperator();
6803 case OO_GreaterEqual:
6806 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6807 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6808 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6809 CE->getOperatorLoc());
6810 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6811 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6812 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6813 CE->getOperatorLoc());
6815 case OO_ExclaimEqual:
6816 if (IneqCondIsCanonical)
6817 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6819 /*LessOp=*/llvm::None,
6820 /*StrictOp=*/true, CE->getSourceRange(),
6821 CE->getOperatorLoc());
6828 if (dependent() || SemaRef.CurContext->isDependentContext())
6830 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6831 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6835 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6836 // RHS of canonical loop form increment can be:
6841 RHS = RHS->IgnoreParenImpCasts();
6842 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6843 if (BO->isAdditiveOp()) {
6844 bool IsAdd = BO->getOpcode() == BO_Add;
6845 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6846 return setStep(BO->getRHS(), !IsAdd);
6847 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6848 return setStep(BO->getLHS(), /*Subtract=*/false);
6850 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6851 bool IsAdd = CE->getOperator() == OO_Plus;
6852 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6853 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6854 return setStep(CE->getArg(1), !IsAdd);
6855 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6856 return setStep(CE->getArg(0), /*Subtract=*/false);
6859 if (dependent() || SemaRef.CurContext->isDependentContext())
6861 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6862 << RHS->getSourceRange() << LCDecl;
6866 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6867 // Check incr-expr for canonical loop form and return true if it
6868 // does not conform.
6869 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6881 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6884 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6885 if (!ExprTemp->cleanupsHaveSideEffects())
6886 S = ExprTemp->getSubExpr();
6888 IncrementSrcRange = S->getSourceRange();
6889 S = S->IgnoreParens();
6890 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
6891 if (UO->isIncrementDecrementOp() &&
6892 getInitLCDecl(UO->getSubExpr()) == LCDecl)
6893 return setStep(SemaRef
6894 .ActOnIntegerConstant(UO->getBeginLoc(),
6895 (UO->isDecrementOp() ? -1 : 1))
6897 /*Subtract=*/false);
6898 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6899 switch (BO->getOpcode()) {
6902 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6903 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6906 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6907 return checkAndSetIncRHS(BO->getRHS());
6912 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6913 switch (CE->getOperator()) {
6916 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6917 return setStep(SemaRef
6918 .ActOnIntegerConstant(
6920 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6922 /*Subtract=*/false);
6926 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6927 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6930 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6931 return checkAndSetIncRHS(CE->getArg(1));
6937 if (dependent() || SemaRef.CurContext->isDependentContext())
6939 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6940 << S->getSourceRange() << LCDecl;
6945 tryBuildCapture(Sema &SemaRef, Expr *Capture,
6946 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6947 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
6949 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
6950 return SemaRef.PerformImplicitConversion(
6951 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
6952 /*AllowExplicit=*/true);
6953 auto I = Captures.find(Capture);
6954 if (I != Captures.end())
6955 return buildCapture(SemaRef, Capture, I->second);
6956 DeclRefExpr *Ref = nullptr;
6957 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
6958 Captures[Capture] = Ref;
6962 /// Calculate number of iterations, transforming to unsigned, if number of
6963 /// iterations may be larger than the original type.
6965 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
6966 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
6967 bool TestIsStrictOp, bool RoundToStep,
6968 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6969 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6970 if (!NewStep.isUsable())
6972 llvm::APSInt LRes, URes, SRes;
6973 bool IsLowerConst = Lower->isIntegerConstantExpr(LRes, SemaRef.Context);
6974 bool IsStepConst = Step->isIntegerConstantExpr(SRes, SemaRef.Context);
6975 bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
6976 ((!TestIsStrictOp && LRes.isNonNegative()) ||
6977 (TestIsStrictOp && LRes.isStrictlyPositive()));
6978 bool NeedToReorganize = false;
6979 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
6980 if (!NoNeedToConvert && IsLowerConst &&
6981 (TestIsStrictOp || (RoundToStep && IsStepConst))) {
6982 NoNeedToConvert = true;
6984 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
6985 ? LRes.getBitWidth()
6986 : SRes.getBitWidth();
6987 LRes = LRes.extend(BW + 1);
6988 LRes.setIsSigned(true);
6989 SRes = SRes.extend(BW + 1);
6990 SRes.setIsSigned(true);
6992 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
6993 LRes = LRes.trunc(BW);
6995 if (TestIsStrictOp) {
6996 unsigned BW = LRes.getBitWidth();
6997 LRes = LRes.extend(BW + 1);
6998 LRes.setIsSigned(true);
7001 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7002 // truncate to the original bitwidth.
7003 LRes = LRes.trunc(BW);
7005 NeedToReorganize = NoNeedToConvert;
7007 bool IsUpperConst = Upper->isIntegerConstantExpr(URes, SemaRef.Context);
7008 if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7009 (!RoundToStep || IsStepConst)) {
7010 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7011 : URes.getBitWidth();
7012 LRes = LRes.extend(BW + 1);
7013 LRes.setIsSigned(true);
7014 URes = URes.extend(BW + 1);
7015 URes.setIsSigned(true);
7017 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7018 NeedToReorganize = NoNeedToConvert;
7020 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7021 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7023 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7024 !LCTy->isDependentType() && LCTy->isIntegerType()) {
7025 QualType LowerTy = Lower->getType();
7026 QualType UpperTy = Upper->getType();
7027 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7028 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7029 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7030 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7031 QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7032 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7035 .PerformImplicitConversion(
7036 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7037 CastType, Sema::AA_Converting)
7039 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7040 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7043 if (!Lower || !Upper || NewStep.isInvalid())
7047 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7049 if (NeedToReorganize) {
7055 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7056 if (!Diff.isUsable())
7060 // Lower - Step [+ 1]
7062 Diff = SemaRef.BuildBinOp(
7063 S, DefaultLoc, BO_Add, Diff.get(),
7064 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7065 if (!Diff.isUsable())
7068 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7069 if (!Diff.isUsable())
7072 // Upper - (Lower - Step [+ 1]).
7073 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7074 if (!Diff.isUsable())
7077 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7079 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7080 // BuildBinOp already emitted error, this one is to point user to upper
7081 // and lower bound, and to tell what is passed to 'operator-'.
7082 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7083 << Upper->getSourceRange() << Lower->getSourceRange();
7087 if (!Diff.isUsable())
7090 // Upper - Lower [- 1]
7092 Diff = SemaRef.BuildBinOp(
7093 S, DefaultLoc, BO_Sub, Diff.get(),
7094 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7095 if (!Diff.isUsable())
7099 // Upper - Lower [- 1] + Step
7101 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7102 if (!Diff.isUsable())
7107 // Parentheses (for dumping/debugging purposes only).
7108 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7109 if (!Diff.isUsable())
7112 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
7113 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
7114 if (!Diff.isUsable())
7120 /// Build the expression to calculate the number of iterations.
7121 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
7122 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7123 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7124 QualType VarType = LCDecl->getType().getNonReferenceType();
7125 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7126 !SemaRef.getLangOpts().CPlusPlus)
7130 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
7131 // max(LB(MinVal), LB(MaxVal))
7132 if (InitDependOnLC) {
7133 const LoopIterationSpace &IS =
7134 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7135 InitDependOnLC.getValueOr(
7136 CondDependOnLC.getValueOr(0))];
7137 if (!IS.MinValue || !IS.MaxValue)
7140 ExprResult MinValue =
7141 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7142 if (!MinValue.isUsable())
7145 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7146 IS.CounterVar, MinValue.get());
7147 if (!LBMinVal.isUsable())
7149 // OuterVar = Min, LBVal
7151 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
7152 if (!LBMinVal.isUsable())
7154 // (OuterVar = Min, LBVal)
7155 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
7156 if (!LBMinVal.isUsable())
7160 ExprResult MaxValue =
7161 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7162 if (!MaxValue.isUsable())
7165 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7166 IS.CounterVar, MaxValue.get());
7167 if (!LBMaxVal.isUsable())
7169 // OuterVar = Max, LBVal
7171 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
7172 if (!LBMaxVal.isUsable())
7174 // (OuterVar = Max, LBVal)
7175 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
7176 if (!LBMaxVal.isUsable())
7179 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
7180 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
7181 if (!LBMin || !LBMax)
7183 // LB(MinVal) < LB(MaxVal)
7184 ExprResult MinLessMaxRes =
7185 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
7186 if (!MinLessMaxRes.isUsable())
7189 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
7192 if (TestIsLessOp.getValue()) {
7193 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
7195 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7196 MinLessMax, LBMin, LBMax);
7197 if (!MinLB.isUsable())
7199 LBVal = MinLB.get();
7201 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
7203 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
7204 MinLessMax, LBMax, LBMin);
7205 if (!MaxLB.isUsable())
7207 LBVal = MaxLB.get();
7210 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
7211 // min(UB(MinVal), UB(MaxVal))
7212 if (CondDependOnLC) {
7213 const LoopIterationSpace &IS =
7214 ResultIterSpaces[ResultIterSpaces.size() - 1 -
7215 InitDependOnLC.getValueOr(
7216 CondDependOnLC.getValueOr(0))];
7217 if (!IS.MinValue || !IS.MaxValue)
7220 ExprResult MinValue =
7221 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
7222 if (!MinValue.isUsable())
7225 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7226 IS.CounterVar, MinValue.get());
7227 if (!UBMinVal.isUsable())
7229 // OuterVar = Min, UBVal
7231 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
7232 if (!UBMinVal.isUsable())
7234 // (OuterVar = Min, UBVal)
7235 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
7236 if (!UBMinVal.isUsable())
7240 ExprResult MaxValue =
7241 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
7242 if (!MaxValue.isUsable())
7245 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
7246 IS.CounterVar, MaxValue.get());
7247 if (!UBMaxVal.isUsable())
7249 // OuterVar = Max, UBVal
7251 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
7252 if (!UBMaxVal.isUsable())
7254 // (OuterVar = Max, UBVal)
7255 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
7256 if (!UBMaxVal.isUsable())
7259 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
7260 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
7261 if (!UBMin || !UBMax)
7263 // UB(MinVal) > UB(MaxVal)
7264 ExprResult MinGreaterMaxRes =
7265 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
7266 if (!MinGreaterMaxRes.isUsable())
7268 Expr *MinGreaterMax =
7269 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
7272 if (TestIsLessOp.getValue()) {
7273 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
7275 ExprResult MaxUB = SemaRef.ActOnConditionalOp(
7276 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
7277 if (!MaxUB.isUsable())
7279 UBVal = MaxUB.get();
7281 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
7283 ExprResult MinUB = SemaRef.ActOnConditionalOp(
7284 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
7285 if (!MinUB.isUsable())
7287 UBVal = MinUB.get();
7290 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
7291 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
7292 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
7293 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
7294 if (!Upper || !Lower)
7298 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7299 TestIsStrictOp, /*RoundToStep=*/true, Captures);
7300 if (!Diff.isUsable())
7303 // OpenMP runtime requires 32-bit or 64-bit loop variables.
7304 QualType Type = Diff.get()->getType();
7305 ASTContext &C = SemaRef.Context;
7306 bool UseVarType = VarType->hasIntegerRepresentation() &&
7307 C.getTypeSize(Type) > C.getTypeSize(VarType);
7308 if (!Type->isIntegerType() || UseVarType) {
7310 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
7311 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
7312 : Type->hasSignedIntegerRepresentation();
7313 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
7314 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
7315 Diff = SemaRef.PerformImplicitConversion(
7316 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
7317 if (!Diff.isUsable())
7322 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
7323 if (NewSize != C.getTypeSize(Type)) {
7324 if (NewSize < C.getTypeSize(Type)) {
7325 assert(NewSize == 64 && "incorrect loop var size");
7326 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
7327 << InitSrcRange << ConditionSrcRange;
7329 QualType NewType = C.getIntTypeForBitwidth(
7330 NewSize, Type->hasSignedIntegerRepresentation() ||
7331 C.getTypeSize(Type) < NewSize);
7332 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
7333 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
7334 Sema::AA_Converting, true);
7335 if (!Diff.isUsable())
7344 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
7345 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7346 // Do not build for iterators, they cannot be used in non-rectangular loop
7348 if (LCDecl->getType()->isRecordType())
7349 return std::make_pair(nullptr, nullptr);
7350 // If we subtract, the min is in the condition, otherwise the min is in the
7352 Expr *MinExpr = nullptr;
7353 Expr *MaxExpr = nullptr;
7354 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
7355 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
7356 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
7357 : CondDependOnLC.hasValue();
7358 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
7359 : InitDependOnLC.hasValue();
7361 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
7363 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
7364 if (!Upper || !Lower)
7365 return std::make_pair(nullptr, nullptr);
7367 if (TestIsLessOp.getValue())
7372 // Build minimum/maximum value based on number of iterations.
7373 QualType VarType = LCDecl->getType().getNonReferenceType();
7376 calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
7377 TestIsStrictOp, /*RoundToStep=*/false, Captures);
7378 if (!Diff.isUsable())
7379 return std::make_pair(nullptr, nullptr);
7381 // ((Upper - Lower [- 1]) / Step) * Step
7382 // Parentheses (for dumping/debugging purposes only).
7383 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7384 if (!Diff.isUsable())
7385 return std::make_pair(nullptr, nullptr);
7387 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7388 if (!NewStep.isUsable())
7389 return std::make_pair(nullptr, nullptr);
7390 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
7391 if (!Diff.isUsable())
7392 return std::make_pair(nullptr, nullptr);
7394 // Parentheses (for dumping/debugging purposes only).
7395 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7396 if (!Diff.isUsable())
7397 return std::make_pair(nullptr, nullptr);
7399 // Convert to the ptrdiff_t, if original type is pointer.
7400 if (VarType->isAnyPointerType() &&
7401 !SemaRef.Context.hasSameType(
7402 Diff.get()->getType(),
7403 SemaRef.Context.getUnsignedPointerDiffType())) {
7404 Diff = SemaRef.PerformImplicitConversion(
7405 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
7406 Sema::AA_Converting, /*AllowExplicit=*/true);
7408 if (!Diff.isUsable())
7409 return std::make_pair(nullptr, nullptr);
7411 if (TestIsLessOp.getValue()) {
7413 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
7414 Diff = SemaRef.BuildBinOp(
7415 S, DefaultLoc, BO_Add,
7416 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
7418 if (!Diff.isUsable())
7419 return std::make_pair(nullptr, nullptr);
7422 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
7423 Diff = SemaRef.BuildBinOp(
7424 S, DefaultLoc, BO_Sub,
7425 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7427 if (!Diff.isUsable())
7428 return std::make_pair(nullptr, nullptr);
7431 // Convert to the original type.
7432 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
7433 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
7434 Sema::AA_Converting,
7435 /*AllowExplicit=*/true);
7436 if (!Diff.isUsable())
7437 return std::make_pair(nullptr, nullptr);
7439 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
7440 if (!Diff.isUsable())
7441 return std::make_pair(nullptr, nullptr);
7443 if (TestIsLessOp.getValue())
7444 MaxExpr = Diff.get();
7446 MinExpr = Diff.get();
7448 return std::make_pair(MinExpr, MaxExpr);
7451 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
7452 if (InitDependOnLC || CondDependOnLC)
7457 Expr *OpenMPIterationSpaceChecker::buildPreCond(
7458 Scope *S, Expr *Cond,
7459 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
7460 // Do not build a precondition when the condition/initialization is dependent
7461 // to prevent pessimistic early loop exit.
7462 // TODO: this can be improved by calculating min/max values but not sure that
7463 // it will be very effective.
7464 if (CondDependOnLC || InitDependOnLC)
7465 return SemaRef.PerformImplicitConversion(
7466 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
7467 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7468 /*AllowExplicit=*/true).get();
7470 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
7471 Sema::TentativeAnalysisScope Trap(SemaRef);
7473 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
7474 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
7475 if (!NewLB.isUsable() || !NewUB.isUsable())
7478 ExprResult CondExpr =
7479 SemaRef.BuildBinOp(S, DefaultLoc,
7480 TestIsLessOp.getValue() ?
7481 (TestIsStrictOp ? BO_LT : BO_LE) :
7482 (TestIsStrictOp ? BO_GT : BO_GE),
7483 NewLB.get(), NewUB.get());
7484 if (CondExpr.isUsable()) {
7485 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
7486 SemaRef.Context.BoolTy))
7487 CondExpr = SemaRef.PerformImplicitConversion(
7488 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
7489 /*AllowExplicit=*/true);
7492 // Otherwise use original loop condition and evaluate it in runtime.
7493 return CondExpr.isUsable() ? CondExpr.get() : Cond;
7496 /// Build reference expression to the counter be used for codegen.
7497 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
7498 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7499 DSAStackTy &DSA) const {
7500 auto *VD = dyn_cast<VarDecl>(LCDecl);
7502 VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
7503 DeclRefExpr *Ref = buildDeclRefExpr(
7504 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
7505 const DSAStackTy::DSAVarData Data =
7506 DSA.getTopDSA(LCDecl, /*FromParent=*/false);
7507 // If the loop control decl is explicitly marked as private, do not mark it
7508 // as captured again.
7509 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
7510 Captures.insert(std::make_pair(LCRef, Ref));
7513 return cast<DeclRefExpr>(LCRef);
7516 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
7517 if (LCDecl && !LCDecl->isInvalidDecl()) {
7518 QualType Type = LCDecl->getType().getNonReferenceType();
7519 VarDecl *PrivateVar = buildVarDecl(
7520 SemaRef, DefaultLoc, Type, LCDecl->getName(),
7521 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
7522 isa<VarDecl>(LCDecl)
7523 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
7525 if (PrivateVar->isInvalidDecl())
7527 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
7532 /// Build initialization of the counter to be used for codegen.
7533 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
7535 /// Build step of the counter be used for codegen.
7536 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
7538 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
7539 Scope *S, Expr *Counter,
7540 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
7541 Expr *Inc, OverloadedOperatorKind OOK) {
7542 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
7546 assert((OOK == OO_Plus || OOK == OO_Minus) &&
7547 "Expected only + or - operations for depend clauses.");
7548 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
7549 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
7553 QualType VarType = LCDecl->getType().getNonReferenceType();
7554 if (!VarType->isIntegerType() && !VarType->isPointerType() &&
7555 !SemaRef.getLangOpts().CPlusPlus)
7558 Expr *Upper = TestIsLessOp.getValue()
7560 : tryBuildCapture(SemaRef, LB, Captures).get();
7561 Expr *Lower = TestIsLessOp.getValue()
7562 ? tryBuildCapture(SemaRef, LB, Captures).get()
7564 if (!Upper || !Lower)
7567 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
7568 Step, VarType, /*TestIsStrictOp=*/false,
7569 /*RoundToStep=*/false, Captures);
7570 if (!Diff.isUsable())
7577 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
7578 assert(getLangOpts().OpenMP && "OpenMP is not active.");
7579 assert(Init && "Expected loop in canonical form.");
7580 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
7581 if (AssociatedLoops > 0 &&
7582 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
7583 DSAStack->loopStart();
7584 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
7585 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
7586 if (ValueDecl *D = ISC.getLoopDecl()) {
7587 auto *VD = dyn_cast<VarDecl>(D);
7588 DeclRefExpr *PrivateRef = nullptr;
7590 if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
7593 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
7594 /*WithInit=*/false);
7595 VD = cast<VarDecl>(PrivateRef->getDecl());
7598 DSAStack->addLoopControlVariable(D, VD);
7599 const Decl *LD = DSAStack->getPossiblyLoopCunter();
7600 if (LD != D->getCanonicalDecl()) {
7601 DSAStack->resetPossibleLoopCounter();
7602 if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
7603 MarkDeclarationsReferencedInExpr(
7604 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
7605 Var->getType().getNonLValueExprType(Context),
7606 ForLoc, /*RefersToCapture=*/true));
7608 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
7609 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
7610 // Referenced in a Construct, C/C++]. The loop iteration variable in the
7611 // associated for-loop of a simd construct with just one associated
7612 // for-loop may be listed in a linear clause with a constant-linear-step
7613 // that is the increment of the associated for-loop. The loop iteration
7614 // variable(s) in the associated for-loop(s) of a for or parallel for
7615 // construct may be listed in a private or lastprivate clause.
7616 DSAStackTy::DSAVarData DVar =
7617 DSAStack->getTopDSA(D, /*FromParent=*/false);
7618 // If LoopVarRefExpr is nullptr it means the corresponding loop variable
7619 // is declared in the loop and it is predetermined as a private.
7620 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
7621 OpenMPClauseKind PredeterminedCKind =
7622 isOpenMPSimdDirective(DKind)
7623 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
7625 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7626 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
7627 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
7628 DVar.CKind != OMPC_private))) ||
7629 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
7630 DKind == OMPD_master_taskloop ||
7631 DKind == OMPD_parallel_master_taskloop ||
7632 isOpenMPDistributeDirective(DKind)) &&
7633 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
7634 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
7635 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
7636 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
7637 << getOpenMPClauseName(DVar.CKind)
7638 << getOpenMPDirectiveName(DKind)
7639 << getOpenMPClauseName(PredeterminedCKind);
7640 if (DVar.RefExpr == nullptr)
7641 DVar.CKind = PredeterminedCKind;
7642 reportOriginalDsa(*this, DSAStack, D, DVar,
7643 /*IsLoopIterVar=*/true);
7644 } else if (LoopDeclRefExpr) {
7645 // Make the loop iteration variable private (for worksharing
7646 // constructs), linear (for simd directives with the only one
7647 // associated loop) or lastprivate (for simd directives with several
7648 // collapsed or ordered loops).
7649 if (DVar.CKind == OMPC_unknown)
7650 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
7655 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
7659 /// Called on a for stmt to check and extract its iteration space
7660 /// for further processing (such as collapsing).
7661 static bool checkOpenMPIterationSpace(
7662 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
7663 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
7664 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
7665 Expr *OrderedLoopCountExpr,
7666 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7667 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
7668 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7669 // OpenMP [2.9.1, Canonical Loop Form]
7670 // for (init-expr; test-expr; incr-expr) structured-block
7671 // for (range-decl: range-expr) structured-block
7672 auto *For = dyn_cast_or_null<ForStmt>(S);
7673 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
7674 // Ranged for is supported only in OpenMP 5.0.
7675 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
7676 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
7677 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
7678 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
7679 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
7680 if (TotalNestedLoopCount > 1) {
7681 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
7682 SemaRef.Diag(DSA.getConstructLoc(),
7683 diag::note_omp_collapse_ordered_expr)
7684 << 2 << CollapseLoopCountExpr->getSourceRange()
7685 << OrderedLoopCountExpr->getSourceRange();
7686 else if (CollapseLoopCountExpr)
7687 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7688 diag::note_omp_collapse_ordered_expr)
7689 << 0 << CollapseLoopCountExpr->getSourceRange();
7691 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7692 diag::note_omp_collapse_ordered_expr)
7693 << 1 << OrderedLoopCountExpr->getSourceRange();
7697 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
7700 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
7701 For ? For->getForLoc() : CXXFor->getForLoc());
7704 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
7705 if (ISC.checkAndSetInit(Init))
7708 bool HasErrors = false;
7710 // Check loop variable's type.
7711 if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
7712 // OpenMP [2.6, Canonical Loop Form]
7713 // Var is one of the following:
7714 // A variable of signed or unsigned integer type.
7715 // For C++, a variable of a random access iterator type.
7716 // For C, a variable of a pointer type.
7717 QualType VarType = LCDecl->getType().getNonReferenceType();
7718 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
7719 !VarType->isPointerType() &&
7720 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
7721 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
7722 << SemaRef.getLangOpts().CPlusPlus;
7726 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
7728 // The loop iteration variable(s) in the associated for-loop(s) of a for or
7729 // parallel for construct is (are) private.
7730 // The loop iteration variable in the associated for-loop of a simd
7731 // construct with just one associated for-loop is linear with a
7732 // constant-linear-step that is the increment of the associated for-loop.
7733 // Exclude loop var from the list of variables with implicitly defined data
7734 // sharing attributes.
7735 VarsWithImplicitDSA.erase(LCDecl);
7737 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
7740 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7743 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7746 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7749 // Build the loop's iteration space representation.
7750 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7751 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7752 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7753 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7754 (isOpenMPWorksharingDirective(DKind) ||
7755 isOpenMPTaskLoopDirective(DKind) ||
7756 isOpenMPDistributeDirective(DKind)),
7758 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7759 ISC.buildCounterVar(Captures, DSA);
7760 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7761 ISC.buildPrivateCounterVar();
7762 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7763 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7764 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7765 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7766 ISC.getConditionSrcRange();
7767 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7768 ISC.getIncrementSrcRange();
7769 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7770 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7771 ISC.isStrictTestOp();
7772 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7773 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7774 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7775 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7776 ISC.buildFinalCondition(DSA.getCurScope());
7777 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7778 ISC.doesInitDependOnLC();
7779 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7780 ISC.doesCondDependOnLC();
7781 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7782 ISC.getLoopDependentIdx();
7785 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7786 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7787 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7788 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7789 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7790 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7791 if (!HasErrors && DSA.isOrderedRegion()) {
7792 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7793 if (CurrentNestedLoopCount <
7794 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7795 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7796 CurrentNestedLoopCount,
7797 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7798 DSA.getOrderedRegionParam().second->setLoopCounter(
7799 CurrentNestedLoopCount,
7800 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7803 for (auto &Pair : DSA.getDoacrossDependClauses()) {
7804 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7805 // Erroneous case - clause has some problems.
7808 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7809 Pair.second.size() <= CurrentNestedLoopCount) {
7810 // Erroneous case - clause has some problems.
7811 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7815 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7816 CntValue = ISC.buildOrderedLoopData(
7818 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7819 Pair.first->getDependencyLoc());
7821 CntValue = ISC.buildOrderedLoopData(
7823 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7824 Pair.first->getDependencyLoc(),
7825 Pair.second[CurrentNestedLoopCount].first,
7826 Pair.second[CurrentNestedLoopCount].second);
7827 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7834 /// Build 'VarRef = Start.
7836 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7837 ExprResult Start, bool IsNonRectangularLB,
7838 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7839 // Build 'VarRef = Start.
7840 ExprResult NewStart = IsNonRectangularLB
7842 : tryBuildCapture(SemaRef, Start.get(), Captures);
7843 if (!NewStart.isUsable())
7845 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7846 VarRef.get()->getType())) {
7847 NewStart = SemaRef.PerformImplicitConversion(
7848 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7849 /*AllowExplicit=*/true);
7850 if (!NewStart.isUsable())
7855 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7859 /// Build 'VarRef = Start + Iter * Step'.
7860 static ExprResult buildCounterUpdate(
7861 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7862 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7863 bool IsNonRectangularLB,
7864 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7865 // Add parentheses (for debugging purposes only).
7866 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7867 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7871 ExprResult NewStep = Step;
7873 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
7874 if (NewStep.isInvalid())
7877 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
7878 if (!Update.isUsable())
7881 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
7882 // 'VarRef = Start (+|-) Iter * Step'.
7883 if (!Start.isUsable())
7885 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
7886 if (!NewStart.isUsable())
7888 if (Captures && !IsNonRectangularLB)
7889 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
7890 if (NewStart.isInvalid())
7893 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
7894 ExprResult SavedUpdate = Update;
7895 ExprResult UpdateVal;
7896 if (VarRef.get()->getType()->isOverloadableType() ||
7897 NewStart.get()->getType()->isOverloadableType() ||
7898 Update.get()->getType()->isOverloadableType()) {
7899 Sema::TentativeAnalysisScope Trap(SemaRef);
7902 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7903 if (Update.isUsable()) {
7905 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7906 VarRef.get(), SavedUpdate.get());
7907 if (UpdateVal.isUsable()) {
7908 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
7914 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
7915 if (!Update.isUsable() || !UpdateVal.isUsable()) {
7916 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7917 NewStart.get(), SavedUpdate.get());
7918 if (!Update.isUsable())
7921 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
7922 VarRef.get()->getType())) {
7923 Update = SemaRef.PerformImplicitConversion(
7924 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
7925 if (!Update.isUsable())
7929 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
7934 /// Convert integer expression \a E to make it have at least \a Bits
7936 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
7939 ASTContext &C = SemaRef.Context;
7940 QualType OldType = E->getType();
7941 unsigned HasBits = C.getTypeSize(OldType);
7942 if (HasBits >= Bits)
7943 return ExprResult(E);
7944 // OK to convert to signed, because new type has more bits than old.
7945 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
7946 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
7950 /// Check if the given expression \a E is a constant integer that fits
7951 /// into \a Bits bits.
7952 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
7955 llvm::APSInt Result;
7956 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
7957 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
7961 /// Build preinits statement for the given declarations.
7962 static Stmt *buildPreInits(ASTContext &Context,
7963 MutableArrayRef<Decl *> PreInits) {
7964 if (!PreInits.empty()) {
7965 return new (Context) DeclStmt(
7966 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
7967 SourceLocation(), SourceLocation());
7972 /// Build preinits statement for the given declarations.
7974 buildPreInits(ASTContext &Context,
7975 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7976 if (!Captures.empty()) {
7977 SmallVector<Decl *, 16> PreInits;
7978 for (const auto &Pair : Captures)
7979 PreInits.push_back(Pair.second->getDecl());
7980 return buildPreInits(Context, PreInits);
7985 /// Build postupdate expression for the given list of postupdates expressions.
7986 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
7987 Expr *PostUpdate = nullptr;
7988 if (!PostUpdates.empty()) {
7989 for (Expr *E : PostUpdates) {
7990 Expr *ConvE = S.BuildCStyleCastExpr(
7992 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
7995 PostUpdate = PostUpdate
7996 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8005 /// Called on a for stmt to check itself and nested loops (if any).
8006 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8007 /// number of collapsed loops otherwise.
8009 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8010 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8012 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8013 OMPLoopDirective::HelperExprs &Built) {
8014 unsigned NestedLoopCount = 1;
8015 if (CollapseLoopCountExpr) {
8016 // Found 'collapse' clause - calculate collapse number.
8017 Expr::EvalResult Result;
8018 if (!CollapseLoopCountExpr->isValueDependent() &&
8019 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8020 NestedLoopCount = Result.Val.getInt().getLimitedValue();
8022 Built.clear(/*Size=*/1);
8026 unsigned OrderedLoopCount = 1;
8027 if (OrderedLoopCountExpr) {
8028 // Found 'ordered' clause - calculate collapse number.
8029 Expr::EvalResult EVResult;
8030 if (!OrderedLoopCountExpr->isValueDependent() &&
8031 OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8032 SemaRef.getASTContext())) {
8033 llvm::APSInt Result = EVResult.Val.getInt();
8034 if (Result.getLimitedValue() < NestedLoopCount) {
8035 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8036 diag::err_omp_wrong_ordered_loop_count)
8037 << OrderedLoopCountExpr->getSourceRange();
8038 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8039 diag::note_collapse_loop_count)
8040 << CollapseLoopCountExpr->getSourceRange();
8042 OrderedLoopCount = Result.getLimitedValue();
8044 Built.clear(/*Size=*/1);
8048 // This is helper routine for loop directives (e.g., 'for', 'simd',
8049 // 'for simd', etc.).
8050 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8051 SmallVector<LoopIterationSpace, 4> IterSpaces(
8052 std::max(OrderedLoopCount, NestedLoopCount));
8053 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
8054 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8055 if (checkOpenMPIterationSpace(
8056 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8057 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8058 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8060 // Move on to the next nested for loop, or to the loop body.
8061 // OpenMP [2.8.1, simd construct, Restrictions]
8062 // All loops associated with the construct must be perfectly nested; that
8063 // is, there must be no intervening code nor any OpenMP directive between
8065 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8066 CurStmt = For->getBody();
8068 assert(isa<CXXForRangeStmt>(CurStmt) &&
8069 "Expected canonical for or range-based for loops.");
8070 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8072 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8073 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8075 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
8076 if (checkOpenMPIterationSpace(
8077 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8078 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
8079 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
8081 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
8082 // Handle initialization of captured loop iterator variables.
8083 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8084 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8085 Captures[DRE] = DRE;
8088 // Move on to the next nested for loop, or to the loop body.
8089 // OpenMP [2.8.1, simd construct, Restrictions]
8090 // All loops associated with the construct must be perfectly nested; that
8091 // is, there must be no intervening code nor any OpenMP directive between
8093 if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
8094 CurStmt = For->getBody();
8096 assert(isa<CXXForRangeStmt>(CurStmt) &&
8097 "Expected canonical for or range-based for loops.");
8098 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
8100 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop(
8101 CurStmt, SemaRef.LangOpts.OpenMP >= 50);
8104 Built.clear(/* size */ NestedLoopCount);
8106 if (SemaRef.CurContext->isDependentContext())
8107 return NestedLoopCount;
8109 // An example of what is generated for the following code:
8111 // #pragma omp simd collapse(2) ordered(2)
8112 // for (i = 0; i < NI; ++i)
8113 // for (k = 0; k < NK; ++k)
8114 // for (j = J0; j < NJ; j+=2) {
8118 // We generate the code below.
8119 // Note: the loop body may be outlined in CodeGen.
8120 // Note: some counters may be C++ classes, operator- is used to find number of
8121 // iterations and operator+= to calculate counter value.
8122 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8123 // or i64 is currently supported).
8125 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8126 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8127 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8128 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8129 // // similar updates for vars in clauses (e.g. 'linear')
8130 // <loop body (using local i and j)>
8132 // i = NI; // assign final values of counters
8136 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
8137 // the iteration counts of the collapsed for loops.
8138 // Precondition tests if there is at least one iteration (all conditions are
8140 auto PreCond = ExprResult(IterSpaces[0].PreCond);
8141 Expr *N0 = IterSpaces[0].NumIterations;
8142 ExprResult LastIteration32 =
8143 widenIterationCount(/*Bits=*/32,
8145 .PerformImplicitConversion(
8146 N0->IgnoreImpCasts(), N0->getType(),
8147 Sema::AA_Converting, /*AllowExplicit=*/true)
8150 ExprResult LastIteration64 = widenIterationCount(
8153 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
8154 Sema::AA_Converting,
8155 /*AllowExplicit=*/true)
8159 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
8160 return NestedLoopCount;
8162 ASTContext &C = SemaRef.Context;
8163 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
8165 Scope *CurScope = DSA.getCurScope();
8166 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
8167 if (PreCond.isUsable()) {
8169 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
8170 PreCond.get(), IterSpaces[Cnt].PreCond);
8172 Expr *N = IterSpaces[Cnt].NumIterations;
8173 SourceLocation Loc = N->getExprLoc();
8174 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
8175 if (LastIteration32.isUsable())
8176 LastIteration32 = SemaRef.BuildBinOp(
8177 CurScope, Loc, BO_Mul, LastIteration32.get(),
8179 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8180 Sema::AA_Converting,
8181 /*AllowExplicit=*/true)
8183 if (LastIteration64.isUsable())
8184 LastIteration64 = SemaRef.BuildBinOp(
8185 CurScope, Loc, BO_Mul, LastIteration64.get(),
8187 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
8188 Sema::AA_Converting,
8189 /*AllowExplicit=*/true)
8193 // Choose either the 32-bit or 64-bit version.
8194 ExprResult LastIteration = LastIteration64;
8195 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
8196 (LastIteration32.isUsable() &&
8197 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
8198 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
8201 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
8202 LastIteration64.get(), SemaRef))))
8203 LastIteration = LastIteration32;
8204 QualType VType = LastIteration.get()->getType();
8205 QualType RealVType = VType;
8206 QualType StrideVType = VType;
8207 if (isOpenMPTaskLoopDirective(DKind)) {
8209 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
8211 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
8214 if (!LastIteration.isUsable())
8217 // Save the number of iterations.
8218 ExprResult NumIterations = LastIteration;
8220 LastIteration = SemaRef.BuildBinOp(
8221 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
8222 LastIteration.get(),
8223 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8224 if (!LastIteration.isUsable())
8228 // Calculate the last iteration number beforehand instead of doing this on
8229 // each iteration. Do not do this if the number of iterations may be kfold-ed.
8230 llvm::APSInt Result;
8232 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
8233 ExprResult CalcLastIteration;
8235 ExprResult SaveRef =
8236 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
8237 LastIteration = SaveRef;
8239 // Prepare SaveRef + 1.
8240 NumIterations = SemaRef.BuildBinOp(
8241 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
8242 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8243 if (!NumIterations.isUsable())
8247 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
8249 // Build variables passed into runtime, necessary for worksharing directives.
8250 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
8251 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8252 isOpenMPDistributeDirective(DKind)) {
8253 // Lower bound variable, initialized with zero.
8254 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
8255 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
8256 SemaRef.AddInitializerToDecl(LBDecl,
8257 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8258 /*DirectInit*/ false);
8260 // Upper bound variable, initialized with last iteration number.
8261 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
8262 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
8263 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
8264 /*DirectInit*/ false);
8266 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
8267 // This will be used to implement clause 'lastprivate'.
8268 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
8269 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
8270 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
8271 SemaRef.AddInitializerToDecl(ILDecl,
8272 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8273 /*DirectInit*/ false);
8275 // Stride variable returned by runtime (we initialize it to 1 by default).
8277 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
8278 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
8279 SemaRef.AddInitializerToDecl(STDecl,
8280 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
8281 /*DirectInit*/ false);
8283 // Build expression: UB = min(UB, LastIteration)
8284 // It is necessary for CodeGen of directives with static scheduling.
8285 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
8286 UB.get(), LastIteration.get());
8287 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8288 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
8289 LastIteration.get(), UB.get());
8290 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
8292 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
8294 // If we have a combined directive that combines 'distribute', 'for' or
8295 // 'simd' we need to be able to access the bounds of the schedule of the
8296 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
8297 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
8298 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8299 // Lower bound variable, initialized with zero.
8300 VarDecl *CombLBDecl =
8301 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
8302 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
8303 SemaRef.AddInitializerToDecl(
8304 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
8305 /*DirectInit*/ false);
8307 // Upper bound variable, initialized with last iteration number.
8308 VarDecl *CombUBDecl =
8309 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
8310 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
8311 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
8312 /*DirectInit*/ false);
8314 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
8315 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
8316 ExprResult CombCondOp =
8317 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
8318 LastIteration.get(), CombUB.get());
8319 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
8322 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
8324 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
8325 // We expect to have at least 2 more parameters than the 'parallel'
8326 // directive does - the lower and upper bounds of the previous schedule.
8327 assert(CD->getNumParams() >= 4 &&
8328 "Unexpected number of parameters in loop combined directive");
8330 // Set the proper type for the bounds given what we learned from the
8332 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
8333 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
8335 // Previous lower and upper bounds are obtained from the region
8338 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
8340 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
8344 // Build the iteration variable and its initialization before loop.
8346 ExprResult Init, CombInit;
8348 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
8349 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
8351 (isOpenMPWorksharingDirective(DKind) ||
8352 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8354 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8355 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
8356 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
8358 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8360 (isOpenMPWorksharingDirective(DKind) ||
8361 isOpenMPTaskLoopDirective(DKind) ||
8362 isOpenMPDistributeDirective(DKind))
8364 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
8366 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
8368 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
8372 bool UseStrictCompare =
8373 RealVType->hasUnsignedIntegerRepresentation() &&
8374 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
8375 return LIS.IsStrictCompare;
8377 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
8378 // unsigned IV)) for worksharing loops.
8379 SourceLocation CondLoc = AStmt->getBeginLoc();
8380 Expr *BoundUB = UB.get();
8381 if (UseStrictCompare) {
8384 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
8385 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8388 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
8391 (isOpenMPWorksharingDirective(DKind) ||
8392 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
8393 ? SemaRef.BuildBinOp(CurScope, CondLoc,
8394 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
8396 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8397 NumIterations.get());
8398 ExprResult CombDistCond;
8399 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8400 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
8401 NumIterations.get());
8404 ExprResult CombCond;
8405 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8406 Expr *BoundCombUB = CombUB.get();
8407 if (UseStrictCompare) {
8411 CurScope, CondLoc, BO_Add, BoundCombUB,
8412 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8415 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
8419 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8420 IV.get(), BoundCombUB);
8422 // Loop increment (IV = IV + 1)
8423 SourceLocation IncLoc = AStmt->getBeginLoc();
8425 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
8426 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
8427 if (!Inc.isUsable())
8429 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
8430 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
8431 if (!Inc.isUsable())
8434 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
8435 // Used for directives with static scheduling.
8436 // In combined construct, add combined version that use CombLB and CombUB
8437 // base variables for the update
8438 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
8439 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
8440 isOpenMPDistributeDirective(DKind)) {
8442 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
8443 if (!NextLB.isUsable())
8447 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
8449 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
8450 if (!NextLB.isUsable())
8453 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
8454 if (!NextUB.isUsable())
8458 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
8460 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
8461 if (!NextUB.isUsable())
8463 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8465 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
8466 if (!NextLB.isUsable())
8469 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
8471 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
8472 /*DiscardedValue*/ false);
8473 if (!CombNextLB.isUsable())
8477 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
8478 if (!CombNextUB.isUsable())
8481 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
8483 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
8484 /*DiscardedValue*/ false);
8485 if (!CombNextUB.isUsable())
8490 // Create increment expression for distribute loop when combined in a same
8491 // directive with for as IV = IV + ST; ensure upper bound expression based
8492 // on PrevUB instead of NumIterations - used to implement 'for' when found
8493 // in combination with 'distribute', like in 'distribute parallel for'
8494 SourceLocation DistIncLoc = AStmt->getBeginLoc();
8495 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
8496 if (isOpenMPLoopBoundSharingDirective(DKind)) {
8497 DistCond = SemaRef.BuildBinOp(
8498 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
8499 assert(DistCond.isUsable() && "distribute cond expr was not built");
8502 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
8503 assert(DistInc.isUsable() && "distribute inc expr was not built");
8504 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
8507 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
8508 assert(DistInc.isUsable() && "distribute inc expr was not built");
8510 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
8512 SourceLocation DistEUBLoc = AStmt->getBeginLoc();
8513 ExprResult IsUBGreater =
8514 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
8515 ExprResult CondOp = SemaRef.ActOnConditionalOp(
8516 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
8517 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
8520 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
8522 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
8523 // parallel for is in combination with a distribute directive with
8524 // schedule(static, 1)
8525 Expr *BoundPrevUB = PrevUB.get();
8526 if (UseStrictCompare) {
8530 CurScope, CondLoc, BO_Add, BoundPrevUB,
8531 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
8534 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
8538 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
8539 IV.get(), BoundPrevUB);
8542 // Build updates and final values of the loop counters.
8543 bool HasErrors = false;
8544 Built.Counters.resize(NestedLoopCount);
8545 Built.Inits.resize(NestedLoopCount);
8546 Built.Updates.resize(NestedLoopCount);
8547 Built.Finals.resize(NestedLoopCount);
8548 Built.DependentCounters.resize(NestedLoopCount);
8549 Built.DependentInits.resize(NestedLoopCount);
8550 Built.FinalsConditions.resize(NestedLoopCount);
8552 // We implement the following algorithm for obtaining the
8553 // original loop iteration variable values based on the
8554 // value of the collapsed loop iteration variable IV.
8556 // Let n+1 be the number of collapsed loops in the nest.
8557 // Iteration variables (I0, I1, .... In)
8558 // Iteration counts (N0, N1, ... Nn)
8562 // To compute Ik for loop k, 0 <= k <= n, generate:
8563 // Prod = N(k+1) * N(k+2) * ... * Nn;
8565 // Acc -= Ik * Prod;
8567 ExprResult Acc = IV;
8568 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
8569 LoopIterationSpace &IS = IterSpaces[Cnt];
8570 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
8575 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
8576 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
8577 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
8578 IterSpaces[K].NumIterations);
8580 // Iter = Acc / Prod
8581 // If there is at least one more inner loop to avoid
8582 // multiplication by 1.
8583 if (Cnt + 1 < NestedLoopCount)
8584 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
8585 Acc.get(), Prod.get());
8588 if (!Iter.isUsable()) {
8594 // Acc -= Iter * Prod
8595 // Check if there is at least one more inner loop to avoid
8596 // multiplication by 1.
8597 if (Cnt + 1 < NestedLoopCount)
8598 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
8599 Iter.get(), Prod.get());
8602 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
8603 Acc.get(), Prod.get());
8605 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
8606 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
8607 DeclRefExpr *CounterVar = buildDeclRefExpr(
8608 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
8609 /*RefersToCapture=*/true);
8611 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
8612 IS.CounterInit, IS.IsNonRectangularLB, Captures);
8613 if (!Init.isUsable()) {
8617 ExprResult Update = buildCounterUpdate(
8618 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
8619 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
8620 if (!Update.isUsable()) {
8625 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
8627 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
8628 IS.CounterInit, IS.NumIterations, IS.CounterStep,
8629 IS.Subtract, IS.IsNonRectangularLB, &Captures);
8630 if (!Final.isUsable()) {
8635 if (!Update.isUsable() || !Final.isUsable()) {
8640 Built.Counters[Cnt] = IS.CounterVar;
8641 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
8642 Built.Inits[Cnt] = Init.get();
8643 Built.Updates[Cnt] = Update.get();
8644 Built.Finals[Cnt] = Final.get();
8645 Built.DependentCounters[Cnt] = nullptr;
8646 Built.DependentInits[Cnt] = nullptr;
8647 Built.FinalsConditions[Cnt] = nullptr;
8648 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
8649 Built.DependentCounters[Cnt] =
8650 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
8651 Built.DependentInits[Cnt] =
8652 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
8653 Built.FinalsConditions[Cnt] = IS.FinalCondition;
8662 Built.IterationVarRef = IV.get();
8663 Built.LastIteration = LastIteration.get();
8664 Built.NumIterations = NumIterations.get();
8665 Built.CalcLastIteration = SemaRef
8666 .ActOnFinishFullExpr(CalcLastIteration.get(),
8667 /*DiscardedValue=*/false)
8669 Built.PreCond = PreCond.get();
8670 Built.PreInits = buildPreInits(C, Captures);
8671 Built.Cond = Cond.get();
8672 Built.Init = Init.get();
8673 Built.Inc = Inc.get();
8674 Built.LB = LB.get();
8675 Built.UB = UB.get();
8676 Built.IL = IL.get();
8677 Built.ST = ST.get();
8678 Built.EUB = EUB.get();
8679 Built.NLB = NextLB.get();
8680 Built.NUB = NextUB.get();
8681 Built.PrevLB = PrevLB.get();
8682 Built.PrevUB = PrevUB.get();
8683 Built.DistInc = DistInc.get();
8684 Built.PrevEUB = PrevEUB.get();
8685 Built.DistCombinedFields.LB = CombLB.get();
8686 Built.DistCombinedFields.UB = CombUB.get();
8687 Built.DistCombinedFields.EUB = CombEUB.get();
8688 Built.DistCombinedFields.Init = CombInit.get();
8689 Built.DistCombinedFields.Cond = CombCond.get();
8690 Built.DistCombinedFields.NLB = CombNextLB.get();
8691 Built.DistCombinedFields.NUB = CombNextUB.get();
8692 Built.DistCombinedFields.DistCond = CombDistCond.get();
8693 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
8695 return NestedLoopCount;
8698 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
8699 auto CollapseClauses =
8700 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
8701 if (CollapseClauses.begin() != CollapseClauses.end())
8702 return (*CollapseClauses.begin())->getNumForLoops();
8706 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
8707 auto OrderedClauses =
8708 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
8709 if (OrderedClauses.begin() != OrderedClauses.end())
8710 return (*OrderedClauses.begin())->getNumForLoops();
8714 static bool checkSimdlenSafelenSpecified(Sema &S,
8715 const ArrayRef<OMPClause *> Clauses) {
8716 const OMPSafelenClause *Safelen = nullptr;
8717 const OMPSimdlenClause *Simdlen = nullptr;
8719 for (const OMPClause *Clause : Clauses) {
8720 if (Clause->getClauseKind() == OMPC_safelen)
8721 Safelen = cast<OMPSafelenClause>(Clause);
8722 else if (Clause->getClauseKind() == OMPC_simdlen)
8723 Simdlen = cast<OMPSimdlenClause>(Clause);
8724 if (Safelen && Simdlen)
8728 if (Simdlen && Safelen) {
8729 const Expr *SimdlenLength = Simdlen->getSimdlen();
8730 const Expr *SafelenLength = Safelen->getSafelen();
8731 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
8732 SimdlenLength->isInstantiationDependent() ||
8733 SimdlenLength->containsUnexpandedParameterPack())
8735 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
8736 SafelenLength->isInstantiationDependent() ||
8737 SafelenLength->containsUnexpandedParameterPack())
8739 Expr::EvalResult SimdlenResult, SafelenResult;
8740 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8741 SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8742 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8743 llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8744 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8745 // If both simdlen and safelen clauses are specified, the value of the
8746 // simdlen parameter must be less than or equal to the value of the safelen
8748 if (SimdlenRes > SafelenRes) {
8749 S.Diag(SimdlenLength->getExprLoc(),
8750 diag::err_omp_wrong_simdlen_safelen_values)
8751 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8759 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8760 SourceLocation StartLoc, SourceLocation EndLoc,
8761 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8765 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8766 OMPLoopDirective::HelperExprs B;
8767 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8768 // define the nested loops number.
8769 unsigned NestedLoopCount = checkOpenMPLoop(
8770 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8771 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8772 if (NestedLoopCount == 0)
8775 assert((CurContext->isDependentContext() || B.builtAll()) &&
8776 "omp simd loop exprs were not built");
8778 if (!CurContext->isDependentContext()) {
8779 // Finalize the clauses that need pre-built expressions for CodeGen.
8780 for (OMPClause *C : Clauses) {
8781 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8782 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8783 B.NumIterations, *this, CurScope,
8789 if (checkSimdlenSafelenSpecified(*this, Clauses))
8792 setFunctionHasBranchProtectedScope();
8793 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8798 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
8799 SourceLocation StartLoc, SourceLocation EndLoc,
8800 VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8804 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8805 OMPLoopDirective::HelperExprs B;
8806 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8807 // define the nested loops number.
8808 unsigned NestedLoopCount = checkOpenMPLoop(
8809 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8810 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8811 if (NestedLoopCount == 0)
8814 assert((CurContext->isDependentContext() || B.builtAll()) &&
8815 "omp for loop exprs were not built");
8817 if (!CurContext->isDependentContext()) {
8818 // Finalize the clauses that need pre-built expressions for CodeGen.
8819 for (OMPClause *C : Clauses) {
8820 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8821 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8822 B.NumIterations, *this, CurScope,
8828 setFunctionHasBranchProtectedScope();
8829 return OMPForDirective::Create(
8830 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8831 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
8834 StmtResult Sema::ActOnOpenMPForSimdDirective(
8835 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8836 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8840 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8841 OMPLoopDirective::HelperExprs B;
8842 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8843 // define the nested loops number.
8844 unsigned NestedLoopCount =
8845 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8846 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8847 VarsWithImplicitDSA, B);
8848 if (NestedLoopCount == 0)
8851 assert((CurContext->isDependentContext() || B.builtAll()) &&
8852 "omp for simd loop exprs were not built");
8854 if (!CurContext->isDependentContext()) {
8855 // Finalize the clauses that need pre-built expressions for CodeGen.
8856 for (OMPClause *C : Clauses) {
8857 if (auto *LC = dyn_cast<OMPLinearClause>(C))
8858 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8859 B.NumIterations, *this, CurScope,
8865 if (checkSimdlenSafelenSpecified(*this, Clauses))
8868 setFunctionHasBranchProtectedScope();
8869 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8873 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
8875 SourceLocation StartLoc,
8876 SourceLocation EndLoc) {
8880 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8881 auto BaseStmt = AStmt;
8882 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8883 BaseStmt = CS->getCapturedStmt();
8884 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8885 auto S = C->children();
8886 if (S.begin() == S.end())
8888 // All associated statements must be '#pragma omp section' except for
8890 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8891 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8893 Diag(SectionStmt->getBeginLoc(),
8894 diag::err_omp_sections_substmt_not_section);
8897 cast<OMPSectionDirective>(SectionStmt)
8898 ->setHasCancel(DSAStack->isCancelRegion());
8901 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
8905 setFunctionHasBranchProtectedScope();
8907 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8908 DSAStack->getTaskgroupReductionRef(),
8909 DSAStack->isCancelRegion());
8912 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
8913 SourceLocation StartLoc,
8914 SourceLocation EndLoc) {
8918 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8920 setFunctionHasBranchProtectedScope();
8921 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
8923 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
8924 DSAStack->isCancelRegion());
8927 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
8929 SourceLocation StartLoc,
8930 SourceLocation EndLoc) {
8934 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8936 setFunctionHasBranchProtectedScope();
8938 // OpenMP [2.7.3, single Construct, Restrictions]
8939 // The copyprivate clause must not be used with the nowait clause.
8940 const OMPClause *Nowait = nullptr;
8941 const OMPClause *Copyprivate = nullptr;
8942 for (const OMPClause *Clause : Clauses) {
8943 if (Clause->getClauseKind() == OMPC_nowait)
8945 else if (Clause->getClauseKind() == OMPC_copyprivate)
8946 Copyprivate = Clause;
8947 if (Copyprivate && Nowait) {
8948 Diag(Copyprivate->getBeginLoc(),
8949 diag::err_omp_single_copyprivate_with_nowait);
8950 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
8955 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8958 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
8959 SourceLocation StartLoc,
8960 SourceLocation EndLoc) {
8964 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8966 setFunctionHasBranchProtectedScope();
8968 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
8971 StmtResult Sema::ActOnOpenMPCriticalDirective(
8972 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
8973 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
8977 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8979 bool ErrorFound = false;
8981 SourceLocation HintLoc;
8982 bool DependentHint = false;
8983 for (const OMPClause *C : Clauses) {
8984 if (C->getClauseKind() == OMPC_hint) {
8985 if (!DirName.getName()) {
8986 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
8989 Expr *E = cast<OMPHintClause>(C)->getHint();
8990 if (E->isTypeDependent() || E->isValueDependent() ||
8991 E->isInstantiationDependent()) {
8992 DependentHint = true;
8994 Hint = E->EvaluateKnownConstInt(Context);
8995 HintLoc = C->getBeginLoc();
9001 const auto Pair = DSAStack->getCriticalWithHint(DirName);
9002 if (Pair.first && DirName.getName() && !DependentHint) {
9003 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9004 Diag(StartLoc, diag::err_omp_critical_with_hint);
9005 if (HintLoc.isValid())
9006 Diag(HintLoc, diag::note_omp_critical_hint_here)
9007 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9009 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9010 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9011 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9013 << C->getHint()->EvaluateKnownConstInt(Context).toString(
9014 /*Radix=*/10, /*Signed=*/false);
9016 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9021 setFunctionHasBranchProtectedScope();
9023 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9025 if (!Pair.first && DirName.getName() && !DependentHint)
9026 DSAStack->addCriticalWithHint(Dir, Hint);
9030 StmtResult Sema::ActOnOpenMPParallelForDirective(
9031 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9032 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9036 auto *CS = cast<CapturedStmt>(AStmt);
9037 // 1.2.2 OpenMP Language Terminology
9038 // Structured block - An executable statement with a single entry at the
9039 // top and a single exit at the bottom.
9040 // The point of exit cannot be a branch out of the structured block.
9041 // longjmp() and throw() must not violate the entry/exit criteria.
9042 CS->getCapturedDecl()->setNothrow();
9044 OMPLoopDirective::HelperExprs B;
9045 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9046 // define the nested loops number.
9047 unsigned NestedLoopCount =
9048 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9049 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9050 VarsWithImplicitDSA, B);
9051 if (NestedLoopCount == 0)
9054 assert((CurContext->isDependentContext() || B.builtAll()) &&
9055 "omp parallel for loop exprs were not built");
9057 if (!CurContext->isDependentContext()) {
9058 // Finalize the clauses that need pre-built expressions for CodeGen.
9059 for (OMPClause *C : Clauses) {
9060 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9061 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9062 B.NumIterations, *this, CurScope,
9068 setFunctionHasBranchProtectedScope();
9069 return OMPParallelForDirective::Create(
9070 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9071 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9074 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
9075 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9076 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9080 auto *CS = cast<CapturedStmt>(AStmt);
9081 // 1.2.2 OpenMP Language Terminology
9082 // Structured block - An executable statement with a single entry at the
9083 // top and a single exit at the bottom.
9084 // The point of exit cannot be a branch out of the structured block.
9085 // longjmp() and throw() must not violate the entry/exit criteria.
9086 CS->getCapturedDecl()->setNothrow();
9088 OMPLoopDirective::HelperExprs B;
9089 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9090 // define the nested loops number.
9091 unsigned NestedLoopCount =
9092 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
9093 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9094 VarsWithImplicitDSA, B);
9095 if (NestedLoopCount == 0)
9098 if (!CurContext->isDependentContext()) {
9099 // Finalize the clauses that need pre-built expressions for CodeGen.
9100 for (OMPClause *C : Clauses) {
9101 if (auto *LC = dyn_cast<OMPLinearClause>(C))
9102 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9103 B.NumIterations, *this, CurScope,
9109 if (checkSimdlenSafelenSpecified(*this, Clauses))
9112 setFunctionHasBranchProtectedScope();
9113 return OMPParallelForSimdDirective::Create(
9114 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9118 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
9119 Stmt *AStmt, SourceLocation StartLoc,
9120 SourceLocation EndLoc) {
9124 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9125 auto *CS = cast<CapturedStmt>(AStmt);
9126 // 1.2.2 OpenMP Language Terminology
9127 // Structured block - An executable statement with a single entry at the
9128 // top and a single exit at the bottom.
9129 // The point of exit cannot be a branch out of the structured block.
9130 // longjmp() and throw() must not violate the entry/exit criteria.
9131 CS->getCapturedDecl()->setNothrow();
9133 setFunctionHasBranchProtectedScope();
9135 return OMPParallelMasterDirective::Create(
9136 Context, StartLoc, EndLoc, Clauses, AStmt,
9137 DSAStack->getTaskgroupReductionRef());
9141 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
9142 Stmt *AStmt, SourceLocation StartLoc,
9143 SourceLocation EndLoc) {
9147 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9148 auto BaseStmt = AStmt;
9149 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9150 BaseStmt = CS->getCapturedStmt();
9151 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9152 auto S = C->children();
9153 if (S.begin() == S.end())
9155 // All associated statements must be '#pragma omp section' except for
9157 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9158 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9160 Diag(SectionStmt->getBeginLoc(),
9161 diag::err_omp_parallel_sections_substmt_not_section);
9164 cast<OMPSectionDirective>(SectionStmt)
9165 ->setHasCancel(DSAStack->isCancelRegion());
9168 Diag(AStmt->getBeginLoc(),
9169 diag::err_omp_parallel_sections_not_compound_stmt);
9173 setFunctionHasBranchProtectedScope();
9175 return OMPParallelSectionsDirective::Create(
9176 Context, StartLoc, EndLoc, Clauses, AStmt,
9177 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9180 /// detach and mergeable clauses are mutially exclusive, check for it.
9181 static bool checkDetachMergeableClauses(Sema &S,
9182 ArrayRef<OMPClause *> Clauses) {
9183 const OMPClause *PrevClause = nullptr;
9184 bool ErrorFound = false;
9185 for (const OMPClause *C : Clauses) {
9186 if (C->getClauseKind() == OMPC_detach ||
9187 C->getClauseKind() == OMPC_mergeable) {
9190 } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9191 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
9192 << getOpenMPClauseName(C->getClauseKind())
9193 << getOpenMPClauseName(PrevClause->getClauseKind());
9194 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
9195 << getOpenMPClauseName(PrevClause->getClauseKind());
9203 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
9204 Stmt *AStmt, SourceLocation StartLoc,
9205 SourceLocation EndLoc) {
9209 // OpenMP 5.0, 2.10.1 task Construct
9210 // If a detach clause appears on the directive, then a mergeable clause cannot
9211 // appear on the same directive.
9212 if (checkDetachMergeableClauses(*this, Clauses))
9215 auto *CS = cast<CapturedStmt>(AStmt);
9216 // 1.2.2 OpenMP Language Terminology
9217 // Structured block - An executable statement with a single entry at the
9218 // top and a single exit at the bottom.
9219 // The point of exit cannot be a branch out of the structured block.
9220 // longjmp() and throw() must not violate the entry/exit criteria.
9221 CS->getCapturedDecl()->setNothrow();
9223 setFunctionHasBranchProtectedScope();
9225 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9226 DSAStack->isCancelRegion());
9229 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
9230 SourceLocation EndLoc) {
9231 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
9234 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
9235 SourceLocation EndLoc) {
9236 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
9239 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
9240 SourceLocation EndLoc) {
9241 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
9244 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
9246 SourceLocation StartLoc,
9247 SourceLocation EndLoc) {
9251 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9253 setFunctionHasBranchProtectedScope();
9255 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
9257 DSAStack->getTaskgroupReductionRef());
9260 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
9261 SourceLocation StartLoc,
9262 SourceLocation EndLoc) {
9263 OMPFlushClause *FC = nullptr;
9264 OMPClause *OrderClause = nullptr;
9265 for (OMPClause *C : Clauses) {
9266 if (C->getClauseKind() == OMPC_flush)
9267 FC = cast<OMPFlushClause>(C);
9271 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9272 SourceLocation MemOrderLoc;
9273 for (const OMPClause *C : Clauses) {
9274 if (C->getClauseKind() == OMPC_acq_rel ||
9275 C->getClauseKind() == OMPC_acquire ||
9276 C->getClauseKind() == OMPC_release) {
9277 if (MemOrderKind != OMPC_unknown) {
9278 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9279 << getOpenMPDirectiveName(OMPD_flush) << 1
9280 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9281 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9282 << getOpenMPClauseName(MemOrderKind);
9284 MemOrderKind = C->getClauseKind();
9285 MemOrderLoc = C->getBeginLoc();
9289 if (FC && OrderClause) {
9290 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
9291 << getOpenMPClauseName(OrderClause->getClauseKind());
9292 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
9293 << getOpenMPClauseName(OrderClause->getClauseKind());
9296 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
9299 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
9300 SourceLocation StartLoc,
9301 SourceLocation EndLoc) {
9302 if (Clauses.empty()) {
9303 Diag(StartLoc, diag::err_omp_depobj_expected);
9305 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
9306 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
9309 // Only depobj expression and another single clause is allowed.
9310 if (Clauses.size() > 2) {
9311 Diag(Clauses[2]->getBeginLoc(),
9312 diag::err_omp_depobj_single_clause_expected);
9314 } else if (Clauses.size() < 1) {
9315 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
9318 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
9321 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
9322 SourceLocation StartLoc,
9323 SourceLocation EndLoc) {
9324 // Check that exactly one clause is specified.
9325 if (Clauses.size() != 1) {
9326 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
9327 diag::err_omp_scan_single_clause_expected);
9330 // Check that scan directive is used in the scopeof the OpenMP loop body.
9331 if (Scope *S = DSAStack->getCurScope()) {
9332 Scope *ParentS = S->getParent();
9333 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
9334 !ParentS->getBreakParent()->isOpenMPLoopScope())
9335 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
9336 << getOpenMPDirectiveName(OMPD_scan) << 5);
9338 // Check that only one instance of scan directives is used in the same outer
9340 if (DSAStack->doesParentHasScanDirective()) {
9341 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
9342 Diag(DSAStack->getParentScanDirectiveLoc(),
9343 diag::note_omp_previous_directive)
9347 DSAStack->setParentHasScanDirective(StartLoc);
9348 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
9351 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
9353 SourceLocation StartLoc,
9354 SourceLocation EndLoc) {
9355 const OMPClause *DependFound = nullptr;
9356 const OMPClause *DependSourceClause = nullptr;
9357 const OMPClause *DependSinkClause = nullptr;
9358 bool ErrorFound = false;
9359 const OMPThreadsClause *TC = nullptr;
9360 const OMPSIMDClause *SC = nullptr;
9361 for (const OMPClause *C : Clauses) {
9362 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
9364 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
9365 if (DependSourceClause) {
9366 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
9367 << getOpenMPDirectiveName(OMPD_ordered)
9368 << getOpenMPClauseName(OMPC_depend) << 2;
9371 DependSourceClause = C;
9373 if (DependSinkClause) {
9374 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9378 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
9379 if (DependSourceClause) {
9380 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
9384 DependSinkClause = C;
9386 } else if (C->getClauseKind() == OMPC_threads) {
9387 TC = cast<OMPThreadsClause>(C);
9388 } else if (C->getClauseKind() == OMPC_simd) {
9389 SC = cast<OMPSIMDClause>(C);
9392 if (!ErrorFound && !SC &&
9393 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
9394 // OpenMP [2.8.1,simd Construct, Restrictions]
9395 // An ordered construct with the simd clause is the only OpenMP construct
9396 // that can appear in the simd region.
9397 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
9398 << (LangOpts.OpenMP >= 50 ? 1 : 0);
9400 } else if (DependFound && (TC || SC)) {
9401 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
9402 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
9404 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
9405 Diag(DependFound->getBeginLoc(),
9406 diag::err_omp_ordered_directive_without_param);
9408 } else if (TC || Clauses.empty()) {
9409 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
9410 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
9411 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
9413 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
9417 if ((!AStmt && !DependFound) || ErrorFound)
9420 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
9421 // During execution of an iteration of a worksharing-loop or a loop nest
9422 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
9423 // must not execute more than one ordered region corresponding to an ordered
9424 // construct without a depend clause.
9426 if (DSAStack->doesParentHasOrderedDirective()) {
9427 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
9428 Diag(DSAStack->getParentOrderedDirectiveLoc(),
9429 diag::note_omp_previous_directive)
9433 DSAStack->setParentHasOrderedDirective(StartLoc);
9437 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9439 setFunctionHasBranchProtectedScope();
9442 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9446 /// Helper class for checking expression in 'omp atomic [update]'
9448 class OpenMPAtomicUpdateChecker {
9449 /// Error results for atomic update expressions.
9450 enum ExprAnalysisErrorCode {
9451 /// A statement is not an expression statement.
9453 /// Expression is not builtin binary or unary operation.
9454 NotABinaryOrUnaryExpression,
9455 /// Unary operation is not post-/pre- increment/decrement operation.
9456 NotAnUnaryIncDecExpression,
9457 /// An expression is not of scalar type.
9459 /// A binary operation is not an assignment operation.
9461 /// RHS part of the binary operation is not a binary expression.
9462 NotABinaryExpression,
9463 /// RHS part is not additive/multiplicative/shift/biwise binary
9466 /// RHS binary operation does not have reference to the updated LHS
9468 NotAnUpdateExpression,
9469 /// No errors is found.
9472 /// Reference to Sema.
9474 /// A location for note diagnostics (when error is found).
9475 SourceLocation NoteLoc;
9476 /// 'x' lvalue part of the source atomic expression.
9478 /// 'expr' rvalue part of the source atomic expression.
9480 /// Helper expression of the form
9481 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9482 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9484 /// Is 'x' a LHS in a RHS part of full update expression. It is
9485 /// important for non-associative operations.
9486 bool IsXLHSInRHSPart;
9487 BinaryOperatorKind Op;
9488 SourceLocation OpLoc;
9489 /// true if the source expression is a postfix unary operation, false
9490 /// if it is a prefix unary operation.
9491 bool IsPostfixUpdate;
9494 OpenMPAtomicUpdateChecker(Sema &SemaRef)
9495 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
9496 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
9497 /// Check specified statement that it is suitable for 'atomic update'
9498 /// constructs and extract 'x', 'expr' and Operation from the original
9499 /// expression. If DiagId and NoteId == 0, then only check is performed
9500 /// without error notification.
9501 /// \param DiagId Diagnostic which should be emitted if error is found.
9502 /// \param NoteId Diagnostic note for the main error message.
9503 /// \return true if statement is not an update expression, false otherwise.
9504 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
9505 /// Return the 'x' lvalue part of the source atomic expression.
9506 Expr *getX() const { return X; }
9507 /// Return the 'expr' rvalue part of the source atomic expression.
9508 Expr *getExpr() const { return E; }
9509 /// Return the update expression used in calculation of the updated
9510 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
9511 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
9512 Expr *getUpdateExpr() const { return UpdateExpr; }
9513 /// Return true if 'x' is LHS in RHS part of full update expression,
9514 /// false otherwise.
9515 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
9517 /// true if the source expression is a postfix unary operation, false
9518 /// if it is a prefix unary operation.
9519 bool isPostfixUpdate() const { return IsPostfixUpdate; }
9522 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
9523 unsigned NoteId = 0);
9527 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
9528 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
9529 ExprAnalysisErrorCode ErrorFound = NoError;
9530 SourceLocation ErrorLoc, NoteLoc;
9531 SourceRange ErrorRange, NoteRange;
9532 // Allowed constructs are:
9533 // x = x binop expr;
9534 // x = expr binop x;
9535 if (AtomicBinOp->getOpcode() == BO_Assign) {
9536 X = AtomicBinOp->getLHS();
9537 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
9538 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
9539 if (AtomicInnerBinOp->isMultiplicativeOp() ||
9540 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
9541 AtomicInnerBinOp->isBitwiseOp()) {
9542 Op = AtomicInnerBinOp->getOpcode();
9543 OpLoc = AtomicInnerBinOp->getOperatorLoc();
9544 Expr *LHS = AtomicInnerBinOp->getLHS();
9545 Expr *RHS = AtomicInnerBinOp->getRHS();
9546 llvm::FoldingSetNodeID XId, LHSId, RHSId;
9547 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
9548 /*Canonical=*/true);
9549 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
9550 /*Canonical=*/true);
9551 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
9552 /*Canonical=*/true);
9555 IsXLHSInRHSPart = true;
9556 } else if (XId == RHSId) {
9558 IsXLHSInRHSPart = false;
9560 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9561 ErrorRange = AtomicInnerBinOp->getSourceRange();
9562 NoteLoc = X->getExprLoc();
9563 NoteRange = X->getSourceRange();
9564 ErrorFound = NotAnUpdateExpression;
9567 ErrorLoc = AtomicInnerBinOp->getExprLoc();
9568 ErrorRange = AtomicInnerBinOp->getSourceRange();
9569 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
9570 NoteRange = SourceRange(NoteLoc, NoteLoc);
9571 ErrorFound = NotABinaryOperator;
9574 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
9575 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
9576 ErrorFound = NotABinaryExpression;
9579 ErrorLoc = AtomicBinOp->getExprLoc();
9580 ErrorRange = AtomicBinOp->getSourceRange();
9581 NoteLoc = AtomicBinOp->getOperatorLoc();
9582 NoteRange = SourceRange(NoteLoc, NoteLoc);
9583 ErrorFound = NotAnAssignmentOp;
9585 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9586 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9587 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9590 if (SemaRef.CurContext->isDependentContext())
9591 E = X = UpdateExpr = nullptr;
9592 return ErrorFound != NoError;
9595 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
9597 ExprAnalysisErrorCode ErrorFound = NoError;
9598 SourceLocation ErrorLoc, NoteLoc;
9599 SourceRange ErrorRange, NoteRange;
9600 // Allowed constructs are:
9606 // x = x binop expr;
9607 // x = expr binop x;
9608 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
9609 AtomicBody = AtomicBody->IgnoreParenImpCasts();
9610 if (AtomicBody->getType()->isScalarType() ||
9611 AtomicBody->isInstantiationDependent()) {
9612 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
9613 AtomicBody->IgnoreParenImpCasts())) {
9614 // Check for Compound Assignment Operation
9615 Op = BinaryOperator::getOpForCompoundAssignment(
9616 AtomicCompAssignOp->getOpcode());
9617 OpLoc = AtomicCompAssignOp->getOperatorLoc();
9618 E = AtomicCompAssignOp->getRHS();
9619 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
9620 IsXLHSInRHSPart = true;
9621 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
9622 AtomicBody->IgnoreParenImpCasts())) {
9623 // Check for Binary Operation
9624 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
9626 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
9627 AtomicBody->IgnoreParenImpCasts())) {
9628 // Check for Unary Operation
9629 if (AtomicUnaryOp->isIncrementDecrementOp()) {
9630 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
9631 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
9632 OpLoc = AtomicUnaryOp->getOperatorLoc();
9633 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
9634 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
9635 IsXLHSInRHSPart = true;
9637 ErrorFound = NotAnUnaryIncDecExpression;
9638 ErrorLoc = AtomicUnaryOp->getExprLoc();
9639 ErrorRange = AtomicUnaryOp->getSourceRange();
9640 NoteLoc = AtomicUnaryOp->getOperatorLoc();
9641 NoteRange = SourceRange(NoteLoc, NoteLoc);
9643 } else if (!AtomicBody->isInstantiationDependent()) {
9644 ErrorFound = NotABinaryOrUnaryExpression;
9645 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
9646 NoteRange = ErrorRange = AtomicBody->getSourceRange();
9649 ErrorFound = NotAScalarType;
9650 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
9651 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9654 ErrorFound = NotAnExpression;
9655 NoteLoc = ErrorLoc = S->getBeginLoc();
9656 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9658 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
9659 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
9660 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
9663 if (SemaRef.CurContext->isDependentContext())
9664 E = X = UpdateExpr = nullptr;
9665 if (ErrorFound == NoError && E && X) {
9666 // Build an update expression of form 'OpaqueValueExpr(x) binop
9667 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
9668 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
9669 auto *OVEX = new (SemaRef.getASTContext())
9670 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
9671 auto *OVEExpr = new (SemaRef.getASTContext())
9672 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
9674 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
9675 IsXLHSInRHSPart ? OVEExpr : OVEX);
9676 if (Update.isInvalid())
9678 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
9680 if (Update.isInvalid())
9682 UpdateExpr = Update.get();
9684 return ErrorFound != NoError;
9687 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
9689 SourceLocation StartLoc,
9690 SourceLocation EndLoc) {
9691 // Register location of the first atomic directive.
9692 DSAStack->addAtomicDirectiveLoc(StartLoc);
9696 auto *CS = cast<CapturedStmt>(AStmt);
9697 // 1.2.2 OpenMP Language Terminology
9698 // Structured block - An executable statement with a single entry at the
9699 // top and a single exit at the bottom.
9700 // The point of exit cannot be a branch out of the structured block.
9701 // longjmp() and throw() must not violate the entry/exit criteria.
9702 OpenMPClauseKind AtomicKind = OMPC_unknown;
9703 SourceLocation AtomicKindLoc;
9704 OpenMPClauseKind MemOrderKind = OMPC_unknown;
9705 SourceLocation MemOrderLoc;
9706 for (const OMPClause *C : Clauses) {
9707 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
9708 C->getClauseKind() == OMPC_update ||
9709 C->getClauseKind() == OMPC_capture) {
9710 if (AtomicKind != OMPC_unknown) {
9711 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
9712 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9713 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
9714 << getOpenMPClauseName(AtomicKind);
9716 AtomicKind = C->getClauseKind();
9717 AtomicKindLoc = C->getBeginLoc();
9720 if (C->getClauseKind() == OMPC_seq_cst ||
9721 C->getClauseKind() == OMPC_acq_rel ||
9722 C->getClauseKind() == OMPC_acquire ||
9723 C->getClauseKind() == OMPC_release ||
9724 C->getClauseKind() == OMPC_relaxed) {
9725 if (MemOrderKind != OMPC_unknown) {
9726 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
9727 << getOpenMPDirectiveName(OMPD_atomic) << 0
9728 << SourceRange(C->getBeginLoc(), C->getEndLoc());
9729 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9730 << getOpenMPClauseName(MemOrderKind);
9732 MemOrderKind = C->getClauseKind();
9733 MemOrderLoc = C->getBeginLoc();
9737 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
9738 // If atomic-clause is read then memory-order-clause must not be acq_rel or
9740 // If atomic-clause is write then memory-order-clause must not be acq_rel or
9742 // If atomic-clause is update or not present then memory-order-clause must not
9743 // be acq_rel or acquire.
9744 if ((AtomicKind == OMPC_read &&
9745 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
9746 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
9747 AtomicKind == OMPC_unknown) &&
9748 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
9749 SourceLocation Loc = AtomicKindLoc;
9750 if (AtomicKind == OMPC_unknown)
9752 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
9753 << getOpenMPClauseName(AtomicKind)
9754 << (AtomicKind == OMPC_unknown ? 1 : 0)
9755 << getOpenMPClauseName(MemOrderKind);
9756 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
9757 << getOpenMPClauseName(MemOrderKind);
9760 Stmt *Body = CS->getCapturedStmt();
9761 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
9762 Body = EWC->getSubExpr();
9768 bool IsXLHSInRHSPart = false;
9769 bool IsPostfixUpdate = false;
9770 // OpenMP [2.12.6, atomic Construct]
9771 // In the next expressions:
9772 // * x and v (as applicable) are both l-value expressions with scalar type.
9773 // * During the execution of an atomic region, multiple syntactic
9774 // occurrences of x must designate the same storage location.
9775 // * Neither of v and expr (as applicable) may access the storage location
9777 // * Neither of x and expr (as applicable) may access the storage location
9779 // * expr is an expression with scalar type.
9780 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
9781 // * binop, binop=, ++, and -- are not overloaded operators.
9782 // * The expression x binop expr must be numerically equivalent to x binop
9783 // (expr). This requirement is satisfied if the operators in expr have
9784 // precedence greater than binop, or by using parentheses around expr or
9785 // subexpressions of expr.
9786 // * The expression expr binop x must be numerically equivalent to (expr)
9787 // binop x. This requirement is satisfied if the operators in expr have
9788 // precedence equal to or greater than binop, or by using parentheses around
9789 // expr or subexpressions of expr.
9790 // * For forms that allow multiple occurrences of x, the number of times
9791 // that x is evaluated is unspecified.
9792 if (AtomicKind == OMPC_read) {
9799 } ErrorFound = NoError;
9800 SourceLocation ErrorLoc, NoteLoc;
9801 SourceRange ErrorRange, NoteRange;
9802 // If clause is read:
9804 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9805 const auto *AtomicBinOp =
9806 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9807 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9808 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9809 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
9810 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9811 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
9812 if (!X->isLValue() || !V->isLValue()) {
9813 const Expr *NotLValueExpr = X->isLValue() ? V : X;
9814 ErrorFound = NotAnLValue;
9815 ErrorLoc = AtomicBinOp->getExprLoc();
9816 ErrorRange = AtomicBinOp->getSourceRange();
9817 NoteLoc = NotLValueExpr->getExprLoc();
9818 NoteRange = NotLValueExpr->getSourceRange();
9820 } else if (!X->isInstantiationDependent() ||
9821 !V->isInstantiationDependent()) {
9822 const Expr *NotScalarExpr =
9823 (X->isInstantiationDependent() || X->getType()->isScalarType())
9826 ErrorFound = NotAScalarType;
9827 ErrorLoc = AtomicBinOp->getExprLoc();
9828 ErrorRange = AtomicBinOp->getSourceRange();
9829 NoteLoc = NotScalarExpr->getExprLoc();
9830 NoteRange = NotScalarExpr->getSourceRange();
9832 } else if (!AtomicBody->isInstantiationDependent()) {
9833 ErrorFound = NotAnAssignmentOp;
9834 ErrorLoc = AtomicBody->getExprLoc();
9835 ErrorRange = AtomicBody->getSourceRange();
9836 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9837 : AtomicBody->getExprLoc();
9838 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9839 : AtomicBody->getSourceRange();
9842 ErrorFound = NotAnExpression;
9843 NoteLoc = ErrorLoc = Body->getBeginLoc();
9844 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9846 if (ErrorFound != NoError) {
9847 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
9849 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9853 if (CurContext->isDependentContext())
9855 } else if (AtomicKind == OMPC_write) {
9862 } ErrorFound = NoError;
9863 SourceLocation ErrorLoc, NoteLoc;
9864 SourceRange ErrorRange, NoteRange;
9865 // If clause is write:
9867 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9868 const auto *AtomicBinOp =
9869 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9870 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9871 X = AtomicBinOp->getLHS();
9872 E = AtomicBinOp->getRHS();
9873 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
9874 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
9875 if (!X->isLValue()) {
9876 ErrorFound = NotAnLValue;
9877 ErrorLoc = AtomicBinOp->getExprLoc();
9878 ErrorRange = AtomicBinOp->getSourceRange();
9879 NoteLoc = X->getExprLoc();
9880 NoteRange = X->getSourceRange();
9882 } else if (!X->isInstantiationDependent() ||
9883 !E->isInstantiationDependent()) {
9884 const Expr *NotScalarExpr =
9885 (X->isInstantiationDependent() || X->getType()->isScalarType())
9888 ErrorFound = NotAScalarType;
9889 ErrorLoc = AtomicBinOp->getExprLoc();
9890 ErrorRange = AtomicBinOp->getSourceRange();
9891 NoteLoc = NotScalarExpr->getExprLoc();
9892 NoteRange = NotScalarExpr->getSourceRange();
9894 } else if (!AtomicBody->isInstantiationDependent()) {
9895 ErrorFound = NotAnAssignmentOp;
9896 ErrorLoc = AtomicBody->getExprLoc();
9897 ErrorRange = AtomicBody->getSourceRange();
9898 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9899 : AtomicBody->getExprLoc();
9900 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9901 : AtomicBody->getSourceRange();
9904 ErrorFound = NotAnExpression;
9905 NoteLoc = ErrorLoc = Body->getBeginLoc();
9906 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
9908 if (ErrorFound != NoError) {
9909 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
9911 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9915 if (CurContext->isDependentContext())
9917 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
9918 // If clause is update:
9924 // x = x binop expr;
9925 // x = expr binop x;
9926 OpenMPAtomicUpdateChecker Checker(*this);
9927 if (Checker.checkStatement(
9928 Body, (AtomicKind == OMPC_update)
9929 ? diag::err_omp_atomic_update_not_expression_statement
9930 : diag::err_omp_atomic_not_expression_statement,
9931 diag::note_omp_atomic_update))
9933 if (!CurContext->isDependentContext()) {
9934 E = Checker.getExpr();
9936 UE = Checker.getUpdateExpr();
9937 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9939 } else if (AtomicKind == OMPC_capture) {
9942 NotACompoundStatement,
9943 NotTwoSubstatements,
9944 NotASpecificExpression,
9946 } ErrorFound = NoError;
9947 SourceLocation ErrorLoc, NoteLoc;
9948 SourceRange ErrorRange, NoteRange;
9949 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9950 // If clause is a capture:
9955 // v = x binop= expr;
9956 // v = x = x binop expr;
9957 // v = x = expr binop x;
9958 const auto *AtomicBinOp =
9959 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9960 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9961 V = AtomicBinOp->getLHS();
9962 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9963 OpenMPAtomicUpdateChecker Checker(*this);
9964 if (Checker.checkStatement(
9965 Body, diag::err_omp_atomic_capture_not_expression_statement,
9966 diag::note_omp_atomic_update))
9968 E = Checker.getExpr();
9970 UE = Checker.getUpdateExpr();
9971 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9972 IsPostfixUpdate = Checker.isPostfixUpdate();
9973 } else if (!AtomicBody->isInstantiationDependent()) {
9974 ErrorLoc = AtomicBody->getExprLoc();
9975 ErrorRange = AtomicBody->getSourceRange();
9976 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9977 : AtomicBody->getExprLoc();
9978 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9979 : AtomicBody->getSourceRange();
9980 ErrorFound = NotAnAssignmentOp;
9982 if (ErrorFound != NoError) {
9983 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
9985 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9988 if (CurContext->isDependentContext())
9989 UE = V = E = X = nullptr;
9991 // If clause is a capture:
9992 // { v = x; x = expr; }
9997 // { v = x; x binop= expr; }
9998 // { v = x; x = x binop expr; }
9999 // { v = x; x = expr binop x; }
10004 // { x binop= expr; v = x; }
10005 // { x = x binop expr; v = x; }
10006 // { x = expr binop x; v = x; }
10007 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10008 // Check that this is { expr1; expr2; }
10009 if (CS->size() == 2) {
10010 Stmt *First = CS->body_front();
10011 Stmt *Second = CS->body_back();
10012 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10013 First = EWC->getSubExpr()->IgnoreParenImpCasts();
10014 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10015 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10016 // Need to find what subexpression is 'v' and what is 'x'.
10017 OpenMPAtomicUpdateChecker Checker(*this);
10018 bool IsUpdateExprFound = !Checker.checkStatement(Second);
10019 BinaryOperator *BinOp = nullptr;
10020 if (IsUpdateExprFound) {
10021 BinOp = dyn_cast<BinaryOperator>(First);
10022 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10024 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10029 // { v = x; x binop= expr; }
10030 // { v = x; x = x binop expr; }
10031 // { v = x; x = expr binop x; }
10032 // Check that the first expression has form v = x.
10033 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10034 llvm::FoldingSetNodeID XId, PossibleXId;
10035 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10036 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10037 IsUpdateExprFound = XId == PossibleXId;
10038 if (IsUpdateExprFound) {
10039 V = BinOp->getLHS();
10040 X = Checker.getX();
10041 E = Checker.getExpr();
10042 UE = Checker.getUpdateExpr();
10043 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10044 IsPostfixUpdate = true;
10047 if (!IsUpdateExprFound) {
10048 IsUpdateExprFound = !Checker.checkStatement(First);
10050 if (IsUpdateExprFound) {
10051 BinOp = dyn_cast<BinaryOperator>(Second);
10052 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10054 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10059 // { x binop= expr; v = x; }
10060 // { x = x binop expr; v = x; }
10061 // { x = expr binop x; v = x; }
10062 // Check that the second expression has form v = x.
10063 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10064 llvm::FoldingSetNodeID XId, PossibleXId;
10065 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10066 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10067 IsUpdateExprFound = XId == PossibleXId;
10068 if (IsUpdateExprFound) {
10069 V = BinOp->getLHS();
10070 X = Checker.getX();
10071 E = Checker.getExpr();
10072 UE = Checker.getUpdateExpr();
10073 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10074 IsPostfixUpdate = false;
10078 if (!IsUpdateExprFound) {
10079 // { v = x; x = expr; }
10080 auto *FirstExpr = dyn_cast<Expr>(First);
10081 auto *SecondExpr = dyn_cast<Expr>(Second);
10082 if (!FirstExpr || !SecondExpr ||
10083 !(FirstExpr->isInstantiationDependent() ||
10084 SecondExpr->isInstantiationDependent())) {
10085 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
10086 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
10087 ErrorFound = NotAnAssignmentOp;
10088 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
10089 : First->getBeginLoc();
10090 NoteRange = ErrorRange = FirstBinOp
10091 ? FirstBinOp->getSourceRange()
10092 : SourceRange(ErrorLoc, ErrorLoc);
10094 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
10095 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
10096 ErrorFound = NotAnAssignmentOp;
10097 NoteLoc = ErrorLoc = SecondBinOp
10098 ? SecondBinOp->getOperatorLoc()
10099 : Second->getBeginLoc();
10100 NoteRange = ErrorRange =
10101 SecondBinOp ? SecondBinOp->getSourceRange()
10102 : SourceRange(ErrorLoc, ErrorLoc);
10104 Expr *PossibleXRHSInFirst =
10105 FirstBinOp->getRHS()->IgnoreParenImpCasts();
10106 Expr *PossibleXLHSInSecond =
10107 SecondBinOp->getLHS()->IgnoreParenImpCasts();
10108 llvm::FoldingSetNodeID X1Id, X2Id;
10109 PossibleXRHSInFirst->Profile(X1Id, Context,
10110 /*Canonical=*/true);
10111 PossibleXLHSInSecond->Profile(X2Id, Context,
10112 /*Canonical=*/true);
10113 IsUpdateExprFound = X1Id == X2Id;
10114 if (IsUpdateExprFound) {
10115 V = FirstBinOp->getLHS();
10116 X = SecondBinOp->getLHS();
10117 E = SecondBinOp->getRHS();
10119 IsXLHSInRHSPart = false;
10120 IsPostfixUpdate = true;
10122 ErrorFound = NotASpecificExpression;
10123 ErrorLoc = FirstBinOp->getExprLoc();
10124 ErrorRange = FirstBinOp->getSourceRange();
10125 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
10126 NoteRange = SecondBinOp->getRHS()->getSourceRange();
10133 NoteLoc = ErrorLoc = Body->getBeginLoc();
10134 NoteRange = ErrorRange =
10135 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10136 ErrorFound = NotTwoSubstatements;
10139 NoteLoc = ErrorLoc = Body->getBeginLoc();
10140 NoteRange = ErrorRange =
10141 SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
10142 ErrorFound = NotACompoundStatement;
10144 if (ErrorFound != NoError) {
10145 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
10147 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10148 return StmtError();
10150 if (CurContext->isDependentContext())
10151 UE = V = E = X = nullptr;
10155 setFunctionHasBranchProtectedScope();
10157 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10158 X, V, E, UE, IsXLHSInRHSPart,
10162 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
10164 SourceLocation StartLoc,
10165 SourceLocation EndLoc) {
10167 return StmtError();
10169 auto *CS = cast<CapturedStmt>(AStmt);
10170 // 1.2.2 OpenMP Language Terminology
10171 // Structured block - An executable statement with a single entry at the
10172 // top and a single exit at the bottom.
10173 // The point of exit cannot be a branch out of the structured block.
10174 // longjmp() and throw() must not violate the entry/exit criteria.
10175 CS->getCapturedDecl()->setNothrow();
10176 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
10177 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10178 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10179 // 1.2.2 OpenMP Language Terminology
10180 // Structured block - An executable statement with a single entry at the
10181 // top and a single exit at the bottom.
10182 // The point of exit cannot be a branch out of the structured block.
10183 // longjmp() and throw() must not violate the entry/exit criteria.
10184 CS->getCapturedDecl()->setNothrow();
10187 // OpenMP [2.16, Nesting of Regions]
10188 // If specified, a teams construct must be contained within a target
10189 // construct. That target construct must contain no statements or directives
10190 // outside of the teams construct.
10191 if (DSAStack->hasInnerTeamsRegion()) {
10192 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
10193 bool OMPTeamsFound = true;
10194 if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
10195 auto I = CS->body_begin();
10196 while (I != CS->body_end()) {
10197 const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
10198 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
10201 OMPTeamsFound = false;
10206 assert(I != CS->body_end() && "Not found statement");
10209 const auto *OED = dyn_cast<OMPExecutableDirective>(S);
10210 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
10212 if (!OMPTeamsFound) {
10213 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
10214 Diag(DSAStack->getInnerTeamsRegionLoc(),
10215 diag::note_omp_nested_teams_construct_here);
10216 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
10217 << isa<OMPExecutableDirective>(S);
10218 return StmtError();
10222 setFunctionHasBranchProtectedScope();
10224 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10228 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
10229 Stmt *AStmt, SourceLocation StartLoc,
10230 SourceLocation EndLoc) {
10232 return StmtError();
10234 auto *CS = cast<CapturedStmt>(AStmt);
10235 // 1.2.2 OpenMP Language Terminology
10236 // Structured block - An executable statement with a single entry at the
10237 // top and a single exit at the bottom.
10238 // The point of exit cannot be a branch out of the structured block.
10239 // longjmp() and throw() must not violate the entry/exit criteria.
10240 CS->getCapturedDecl()->setNothrow();
10241 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
10242 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10243 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10244 // 1.2.2 OpenMP Language Terminology
10245 // Structured block - An executable statement with a single entry at the
10246 // top and a single exit at the bottom.
10247 // The point of exit cannot be a branch out of the structured block.
10248 // longjmp() and throw() must not violate the entry/exit criteria.
10249 CS->getCapturedDecl()->setNothrow();
10252 setFunctionHasBranchProtectedScope();
10254 return OMPTargetParallelDirective::Create(
10255 Context, StartLoc, EndLoc, Clauses, AStmt,
10256 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10259 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
10260 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10261 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10263 return StmtError();
10265 auto *CS = cast<CapturedStmt>(AStmt);
10266 // 1.2.2 OpenMP Language Terminology
10267 // Structured block - An executable statement with a single entry at the
10268 // top and a single exit at the bottom.
10269 // The point of exit cannot be a branch out of the structured block.
10270 // longjmp() and throw() must not violate the entry/exit criteria.
10271 CS->getCapturedDecl()->setNothrow();
10272 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10273 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10274 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10275 // 1.2.2 OpenMP Language Terminology
10276 // Structured block - An executable statement with a single entry at the
10277 // top and a single exit at the bottom.
10278 // The point of exit cannot be a branch out of the structured block.
10279 // longjmp() and throw() must not violate the entry/exit criteria.
10280 CS->getCapturedDecl()->setNothrow();
10283 OMPLoopDirective::HelperExprs B;
10284 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10285 // define the nested loops number.
10286 unsigned NestedLoopCount =
10287 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
10288 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10289 VarsWithImplicitDSA, B);
10290 if (NestedLoopCount == 0)
10291 return StmtError();
10293 assert((CurContext->isDependentContext() || B.builtAll()) &&
10294 "omp target parallel for loop exprs were not built");
10296 if (!CurContext->isDependentContext()) {
10297 // Finalize the clauses that need pre-built expressions for CodeGen.
10298 for (OMPClause *C : Clauses) {
10299 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10300 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10301 B.NumIterations, *this, CurScope,
10303 return StmtError();
10307 setFunctionHasBranchProtectedScope();
10308 return OMPTargetParallelForDirective::Create(
10309 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10310 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10313 /// Check for existence of a map clause in the list of clauses.
10314 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
10315 const OpenMPClauseKind K) {
10316 return llvm::any_of(
10317 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
10320 template <typename... Params>
10321 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
10322 const Params... ClauseTypes) {
10323 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
10326 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
10328 SourceLocation StartLoc,
10329 SourceLocation EndLoc) {
10331 return StmtError();
10333 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10335 // OpenMP [2.12.2, target data Construct, Restrictions]
10336 // At least one map, use_device_addr or use_device_ptr clause must appear on
10338 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
10339 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
10340 StringRef Expected;
10341 if (LangOpts.OpenMP < 50)
10342 Expected = "'map' or 'use_device_ptr'";
10344 Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
10345 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10346 << Expected << getOpenMPDirectiveName(OMPD_target_data);
10347 return StmtError();
10350 setFunctionHasBranchProtectedScope();
10352 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10357 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
10358 SourceLocation StartLoc,
10359 SourceLocation EndLoc, Stmt *AStmt) {
10361 return StmtError();
10363 auto *CS = cast<CapturedStmt>(AStmt);
10364 // 1.2.2 OpenMP Language Terminology
10365 // Structured block - An executable statement with a single entry at the
10366 // top and a single exit at the bottom.
10367 // The point of exit cannot be a branch out of the structured block.
10368 // longjmp() and throw() must not violate the entry/exit criteria.
10369 CS->getCapturedDecl()->setNothrow();
10370 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
10371 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10372 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10373 // 1.2.2 OpenMP Language Terminology
10374 // Structured block - An executable statement with a single entry at the
10375 // top and a single exit at the bottom.
10376 // The point of exit cannot be a branch out of the structured block.
10377 // longjmp() and throw() must not violate the entry/exit criteria.
10378 CS->getCapturedDecl()->setNothrow();
10381 // OpenMP [2.10.2, Restrictions, p. 99]
10382 // At least one map clause must appear on the directive.
10383 if (!hasClauses(Clauses, OMPC_map)) {
10384 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10385 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
10386 return StmtError();
10389 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10394 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
10395 SourceLocation StartLoc,
10396 SourceLocation EndLoc, Stmt *AStmt) {
10398 return StmtError();
10400 auto *CS = cast<CapturedStmt>(AStmt);
10401 // 1.2.2 OpenMP Language Terminology
10402 // Structured block - An executable statement with a single entry at the
10403 // top and a single exit at the bottom.
10404 // The point of exit cannot be a branch out of the structured block.
10405 // longjmp() and throw() must not violate the entry/exit criteria.
10406 CS->getCapturedDecl()->setNothrow();
10407 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
10408 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10409 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10410 // 1.2.2 OpenMP Language Terminology
10411 // Structured block - An executable statement with a single entry at the
10412 // top and a single exit at the bottom.
10413 // The point of exit cannot be a branch out of the structured block.
10414 // longjmp() and throw() must not violate the entry/exit criteria.
10415 CS->getCapturedDecl()->setNothrow();
10418 // OpenMP [2.10.3, Restrictions, p. 102]
10419 // At least one map clause must appear on the directive.
10420 if (!hasClauses(Clauses, OMPC_map)) {
10421 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
10422 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
10423 return StmtError();
10426 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
10430 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
10431 SourceLocation StartLoc,
10432 SourceLocation EndLoc,
10435 return StmtError();
10437 auto *CS = cast<CapturedStmt>(AStmt);
10438 // 1.2.2 OpenMP Language Terminology
10439 // Structured block - An executable statement with a single entry at the
10440 // top and a single exit at the bottom.
10441 // The point of exit cannot be a branch out of the structured block.
10442 // longjmp() and throw() must not violate the entry/exit criteria.
10443 CS->getCapturedDecl()->setNothrow();
10444 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
10445 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10446 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10447 // 1.2.2 OpenMP Language Terminology
10448 // Structured block - An executable statement with a single entry at the
10449 // top and a single exit at the bottom.
10450 // The point of exit cannot be a branch out of the structured block.
10451 // longjmp() and throw() must not violate the entry/exit criteria.
10452 CS->getCapturedDecl()->setNothrow();
10455 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
10456 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
10457 return StmtError();
10459 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
10463 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
10464 Stmt *AStmt, SourceLocation StartLoc,
10465 SourceLocation EndLoc) {
10467 return StmtError();
10469 auto *CS = cast<CapturedStmt>(AStmt);
10470 // 1.2.2 OpenMP Language Terminology
10471 // Structured block - An executable statement with a single entry at the
10472 // top and a single exit at the bottom.
10473 // The point of exit cannot be a branch out of the structured block.
10474 // longjmp() and throw() must not violate the entry/exit criteria.
10475 CS->getCapturedDecl()->setNothrow();
10477 setFunctionHasBranchProtectedScope();
10479 DSAStack->setParentTeamsRegionLoc(StartLoc);
10481 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10485 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
10486 SourceLocation EndLoc,
10487 OpenMPDirectiveKind CancelRegion) {
10488 if (DSAStack->isParentNowaitRegion()) {
10489 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
10490 return StmtError();
10492 if (DSAStack->isParentOrderedRegion()) {
10493 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
10494 return StmtError();
10496 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
10500 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
10501 SourceLocation StartLoc,
10502 SourceLocation EndLoc,
10503 OpenMPDirectiveKind CancelRegion) {
10504 if (DSAStack->isParentNowaitRegion()) {
10505 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
10506 return StmtError();
10508 if (DSAStack->isParentOrderedRegion()) {
10509 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
10510 return StmtError();
10512 DSAStack->setParentCancelRegion(/*Cancel=*/true);
10513 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
10517 static bool checkGrainsizeNumTasksClauses(Sema &S,
10518 ArrayRef<OMPClause *> Clauses) {
10519 const OMPClause *PrevClause = nullptr;
10520 bool ErrorFound = false;
10521 for (const OMPClause *C : Clauses) {
10522 if (C->getClauseKind() == OMPC_grainsize ||
10523 C->getClauseKind() == OMPC_num_tasks) {
10526 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10527 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10528 << getOpenMPClauseName(C->getClauseKind())
10529 << getOpenMPClauseName(PrevClause->getClauseKind());
10530 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10531 << getOpenMPClauseName(PrevClause->getClauseKind());
10539 static bool checkReductionClauseWithNogroup(Sema &S,
10540 ArrayRef<OMPClause *> Clauses) {
10541 const OMPClause *ReductionClause = nullptr;
10542 const OMPClause *NogroupClause = nullptr;
10543 for (const OMPClause *C : Clauses) {
10544 if (C->getClauseKind() == OMPC_reduction) {
10545 ReductionClause = C;
10550 if (C->getClauseKind() == OMPC_nogroup) {
10552 if (ReductionClause)
10557 if (ReductionClause && NogroupClause) {
10558 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
10559 << SourceRange(NogroupClause->getBeginLoc(),
10560 NogroupClause->getEndLoc());
10566 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
10567 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10568 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10570 return StmtError();
10572 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10573 OMPLoopDirective::HelperExprs B;
10574 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10575 // define the nested loops number.
10576 unsigned NestedLoopCount =
10577 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
10578 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10579 VarsWithImplicitDSA, B);
10580 if (NestedLoopCount == 0)
10581 return StmtError();
10583 assert((CurContext->isDependentContext() || B.builtAll()) &&
10584 "omp for loop exprs were not built");
10586 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10587 // The grainsize clause and num_tasks clause are mutually exclusive and may
10588 // not appear on the same taskloop directive.
10589 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10590 return StmtError();
10591 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10592 // If a reduction clause is present on the taskloop directive, the nogroup
10593 // clause must not be specified.
10594 if (checkReductionClauseWithNogroup(*this, Clauses))
10595 return StmtError();
10597 setFunctionHasBranchProtectedScope();
10598 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10599 NestedLoopCount, Clauses, AStmt, B,
10600 DSAStack->isCancelRegion());
10603 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
10604 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10605 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10607 return StmtError();
10609 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10610 OMPLoopDirective::HelperExprs B;
10611 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10612 // define the nested loops number.
10613 unsigned NestedLoopCount =
10614 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
10615 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10616 VarsWithImplicitDSA, B);
10617 if (NestedLoopCount == 0)
10618 return StmtError();
10620 assert((CurContext->isDependentContext() || B.builtAll()) &&
10621 "omp for loop exprs were not built");
10623 if (!CurContext->isDependentContext()) {
10624 // Finalize the clauses that need pre-built expressions for CodeGen.
10625 for (OMPClause *C : Clauses) {
10626 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10627 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10628 B.NumIterations, *this, CurScope,
10630 return StmtError();
10634 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10635 // The grainsize clause and num_tasks clause are mutually exclusive and may
10636 // not appear on the same taskloop directive.
10637 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10638 return StmtError();
10639 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10640 // If a reduction clause is present on the taskloop directive, the nogroup
10641 // clause must not be specified.
10642 if (checkReductionClauseWithNogroup(*this, Clauses))
10643 return StmtError();
10644 if (checkSimdlenSafelenSpecified(*this, Clauses))
10645 return StmtError();
10647 setFunctionHasBranchProtectedScope();
10648 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
10649 NestedLoopCount, Clauses, AStmt, B);
10652 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
10653 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10654 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10656 return StmtError();
10658 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10659 OMPLoopDirective::HelperExprs B;
10660 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10661 // define the nested loops number.
10662 unsigned NestedLoopCount =
10663 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
10664 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10665 VarsWithImplicitDSA, B);
10666 if (NestedLoopCount == 0)
10667 return StmtError();
10669 assert((CurContext->isDependentContext() || B.builtAll()) &&
10670 "omp for loop exprs were not built");
10672 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10673 // The grainsize clause and num_tasks clause are mutually exclusive and may
10674 // not appear on the same taskloop directive.
10675 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10676 return StmtError();
10677 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10678 // If a reduction clause is present on the taskloop directive, the nogroup
10679 // clause must not be specified.
10680 if (checkReductionClauseWithNogroup(*this, Clauses))
10681 return StmtError();
10683 setFunctionHasBranchProtectedScope();
10684 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
10685 NestedLoopCount, Clauses, AStmt, B,
10686 DSAStack->isCancelRegion());
10689 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
10690 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10691 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10693 return StmtError();
10695 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10696 OMPLoopDirective::HelperExprs B;
10697 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10698 // define the nested loops number.
10699 unsigned NestedLoopCount =
10700 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10701 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
10702 VarsWithImplicitDSA, B);
10703 if (NestedLoopCount == 0)
10704 return StmtError();
10706 assert((CurContext->isDependentContext() || B.builtAll()) &&
10707 "omp for loop exprs were not built");
10709 if (!CurContext->isDependentContext()) {
10710 // Finalize the clauses that need pre-built expressions for CodeGen.
10711 for (OMPClause *C : Clauses) {
10712 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10713 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10714 B.NumIterations, *this, CurScope,
10716 return StmtError();
10720 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10721 // The grainsize clause and num_tasks clause are mutually exclusive and may
10722 // not appear on the same taskloop directive.
10723 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10724 return StmtError();
10725 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10726 // If a reduction clause is present on the taskloop directive, the nogroup
10727 // clause must not be specified.
10728 if (checkReductionClauseWithNogroup(*this, Clauses))
10729 return StmtError();
10730 if (checkSimdlenSafelenSpecified(*this, Clauses))
10731 return StmtError();
10733 setFunctionHasBranchProtectedScope();
10734 return OMPMasterTaskLoopSimdDirective::Create(
10735 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10738 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
10739 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10740 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10742 return StmtError();
10744 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10745 auto *CS = cast<CapturedStmt>(AStmt);
10746 // 1.2.2 OpenMP Language Terminology
10747 // Structured block - An executable statement with a single entry at the
10748 // top and a single exit at the bottom.
10749 // The point of exit cannot be a branch out of the structured block.
10750 // longjmp() and throw() must not violate the entry/exit criteria.
10751 CS->getCapturedDecl()->setNothrow();
10752 for (int ThisCaptureLevel =
10753 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
10754 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10755 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10756 // 1.2.2 OpenMP Language Terminology
10757 // Structured block - An executable statement with a single entry at the
10758 // top and a single exit at the bottom.
10759 // The point of exit cannot be a branch out of the structured block.
10760 // longjmp() and throw() must not violate the entry/exit criteria.
10761 CS->getCapturedDecl()->setNothrow();
10764 OMPLoopDirective::HelperExprs B;
10765 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10766 // define the nested loops number.
10767 unsigned NestedLoopCount = checkOpenMPLoop(
10768 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
10769 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10770 VarsWithImplicitDSA, B);
10771 if (NestedLoopCount == 0)
10772 return StmtError();
10774 assert((CurContext->isDependentContext() || B.builtAll()) &&
10775 "omp for loop exprs were not built");
10777 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10778 // The grainsize clause and num_tasks clause are mutually exclusive and may
10779 // not appear on the same taskloop directive.
10780 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10781 return StmtError();
10782 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10783 // If a reduction clause is present on the taskloop directive, the nogroup
10784 // clause must not be specified.
10785 if (checkReductionClauseWithNogroup(*this, Clauses))
10786 return StmtError();
10788 setFunctionHasBranchProtectedScope();
10789 return OMPParallelMasterTaskLoopDirective::Create(
10790 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10791 DSAStack->isCancelRegion());
10794 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
10795 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10796 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10798 return StmtError();
10800 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10801 auto *CS = cast<CapturedStmt>(AStmt);
10802 // 1.2.2 OpenMP Language Terminology
10803 // Structured block - An executable statement with a single entry at the
10804 // top and a single exit at the bottom.
10805 // The point of exit cannot be a branch out of the structured block.
10806 // longjmp() and throw() must not violate the entry/exit criteria.
10807 CS->getCapturedDecl()->setNothrow();
10808 for (int ThisCaptureLevel =
10809 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
10810 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10811 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10812 // 1.2.2 OpenMP Language Terminology
10813 // Structured block - An executable statement with a single entry at the
10814 // top and a single exit at the bottom.
10815 // The point of exit cannot be a branch out of the structured block.
10816 // longjmp() and throw() must not violate the entry/exit criteria.
10817 CS->getCapturedDecl()->setNothrow();
10820 OMPLoopDirective::HelperExprs B;
10821 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10822 // define the nested loops number.
10823 unsigned NestedLoopCount = checkOpenMPLoop(
10824 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
10825 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10826 VarsWithImplicitDSA, B);
10827 if (NestedLoopCount == 0)
10828 return StmtError();
10830 assert((CurContext->isDependentContext() || B.builtAll()) &&
10831 "omp for loop exprs were not built");
10833 if (!CurContext->isDependentContext()) {
10834 // Finalize the clauses that need pre-built expressions for CodeGen.
10835 for (OMPClause *C : Clauses) {
10836 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10837 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10838 B.NumIterations, *this, CurScope,
10840 return StmtError();
10844 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10845 // The grainsize clause and num_tasks clause are mutually exclusive and may
10846 // not appear on the same taskloop directive.
10847 if (checkGrainsizeNumTasksClauses(*this, Clauses))
10848 return StmtError();
10849 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
10850 // If a reduction clause is present on the taskloop directive, the nogroup
10851 // clause must not be specified.
10852 if (checkReductionClauseWithNogroup(*this, Clauses))
10853 return StmtError();
10854 if (checkSimdlenSafelenSpecified(*this, Clauses))
10855 return StmtError();
10857 setFunctionHasBranchProtectedScope();
10858 return OMPParallelMasterTaskLoopSimdDirective::Create(
10859 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10862 StmtResult Sema::ActOnOpenMPDistributeDirective(
10863 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10864 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10866 return StmtError();
10868 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10869 OMPLoopDirective::HelperExprs B;
10870 // In presence of clause 'collapse' with number of loops, it will
10871 // define the nested loops number.
10872 unsigned NestedLoopCount =
10873 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
10874 nullptr /*ordered not a clause on distribute*/, AStmt,
10875 *this, *DSAStack, VarsWithImplicitDSA, B);
10876 if (NestedLoopCount == 0)
10877 return StmtError();
10879 assert((CurContext->isDependentContext() || B.builtAll()) &&
10880 "omp for loop exprs were not built");
10882 setFunctionHasBranchProtectedScope();
10883 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
10884 NestedLoopCount, Clauses, AStmt, B);
10887 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
10888 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10889 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10891 return StmtError();
10893 auto *CS = cast<CapturedStmt>(AStmt);
10894 // 1.2.2 OpenMP Language Terminology
10895 // Structured block - An executable statement with a single entry at the
10896 // top and a single exit at the bottom.
10897 // The point of exit cannot be a branch out of the structured block.
10898 // longjmp() and throw() must not violate the entry/exit criteria.
10899 CS->getCapturedDecl()->setNothrow();
10900 for (int ThisCaptureLevel =
10901 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
10902 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10903 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10904 // 1.2.2 OpenMP Language Terminology
10905 // Structured block - An executable statement with a single entry at the
10906 // top and a single exit at the bottom.
10907 // The point of exit cannot be a branch out of the structured block.
10908 // longjmp() and throw() must not violate the entry/exit criteria.
10909 CS->getCapturedDecl()->setNothrow();
10912 OMPLoopDirective::HelperExprs B;
10913 // In presence of clause 'collapse' with number of loops, it will
10914 // define the nested loops number.
10915 unsigned NestedLoopCount = checkOpenMPLoop(
10916 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10917 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10918 VarsWithImplicitDSA, B);
10919 if (NestedLoopCount == 0)
10920 return StmtError();
10922 assert((CurContext->isDependentContext() || B.builtAll()) &&
10923 "omp for loop exprs were not built");
10925 setFunctionHasBranchProtectedScope();
10926 return OMPDistributeParallelForDirective::Create(
10927 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10928 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10931 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
10932 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10933 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10935 return StmtError();
10937 auto *CS = cast<CapturedStmt>(AStmt);
10938 // 1.2.2 OpenMP Language Terminology
10939 // Structured block - An executable statement with a single entry at the
10940 // top and a single exit at the bottom.
10941 // The point of exit cannot be a branch out of the structured block.
10942 // longjmp() and throw() must not violate the entry/exit criteria.
10943 CS->getCapturedDecl()->setNothrow();
10944 for (int ThisCaptureLevel =
10945 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10946 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10947 CS = cast<CapturedStmt>(CS->getCapturedStmt());
10948 // 1.2.2 OpenMP Language Terminology
10949 // Structured block - An executable statement with a single entry at the
10950 // top and a single exit at the bottom.
10951 // The point of exit cannot be a branch out of the structured block.
10952 // longjmp() and throw() must not violate the entry/exit criteria.
10953 CS->getCapturedDecl()->setNothrow();
10956 OMPLoopDirective::HelperExprs B;
10957 // In presence of clause 'collapse' with number of loops, it will
10958 // define the nested loops number.
10959 unsigned NestedLoopCount = checkOpenMPLoop(
10960 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10961 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10962 VarsWithImplicitDSA, B);
10963 if (NestedLoopCount == 0)
10964 return StmtError();
10966 assert((CurContext->isDependentContext() || B.builtAll()) &&
10967 "omp for loop exprs were not built");
10969 if (!CurContext->isDependentContext()) {
10970 // Finalize the clauses that need pre-built expressions for CodeGen.
10971 for (OMPClause *C : Clauses) {
10972 if (auto *LC = dyn_cast<OMPLinearClause>(C))
10973 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10974 B.NumIterations, *this, CurScope,
10976 return StmtError();
10980 if (checkSimdlenSafelenSpecified(*this, Clauses))
10981 return StmtError();
10983 setFunctionHasBranchProtectedScope();
10984 return OMPDistributeParallelForSimdDirective::Create(
10985 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10988 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
10989 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10990 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10992 return StmtError();
10994 auto *CS = cast<CapturedStmt>(AStmt);
10995 // 1.2.2 OpenMP Language Terminology
10996 // Structured block - An executable statement with a single entry at the
10997 // top and a single exit at the bottom.
10998 // The point of exit cannot be a branch out of the structured block.
10999 // longjmp() and throw() must not violate the entry/exit criteria.
11000 CS->getCapturedDecl()->setNothrow();
11001 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11002 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11003 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11004 // 1.2.2 OpenMP Language Terminology
11005 // Structured block - An executable statement with a single entry at the
11006 // top and a single exit at the bottom.
11007 // The point of exit cannot be a branch out of the structured block.
11008 // longjmp() and throw() must not violate the entry/exit criteria.
11009 CS->getCapturedDecl()->setNothrow();
11012 OMPLoopDirective::HelperExprs B;
11013 // In presence of clause 'collapse' with number of loops, it will
11014 // define the nested loops number.
11015 unsigned NestedLoopCount =
11016 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11017 nullptr /*ordered not a clause on distribute*/, CS, *this,
11018 *DSAStack, VarsWithImplicitDSA, B);
11019 if (NestedLoopCount == 0)
11020 return StmtError();
11022 assert((CurContext->isDependentContext() || B.builtAll()) &&
11023 "omp for loop exprs were not built");
11025 if (!CurContext->isDependentContext()) {
11026 // Finalize the clauses that need pre-built expressions for CodeGen.
11027 for (OMPClause *C : Clauses) {
11028 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11029 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11030 B.NumIterations, *this, CurScope,
11032 return StmtError();
11036 if (checkSimdlenSafelenSpecified(*this, Clauses))
11037 return StmtError();
11039 setFunctionHasBranchProtectedScope();
11040 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11041 NestedLoopCount, Clauses, AStmt, B);
11044 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11045 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11046 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11048 return StmtError();
11050 auto *CS = cast<CapturedStmt>(AStmt);
11051 // 1.2.2 OpenMP Language Terminology
11052 // Structured block - An executable statement with a single entry at the
11053 // top and a single exit at the bottom.
11054 // The point of exit cannot be a branch out of the structured block.
11055 // longjmp() and throw() must not violate the entry/exit criteria.
11056 CS->getCapturedDecl()->setNothrow();
11057 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11058 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11059 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11060 // 1.2.2 OpenMP Language Terminology
11061 // Structured block - An executable statement with a single entry at the
11062 // top and a single exit at the bottom.
11063 // The point of exit cannot be a branch out of the structured block.
11064 // longjmp() and throw() must not violate the entry/exit criteria.
11065 CS->getCapturedDecl()->setNothrow();
11068 OMPLoopDirective::HelperExprs B;
11069 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11070 // define the nested loops number.
11071 unsigned NestedLoopCount = checkOpenMPLoop(
11072 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
11073 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11074 VarsWithImplicitDSA, B);
11075 if (NestedLoopCount == 0)
11076 return StmtError();
11078 assert((CurContext->isDependentContext() || B.builtAll()) &&
11079 "omp target parallel for simd loop exprs were not built");
11081 if (!CurContext->isDependentContext()) {
11082 // Finalize the clauses that need pre-built expressions for CodeGen.
11083 for (OMPClause *C : Clauses) {
11084 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11085 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11086 B.NumIterations, *this, CurScope,
11088 return StmtError();
11091 if (checkSimdlenSafelenSpecified(*this, Clauses))
11092 return StmtError();
11094 setFunctionHasBranchProtectedScope();
11095 return OMPTargetParallelForSimdDirective::Create(
11096 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11099 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
11100 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11101 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11103 return StmtError();
11105 auto *CS = cast<CapturedStmt>(AStmt);
11106 // 1.2.2 OpenMP Language Terminology
11107 // Structured block - An executable statement with a single entry at the
11108 // top and a single exit at the bottom.
11109 // The point of exit cannot be a branch out of the structured block.
11110 // longjmp() and throw() must not violate the entry/exit criteria.
11111 CS->getCapturedDecl()->setNothrow();
11112 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
11113 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11114 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11115 // 1.2.2 OpenMP Language Terminology
11116 // Structured block - An executable statement with a single entry at the
11117 // top and a single exit at the bottom.
11118 // The point of exit cannot be a branch out of the structured block.
11119 // longjmp() and throw() must not violate the entry/exit criteria.
11120 CS->getCapturedDecl()->setNothrow();
11123 OMPLoopDirective::HelperExprs B;
11124 // In presence of clause 'collapse' with number of loops, it will define the
11125 // nested loops number.
11126 unsigned NestedLoopCount =
11127 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
11128 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11129 VarsWithImplicitDSA, B);
11130 if (NestedLoopCount == 0)
11131 return StmtError();
11133 assert((CurContext->isDependentContext() || B.builtAll()) &&
11134 "omp target simd loop exprs were not built");
11136 if (!CurContext->isDependentContext()) {
11137 // Finalize the clauses that need pre-built expressions for CodeGen.
11138 for (OMPClause *C : Clauses) {
11139 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11140 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11141 B.NumIterations, *this, CurScope,
11143 return StmtError();
11147 if (checkSimdlenSafelenSpecified(*this, Clauses))
11148 return StmtError();
11150 setFunctionHasBranchProtectedScope();
11151 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
11152 NestedLoopCount, Clauses, AStmt, B);
11155 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
11156 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11157 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11159 return StmtError();
11161 auto *CS = cast<CapturedStmt>(AStmt);
11162 // 1.2.2 OpenMP Language Terminology
11163 // Structured block - An executable statement with a single entry at the
11164 // top and a single exit at the bottom.
11165 // The point of exit cannot be a branch out of the structured block.
11166 // longjmp() and throw() must not violate the entry/exit criteria.
11167 CS->getCapturedDecl()->setNothrow();
11168 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
11169 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11170 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11171 // 1.2.2 OpenMP Language Terminology
11172 // Structured block - An executable statement with a single entry at the
11173 // top and a single exit at the bottom.
11174 // The point of exit cannot be a branch out of the structured block.
11175 // longjmp() and throw() must not violate the entry/exit criteria.
11176 CS->getCapturedDecl()->setNothrow();
11179 OMPLoopDirective::HelperExprs B;
11180 // In presence of clause 'collapse' with number of loops, it will
11181 // define the nested loops number.
11182 unsigned NestedLoopCount =
11183 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
11184 nullptr /*ordered not a clause on distribute*/, CS, *this,
11185 *DSAStack, VarsWithImplicitDSA, B);
11186 if (NestedLoopCount == 0)
11187 return StmtError();
11189 assert((CurContext->isDependentContext() || B.builtAll()) &&
11190 "omp teams distribute loop exprs were not built");
11192 setFunctionHasBranchProtectedScope();
11194 DSAStack->setParentTeamsRegionLoc(StartLoc);
11196 return OMPTeamsDistributeDirective::Create(
11197 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11200 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
11201 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11202 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11204 return StmtError();
11206 auto *CS = cast<CapturedStmt>(AStmt);
11207 // 1.2.2 OpenMP Language Terminology
11208 // Structured block - An executable statement with a single entry at the
11209 // top and a single exit at the bottom.
11210 // The point of exit cannot be a branch out of the structured block.
11211 // longjmp() and throw() must not violate the entry/exit criteria.
11212 CS->getCapturedDecl()->setNothrow();
11213 for (int ThisCaptureLevel =
11214 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
11215 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11216 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11217 // 1.2.2 OpenMP Language Terminology
11218 // Structured block - An executable statement with a single entry at the
11219 // top and a single exit at the bottom.
11220 // The point of exit cannot be a branch out of the structured block.
11221 // longjmp() and throw() must not violate the entry/exit criteria.
11222 CS->getCapturedDecl()->setNothrow();
11225 OMPLoopDirective::HelperExprs B;
11226 // In presence of clause 'collapse' with number of loops, it will
11227 // define the nested loops number.
11228 unsigned NestedLoopCount = checkOpenMPLoop(
11229 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11230 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11231 VarsWithImplicitDSA, B);
11233 if (NestedLoopCount == 0)
11234 return StmtError();
11236 assert((CurContext->isDependentContext() || B.builtAll()) &&
11237 "omp teams distribute simd loop exprs were not built");
11239 if (!CurContext->isDependentContext()) {
11240 // Finalize the clauses that need pre-built expressions for CodeGen.
11241 for (OMPClause *C : Clauses) {
11242 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11243 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11244 B.NumIterations, *this, CurScope,
11246 return StmtError();
11250 if (checkSimdlenSafelenSpecified(*this, Clauses))
11251 return StmtError();
11253 setFunctionHasBranchProtectedScope();
11255 DSAStack->setParentTeamsRegionLoc(StartLoc);
11257 return OMPTeamsDistributeSimdDirective::Create(
11258 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11261 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
11262 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11263 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11265 return StmtError();
11267 auto *CS = cast<CapturedStmt>(AStmt);
11268 // 1.2.2 OpenMP Language Terminology
11269 // Structured block - An executable statement with a single entry at the
11270 // top and a single exit at the bottom.
11271 // The point of exit cannot be a branch out of the structured block.
11272 // longjmp() and throw() must not violate the entry/exit criteria.
11273 CS->getCapturedDecl()->setNothrow();
11275 for (int ThisCaptureLevel =
11276 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
11277 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11278 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11279 // 1.2.2 OpenMP Language Terminology
11280 // Structured block - An executable statement with a single entry at the
11281 // top and a single exit at the bottom.
11282 // The point of exit cannot be a branch out of the structured block.
11283 // longjmp() and throw() must not violate the entry/exit criteria.
11284 CS->getCapturedDecl()->setNothrow();
11287 OMPLoopDirective::HelperExprs B;
11288 // In presence of clause 'collapse' with number of loops, it will
11289 // define the nested loops number.
11290 unsigned NestedLoopCount = checkOpenMPLoop(
11291 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11292 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11293 VarsWithImplicitDSA, B);
11295 if (NestedLoopCount == 0)
11296 return StmtError();
11298 assert((CurContext->isDependentContext() || B.builtAll()) &&
11299 "omp for loop exprs were not built");
11301 if (!CurContext->isDependentContext()) {
11302 // Finalize the clauses that need pre-built expressions for CodeGen.
11303 for (OMPClause *C : Clauses) {
11304 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11305 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11306 B.NumIterations, *this, CurScope,
11308 return StmtError();
11312 if (checkSimdlenSafelenSpecified(*this, Clauses))
11313 return StmtError();
11315 setFunctionHasBranchProtectedScope();
11317 DSAStack->setParentTeamsRegionLoc(StartLoc);
11319 return OMPTeamsDistributeParallelForSimdDirective::Create(
11320 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11323 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
11324 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11325 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11327 return StmtError();
11329 auto *CS = cast<CapturedStmt>(AStmt);
11330 // 1.2.2 OpenMP Language Terminology
11331 // Structured block - An executable statement with a single entry at the
11332 // top and a single exit at the bottom.
11333 // The point of exit cannot be a branch out of the structured block.
11334 // longjmp() and throw() must not violate the entry/exit criteria.
11335 CS->getCapturedDecl()->setNothrow();
11337 for (int ThisCaptureLevel =
11338 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
11339 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11340 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11341 // 1.2.2 OpenMP Language Terminology
11342 // Structured block - An executable statement with a single entry at the
11343 // top and a single exit at the bottom.
11344 // The point of exit cannot be a branch out of the structured block.
11345 // longjmp() and throw() must not violate the entry/exit criteria.
11346 CS->getCapturedDecl()->setNothrow();
11349 OMPLoopDirective::HelperExprs B;
11350 // In presence of clause 'collapse' with number of loops, it will
11351 // define the nested loops number.
11352 unsigned NestedLoopCount = checkOpenMPLoop(
11353 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11354 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11355 VarsWithImplicitDSA, B);
11357 if (NestedLoopCount == 0)
11358 return StmtError();
11360 assert((CurContext->isDependentContext() || B.builtAll()) &&
11361 "omp for loop exprs were not built");
11363 setFunctionHasBranchProtectedScope();
11365 DSAStack->setParentTeamsRegionLoc(StartLoc);
11367 return OMPTeamsDistributeParallelForDirective::Create(
11368 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11369 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11372 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
11374 SourceLocation StartLoc,
11375 SourceLocation EndLoc) {
11377 return StmtError();
11379 auto *CS = cast<CapturedStmt>(AStmt);
11380 // 1.2.2 OpenMP Language Terminology
11381 // Structured block - An executable statement with a single entry at the
11382 // top and a single exit at the bottom.
11383 // The point of exit cannot be a branch out of the structured block.
11384 // longjmp() and throw() must not violate the entry/exit criteria.
11385 CS->getCapturedDecl()->setNothrow();
11387 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
11388 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11389 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11390 // 1.2.2 OpenMP Language Terminology
11391 // Structured block - An executable statement with a single entry at the
11392 // top and a single exit at the bottom.
11393 // The point of exit cannot be a branch out of the structured block.
11394 // longjmp() and throw() must not violate the entry/exit criteria.
11395 CS->getCapturedDecl()->setNothrow();
11397 setFunctionHasBranchProtectedScope();
11399 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
11403 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
11404 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11405 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11407 return StmtError();
11409 auto *CS = cast<CapturedStmt>(AStmt);
11410 // 1.2.2 OpenMP Language Terminology
11411 // Structured block - An executable statement with a single entry at the
11412 // top and a single exit at the bottom.
11413 // The point of exit cannot be a branch out of the structured block.
11414 // longjmp() and throw() must not violate the entry/exit criteria.
11415 CS->getCapturedDecl()->setNothrow();
11416 for (int ThisCaptureLevel =
11417 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
11418 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11419 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11420 // 1.2.2 OpenMP Language Terminology
11421 // Structured block - An executable statement with a single entry at the
11422 // top and a single exit at the bottom.
11423 // The point of exit cannot be a branch out of the structured block.
11424 // longjmp() and throw() must not violate the entry/exit criteria.
11425 CS->getCapturedDecl()->setNothrow();
11428 OMPLoopDirective::HelperExprs B;
11429 // In presence of clause 'collapse' with number of loops, it will
11430 // define the nested loops number.
11431 unsigned NestedLoopCount = checkOpenMPLoop(
11432 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
11433 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11434 VarsWithImplicitDSA, B);
11435 if (NestedLoopCount == 0)
11436 return StmtError();
11438 assert((CurContext->isDependentContext() || B.builtAll()) &&
11439 "omp target teams distribute loop exprs were not built");
11441 setFunctionHasBranchProtectedScope();
11442 return OMPTargetTeamsDistributeDirective::Create(
11443 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11446 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
11447 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11448 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11450 return StmtError();
11452 auto *CS = cast<CapturedStmt>(AStmt);
11453 // 1.2.2 OpenMP Language Terminology
11454 // Structured block - An executable statement with a single entry at the
11455 // top and a single exit at the bottom.
11456 // The point of exit cannot be a branch out of the structured block.
11457 // longjmp() and throw() must not violate the entry/exit criteria.
11458 CS->getCapturedDecl()->setNothrow();
11459 for (int ThisCaptureLevel =
11460 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
11461 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11462 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11463 // 1.2.2 OpenMP Language Terminology
11464 // Structured block - An executable statement with a single entry at the
11465 // top and a single exit at the bottom.
11466 // The point of exit cannot be a branch out of the structured block.
11467 // longjmp() and throw() must not violate the entry/exit criteria.
11468 CS->getCapturedDecl()->setNothrow();
11471 OMPLoopDirective::HelperExprs B;
11472 // In presence of clause 'collapse' with number of loops, it will
11473 // define the nested loops number.
11474 unsigned NestedLoopCount = checkOpenMPLoop(
11475 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11476 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11477 VarsWithImplicitDSA, B);
11478 if (NestedLoopCount == 0)
11479 return StmtError();
11481 assert((CurContext->isDependentContext() || B.builtAll()) &&
11482 "omp target teams distribute parallel for loop exprs were not built");
11484 if (!CurContext->isDependentContext()) {
11485 // Finalize the clauses that need pre-built expressions for CodeGen.
11486 for (OMPClause *C : Clauses) {
11487 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11488 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11489 B.NumIterations, *this, CurScope,
11491 return StmtError();
11495 setFunctionHasBranchProtectedScope();
11496 return OMPTargetTeamsDistributeParallelForDirective::Create(
11497 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11498 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11501 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
11502 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11503 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11505 return StmtError();
11507 auto *CS = cast<CapturedStmt>(AStmt);
11508 // 1.2.2 OpenMP Language Terminology
11509 // Structured block - An executable statement with a single entry at the
11510 // top and a single exit at the bottom.
11511 // The point of exit cannot be a branch out of the structured block.
11512 // longjmp() and throw() must not violate the entry/exit criteria.
11513 CS->getCapturedDecl()->setNothrow();
11514 for (int ThisCaptureLevel = getOpenMPCaptureLevels(
11515 OMPD_target_teams_distribute_parallel_for_simd);
11516 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11517 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11518 // 1.2.2 OpenMP Language Terminology
11519 // Structured block - An executable statement with a single entry at the
11520 // top and a single exit at the bottom.
11521 // The point of exit cannot be a branch out of the structured block.
11522 // longjmp() and throw() must not violate the entry/exit criteria.
11523 CS->getCapturedDecl()->setNothrow();
11526 OMPLoopDirective::HelperExprs B;
11527 // In presence of clause 'collapse' with number of loops, it will
11528 // define the nested loops number.
11529 unsigned NestedLoopCount =
11530 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
11531 getCollapseNumberExpr(Clauses),
11532 nullptr /*ordered not a clause on distribute*/, CS, *this,
11533 *DSAStack, VarsWithImplicitDSA, B);
11534 if (NestedLoopCount == 0)
11535 return StmtError();
11537 assert((CurContext->isDependentContext() || B.builtAll()) &&
11538 "omp target teams distribute parallel for simd loop exprs were not "
11541 if (!CurContext->isDependentContext()) {
11542 // Finalize the clauses that need pre-built expressions for CodeGen.
11543 for (OMPClause *C : Clauses) {
11544 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11545 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11546 B.NumIterations, *this, CurScope,
11548 return StmtError();
11552 if (checkSimdlenSafelenSpecified(*this, Clauses))
11553 return StmtError();
11555 setFunctionHasBranchProtectedScope();
11556 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
11557 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11560 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
11561 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11562 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11564 return StmtError();
11566 auto *CS = cast<CapturedStmt>(AStmt);
11567 // 1.2.2 OpenMP Language Terminology
11568 // Structured block - An executable statement with a single entry at the
11569 // top and a single exit at the bottom.
11570 // The point of exit cannot be a branch out of the structured block.
11571 // longjmp() and throw() must not violate the entry/exit criteria.
11572 CS->getCapturedDecl()->setNothrow();
11573 for (int ThisCaptureLevel =
11574 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
11575 ThisCaptureLevel > 1; --ThisCaptureLevel) {
11576 CS = cast<CapturedStmt>(CS->getCapturedStmt());
11577 // 1.2.2 OpenMP Language Terminology
11578 // Structured block - An executable statement with a single entry at the
11579 // top and a single exit at the bottom.
11580 // The point of exit cannot be a branch out of the structured block.
11581 // longjmp() and throw() must not violate the entry/exit criteria.
11582 CS->getCapturedDecl()->setNothrow();
11585 OMPLoopDirective::HelperExprs B;
11586 // In presence of clause 'collapse' with number of loops, it will
11587 // define the nested loops number.
11588 unsigned NestedLoopCount = checkOpenMPLoop(
11589 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
11590 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11591 VarsWithImplicitDSA, B);
11592 if (NestedLoopCount == 0)
11593 return StmtError();
11595 assert((CurContext->isDependentContext() || B.builtAll()) &&
11596 "omp target teams distribute simd loop exprs were not built");
11598 if (!CurContext->isDependentContext()) {
11599 // Finalize the clauses that need pre-built expressions for CodeGen.
11600 for (OMPClause *C : Clauses) {
11601 if (auto *LC = dyn_cast<OMPLinearClause>(C))
11602 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11603 B.NumIterations, *this, CurScope,
11605 return StmtError();
11609 if (checkSimdlenSafelenSpecified(*this, Clauses))
11610 return StmtError();
11612 setFunctionHasBranchProtectedScope();
11613 return OMPTargetTeamsDistributeSimdDirective::Create(
11614 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11617 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
11618 SourceLocation StartLoc,
11619 SourceLocation LParenLoc,
11620 SourceLocation EndLoc) {
11621 OMPClause *Res = nullptr;
11624 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
11626 case OMPC_num_threads:
11627 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
11630 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
11633 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
11635 case OMPC_allocator:
11636 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
11638 case OMPC_collapse:
11639 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
11642 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
11644 case OMPC_num_teams:
11645 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
11647 case OMPC_thread_limit:
11648 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
11650 case OMPC_priority:
11651 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
11653 case OMPC_grainsize:
11654 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
11656 case OMPC_num_tasks:
11657 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
11660 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
11663 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
11666 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
11671 case OMPC_proc_bind:
11672 case OMPC_schedule:
11674 case OMPC_firstprivate:
11675 case OMPC_lastprivate:
11677 case OMPC_reduction:
11678 case OMPC_task_reduction:
11679 case OMPC_in_reduction:
11683 case OMPC_copyprivate:
11686 case OMPC_mergeable:
11687 case OMPC_threadprivate:
11688 case OMPC_allocate:
11704 case OMPC_dist_schedule:
11705 case OMPC_defaultmap:
11710 case OMPC_use_device_ptr:
11711 case OMPC_use_device_addr:
11712 case OMPC_is_device_ptr:
11713 case OMPC_unified_address:
11714 case OMPC_unified_shared_memory:
11715 case OMPC_reverse_offload:
11716 case OMPC_dynamic_allocators:
11717 case OMPC_atomic_default_mem_order:
11718 case OMPC_device_type:
11720 case OMPC_nontemporal:
11723 case OMPC_inclusive:
11724 case OMPC_exclusive:
11725 case OMPC_uses_allocators:
11726 case OMPC_affinity:
11728 llvm_unreachable("Clause is not allowed.");
11733 // An OpenMP directive such as 'target parallel' has two captured regions:
11734 // for the 'target' and 'parallel' respectively. This function returns
11735 // the region in which to capture expressions associated with a clause.
11736 // A return value of OMPD_unknown signifies that the expression should not
11738 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
11739 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
11740 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
11741 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11745 case OMPD_target_parallel_for_simd:
11746 if (OpenMPVersion >= 50 &&
11747 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11748 CaptureRegion = OMPD_parallel;
11752 case OMPD_target_parallel:
11753 case OMPD_target_parallel_for:
11754 // If this clause applies to the nested 'parallel' region, capture within
11755 // the 'target' region, otherwise do not capture.
11756 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11757 CaptureRegion = OMPD_target;
11759 case OMPD_target_teams_distribute_parallel_for_simd:
11760 if (OpenMPVersion >= 50 &&
11761 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11762 CaptureRegion = OMPD_parallel;
11766 case OMPD_target_teams_distribute_parallel_for:
11767 // If this clause applies to the nested 'parallel' region, capture within
11768 // the 'teams' region, otherwise do not capture.
11769 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
11770 CaptureRegion = OMPD_teams;
11772 case OMPD_teams_distribute_parallel_for_simd:
11773 if (OpenMPVersion >= 50 &&
11774 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
11775 CaptureRegion = OMPD_parallel;
11779 case OMPD_teams_distribute_parallel_for:
11780 CaptureRegion = OMPD_teams;
11782 case OMPD_target_update:
11783 case OMPD_target_enter_data:
11784 case OMPD_target_exit_data:
11785 CaptureRegion = OMPD_task;
11787 case OMPD_parallel_master_taskloop:
11788 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
11789 CaptureRegion = OMPD_parallel;
11791 case OMPD_parallel_master_taskloop_simd:
11792 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
11793 NameModifier == OMPD_taskloop) {
11794 CaptureRegion = OMPD_parallel;
11797 if (OpenMPVersion <= 45)
11799 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11800 CaptureRegion = OMPD_taskloop;
11802 case OMPD_parallel_for_simd:
11803 if (OpenMPVersion <= 45)
11805 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11806 CaptureRegion = OMPD_parallel;
11808 case OMPD_taskloop_simd:
11809 case OMPD_master_taskloop_simd:
11810 if (OpenMPVersion <= 45)
11812 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11813 CaptureRegion = OMPD_taskloop;
11815 case OMPD_distribute_parallel_for_simd:
11816 if (OpenMPVersion <= 45)
11818 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
11819 CaptureRegion = OMPD_parallel;
11821 case OMPD_target_simd:
11822 if (OpenMPVersion >= 50 &&
11823 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11824 CaptureRegion = OMPD_target;
11826 case OMPD_teams_distribute_simd:
11827 case OMPD_target_teams_distribute_simd:
11828 if (OpenMPVersion >= 50 &&
11829 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
11830 CaptureRegion = OMPD_teams;
11833 case OMPD_parallel:
11834 case OMPD_parallel_master:
11835 case OMPD_parallel_sections:
11836 case OMPD_parallel_for:
11838 case OMPD_target_teams:
11839 case OMPD_target_teams_distribute:
11840 case OMPD_distribute_parallel_for:
11842 case OMPD_taskloop:
11843 case OMPD_master_taskloop:
11844 case OMPD_target_data:
11846 case OMPD_for_simd:
11847 case OMPD_distribute_simd:
11848 // Do not capture if-clause expressions.
11850 case OMPD_threadprivate:
11851 case OMPD_allocate:
11852 case OMPD_taskyield:
11854 case OMPD_taskwait:
11855 case OMPD_cancellation_point:
11859 case OMPD_declare_reduction:
11860 case OMPD_declare_mapper:
11861 case OMPD_declare_simd:
11862 case OMPD_declare_variant:
11863 case OMPD_begin_declare_variant:
11864 case OMPD_end_declare_variant:
11865 case OMPD_declare_target:
11866 case OMPD_end_declare_target:
11869 case OMPD_sections:
11873 case OMPD_critical:
11874 case OMPD_taskgroup:
11875 case OMPD_distribute:
11878 case OMPD_teams_distribute:
11879 case OMPD_requires:
11880 llvm_unreachable("Unexpected OpenMP directive with if-clause");
11883 llvm_unreachable("Unknown OpenMP directive");
11886 case OMPC_num_threads:
11888 case OMPD_target_parallel:
11889 case OMPD_target_parallel_for:
11890 case OMPD_target_parallel_for_simd:
11891 CaptureRegion = OMPD_target;
11893 case OMPD_teams_distribute_parallel_for:
11894 case OMPD_teams_distribute_parallel_for_simd:
11895 case OMPD_target_teams_distribute_parallel_for:
11896 case OMPD_target_teams_distribute_parallel_for_simd:
11897 CaptureRegion = OMPD_teams;
11899 case OMPD_parallel:
11900 case OMPD_parallel_master:
11901 case OMPD_parallel_sections:
11902 case OMPD_parallel_for:
11903 case OMPD_parallel_for_simd:
11904 case OMPD_distribute_parallel_for:
11905 case OMPD_distribute_parallel_for_simd:
11906 case OMPD_parallel_master_taskloop:
11907 case OMPD_parallel_master_taskloop_simd:
11908 // Do not capture num_threads-clause expressions.
11910 case OMPD_target_data:
11911 case OMPD_target_enter_data:
11912 case OMPD_target_exit_data:
11913 case OMPD_target_update:
11915 case OMPD_target_simd:
11916 case OMPD_target_teams:
11917 case OMPD_target_teams_distribute:
11918 case OMPD_target_teams_distribute_simd:
11921 case OMPD_taskloop:
11922 case OMPD_taskloop_simd:
11923 case OMPD_master_taskloop:
11924 case OMPD_master_taskloop_simd:
11925 case OMPD_threadprivate:
11926 case OMPD_allocate:
11927 case OMPD_taskyield:
11929 case OMPD_taskwait:
11930 case OMPD_cancellation_point:
11934 case OMPD_declare_reduction:
11935 case OMPD_declare_mapper:
11936 case OMPD_declare_simd:
11937 case OMPD_declare_variant:
11938 case OMPD_begin_declare_variant:
11939 case OMPD_end_declare_variant:
11940 case OMPD_declare_target:
11941 case OMPD_end_declare_target:
11945 case OMPD_for_simd:
11946 case OMPD_sections:
11950 case OMPD_critical:
11951 case OMPD_taskgroup:
11952 case OMPD_distribute:
11955 case OMPD_distribute_simd:
11956 case OMPD_teams_distribute:
11957 case OMPD_teams_distribute_simd:
11958 case OMPD_requires:
11959 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
11962 llvm_unreachable("Unknown OpenMP directive");
11965 case OMPC_num_teams:
11967 case OMPD_target_teams:
11968 case OMPD_target_teams_distribute:
11969 case OMPD_target_teams_distribute_simd:
11970 case OMPD_target_teams_distribute_parallel_for:
11971 case OMPD_target_teams_distribute_parallel_for_simd:
11972 CaptureRegion = OMPD_target;
11974 case OMPD_teams_distribute_parallel_for:
11975 case OMPD_teams_distribute_parallel_for_simd:
11977 case OMPD_teams_distribute:
11978 case OMPD_teams_distribute_simd:
11979 // Do not capture num_teams-clause expressions.
11981 case OMPD_distribute_parallel_for:
11982 case OMPD_distribute_parallel_for_simd:
11984 case OMPD_taskloop:
11985 case OMPD_taskloop_simd:
11986 case OMPD_master_taskloop:
11987 case OMPD_master_taskloop_simd:
11988 case OMPD_parallel_master_taskloop:
11989 case OMPD_parallel_master_taskloop_simd:
11990 case OMPD_target_data:
11991 case OMPD_target_enter_data:
11992 case OMPD_target_exit_data:
11993 case OMPD_target_update:
11995 case OMPD_parallel:
11996 case OMPD_parallel_master:
11997 case OMPD_parallel_sections:
11998 case OMPD_parallel_for:
11999 case OMPD_parallel_for_simd:
12001 case OMPD_target_simd:
12002 case OMPD_target_parallel:
12003 case OMPD_target_parallel_for:
12004 case OMPD_target_parallel_for_simd:
12005 case OMPD_threadprivate:
12006 case OMPD_allocate:
12007 case OMPD_taskyield:
12009 case OMPD_taskwait:
12010 case OMPD_cancellation_point:
12014 case OMPD_declare_reduction:
12015 case OMPD_declare_mapper:
12016 case OMPD_declare_simd:
12017 case OMPD_declare_variant:
12018 case OMPD_begin_declare_variant:
12019 case OMPD_end_declare_variant:
12020 case OMPD_declare_target:
12021 case OMPD_end_declare_target:
12024 case OMPD_for_simd:
12025 case OMPD_sections:
12029 case OMPD_critical:
12030 case OMPD_taskgroup:
12031 case OMPD_distribute:
12034 case OMPD_distribute_simd:
12035 case OMPD_requires:
12036 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12039 llvm_unreachable("Unknown OpenMP directive");
12042 case OMPC_thread_limit:
12044 case OMPD_target_teams:
12045 case OMPD_target_teams_distribute:
12046 case OMPD_target_teams_distribute_simd:
12047 case OMPD_target_teams_distribute_parallel_for:
12048 case OMPD_target_teams_distribute_parallel_for_simd:
12049 CaptureRegion = OMPD_target;
12051 case OMPD_teams_distribute_parallel_for:
12052 case OMPD_teams_distribute_parallel_for_simd:
12054 case OMPD_teams_distribute:
12055 case OMPD_teams_distribute_simd:
12056 // Do not capture thread_limit-clause expressions.
12058 case OMPD_distribute_parallel_for:
12059 case OMPD_distribute_parallel_for_simd:
12061 case OMPD_taskloop:
12062 case OMPD_taskloop_simd:
12063 case OMPD_master_taskloop:
12064 case OMPD_master_taskloop_simd:
12065 case OMPD_parallel_master_taskloop:
12066 case OMPD_parallel_master_taskloop_simd:
12067 case OMPD_target_data:
12068 case OMPD_target_enter_data:
12069 case OMPD_target_exit_data:
12070 case OMPD_target_update:
12072 case OMPD_parallel:
12073 case OMPD_parallel_master:
12074 case OMPD_parallel_sections:
12075 case OMPD_parallel_for:
12076 case OMPD_parallel_for_simd:
12078 case OMPD_target_simd:
12079 case OMPD_target_parallel:
12080 case OMPD_target_parallel_for:
12081 case OMPD_target_parallel_for_simd:
12082 case OMPD_threadprivate:
12083 case OMPD_allocate:
12084 case OMPD_taskyield:
12086 case OMPD_taskwait:
12087 case OMPD_cancellation_point:
12091 case OMPD_declare_reduction:
12092 case OMPD_declare_mapper:
12093 case OMPD_declare_simd:
12094 case OMPD_declare_variant:
12095 case OMPD_begin_declare_variant:
12096 case OMPD_end_declare_variant:
12097 case OMPD_declare_target:
12098 case OMPD_end_declare_target:
12101 case OMPD_for_simd:
12102 case OMPD_sections:
12106 case OMPD_critical:
12107 case OMPD_taskgroup:
12108 case OMPD_distribute:
12111 case OMPD_distribute_simd:
12112 case OMPD_requires:
12113 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
12116 llvm_unreachable("Unknown OpenMP directive");
12119 case OMPC_schedule:
12121 case OMPD_parallel_for:
12122 case OMPD_parallel_for_simd:
12123 case OMPD_distribute_parallel_for:
12124 case OMPD_distribute_parallel_for_simd:
12125 case OMPD_teams_distribute_parallel_for:
12126 case OMPD_teams_distribute_parallel_for_simd:
12127 case OMPD_target_parallel_for:
12128 case OMPD_target_parallel_for_simd:
12129 case OMPD_target_teams_distribute_parallel_for:
12130 case OMPD_target_teams_distribute_parallel_for_simd:
12131 CaptureRegion = OMPD_parallel;
12134 case OMPD_for_simd:
12135 // Do not capture schedule-clause expressions.
12138 case OMPD_taskloop:
12139 case OMPD_taskloop_simd:
12140 case OMPD_master_taskloop:
12141 case OMPD_master_taskloop_simd:
12142 case OMPD_parallel_master_taskloop:
12143 case OMPD_parallel_master_taskloop_simd:
12144 case OMPD_target_data:
12145 case OMPD_target_enter_data:
12146 case OMPD_target_exit_data:
12147 case OMPD_target_update:
12149 case OMPD_teams_distribute:
12150 case OMPD_teams_distribute_simd:
12151 case OMPD_target_teams_distribute:
12152 case OMPD_target_teams_distribute_simd:
12154 case OMPD_target_simd:
12155 case OMPD_target_parallel:
12157 case OMPD_parallel:
12158 case OMPD_parallel_master:
12159 case OMPD_parallel_sections:
12160 case OMPD_threadprivate:
12161 case OMPD_allocate:
12162 case OMPD_taskyield:
12164 case OMPD_taskwait:
12165 case OMPD_cancellation_point:
12169 case OMPD_declare_reduction:
12170 case OMPD_declare_mapper:
12171 case OMPD_declare_simd:
12172 case OMPD_declare_variant:
12173 case OMPD_begin_declare_variant:
12174 case OMPD_end_declare_variant:
12175 case OMPD_declare_target:
12176 case OMPD_end_declare_target:
12178 case OMPD_sections:
12182 case OMPD_critical:
12183 case OMPD_taskgroup:
12184 case OMPD_distribute:
12187 case OMPD_distribute_simd:
12188 case OMPD_target_teams:
12189 case OMPD_requires:
12190 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12193 llvm_unreachable("Unknown OpenMP directive");
12196 case OMPC_dist_schedule:
12198 case OMPD_teams_distribute_parallel_for:
12199 case OMPD_teams_distribute_parallel_for_simd:
12200 case OMPD_teams_distribute:
12201 case OMPD_teams_distribute_simd:
12202 case OMPD_target_teams_distribute_parallel_for:
12203 case OMPD_target_teams_distribute_parallel_for_simd:
12204 case OMPD_target_teams_distribute:
12205 case OMPD_target_teams_distribute_simd:
12206 CaptureRegion = OMPD_teams;
12208 case OMPD_distribute_parallel_for:
12209 case OMPD_distribute_parallel_for_simd:
12210 case OMPD_distribute:
12211 case OMPD_distribute_simd:
12212 // Do not capture thread_limit-clause expressions.
12214 case OMPD_parallel_for:
12215 case OMPD_parallel_for_simd:
12216 case OMPD_target_parallel_for_simd:
12217 case OMPD_target_parallel_for:
12219 case OMPD_taskloop:
12220 case OMPD_taskloop_simd:
12221 case OMPD_master_taskloop:
12222 case OMPD_master_taskloop_simd:
12223 case OMPD_parallel_master_taskloop:
12224 case OMPD_parallel_master_taskloop_simd:
12225 case OMPD_target_data:
12226 case OMPD_target_enter_data:
12227 case OMPD_target_exit_data:
12228 case OMPD_target_update:
12231 case OMPD_target_simd:
12232 case OMPD_target_parallel:
12234 case OMPD_parallel:
12235 case OMPD_parallel_master:
12236 case OMPD_parallel_sections:
12237 case OMPD_threadprivate:
12238 case OMPD_allocate:
12239 case OMPD_taskyield:
12241 case OMPD_taskwait:
12242 case OMPD_cancellation_point:
12246 case OMPD_declare_reduction:
12247 case OMPD_declare_mapper:
12248 case OMPD_declare_simd:
12249 case OMPD_declare_variant:
12250 case OMPD_begin_declare_variant:
12251 case OMPD_end_declare_variant:
12252 case OMPD_declare_target:
12253 case OMPD_end_declare_target:
12256 case OMPD_for_simd:
12257 case OMPD_sections:
12261 case OMPD_critical:
12262 case OMPD_taskgroup:
12265 case OMPD_target_teams:
12266 case OMPD_requires:
12267 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
12270 llvm_unreachable("Unknown OpenMP directive");
12275 case OMPD_target_update:
12276 case OMPD_target_enter_data:
12277 case OMPD_target_exit_data:
12279 case OMPD_target_simd:
12280 case OMPD_target_teams:
12281 case OMPD_target_parallel:
12282 case OMPD_target_teams_distribute:
12283 case OMPD_target_teams_distribute_simd:
12284 case OMPD_target_parallel_for:
12285 case OMPD_target_parallel_for_simd:
12286 case OMPD_target_teams_distribute_parallel_for:
12287 case OMPD_target_teams_distribute_parallel_for_simd:
12288 CaptureRegion = OMPD_task;
12290 case OMPD_target_data:
12291 // Do not capture device-clause expressions.
12293 case OMPD_teams_distribute_parallel_for:
12294 case OMPD_teams_distribute_parallel_for_simd:
12296 case OMPD_teams_distribute:
12297 case OMPD_teams_distribute_simd:
12298 case OMPD_distribute_parallel_for:
12299 case OMPD_distribute_parallel_for_simd:
12301 case OMPD_taskloop:
12302 case OMPD_taskloop_simd:
12303 case OMPD_master_taskloop:
12304 case OMPD_master_taskloop_simd:
12305 case OMPD_parallel_master_taskloop:
12306 case OMPD_parallel_master_taskloop_simd:
12308 case OMPD_parallel:
12309 case OMPD_parallel_master:
12310 case OMPD_parallel_sections:
12311 case OMPD_parallel_for:
12312 case OMPD_parallel_for_simd:
12313 case OMPD_threadprivate:
12314 case OMPD_allocate:
12315 case OMPD_taskyield:
12317 case OMPD_taskwait:
12318 case OMPD_cancellation_point:
12322 case OMPD_declare_reduction:
12323 case OMPD_declare_mapper:
12324 case OMPD_declare_simd:
12325 case OMPD_declare_variant:
12326 case OMPD_begin_declare_variant:
12327 case OMPD_end_declare_variant:
12328 case OMPD_declare_target:
12329 case OMPD_end_declare_target:
12332 case OMPD_for_simd:
12333 case OMPD_sections:
12337 case OMPD_critical:
12338 case OMPD_taskgroup:
12339 case OMPD_distribute:
12342 case OMPD_distribute_simd:
12343 case OMPD_requires:
12344 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
12347 llvm_unreachable("Unknown OpenMP directive");
12350 case OMPC_grainsize:
12351 case OMPC_num_tasks:
12353 case OMPC_priority:
12356 case OMPD_taskloop:
12357 case OMPD_taskloop_simd:
12358 case OMPD_master_taskloop:
12359 case OMPD_master_taskloop_simd:
12361 case OMPD_parallel_master_taskloop:
12362 case OMPD_parallel_master_taskloop_simd:
12363 CaptureRegion = OMPD_parallel;
12365 case OMPD_target_update:
12366 case OMPD_target_enter_data:
12367 case OMPD_target_exit_data:
12369 case OMPD_target_simd:
12370 case OMPD_target_teams:
12371 case OMPD_target_parallel:
12372 case OMPD_target_teams_distribute:
12373 case OMPD_target_teams_distribute_simd:
12374 case OMPD_target_parallel_for:
12375 case OMPD_target_parallel_for_simd:
12376 case OMPD_target_teams_distribute_parallel_for:
12377 case OMPD_target_teams_distribute_parallel_for_simd:
12378 case OMPD_target_data:
12379 case OMPD_teams_distribute_parallel_for:
12380 case OMPD_teams_distribute_parallel_for_simd:
12382 case OMPD_teams_distribute:
12383 case OMPD_teams_distribute_simd:
12384 case OMPD_distribute_parallel_for:
12385 case OMPD_distribute_parallel_for_simd:
12387 case OMPD_parallel:
12388 case OMPD_parallel_master:
12389 case OMPD_parallel_sections:
12390 case OMPD_parallel_for:
12391 case OMPD_parallel_for_simd:
12392 case OMPD_threadprivate:
12393 case OMPD_allocate:
12394 case OMPD_taskyield:
12396 case OMPD_taskwait:
12397 case OMPD_cancellation_point:
12401 case OMPD_declare_reduction:
12402 case OMPD_declare_mapper:
12403 case OMPD_declare_simd:
12404 case OMPD_declare_variant:
12405 case OMPD_begin_declare_variant:
12406 case OMPD_end_declare_variant:
12407 case OMPD_declare_target:
12408 case OMPD_end_declare_target:
12411 case OMPD_for_simd:
12412 case OMPD_sections:
12416 case OMPD_critical:
12417 case OMPD_taskgroup:
12418 case OMPD_distribute:
12421 case OMPD_distribute_simd:
12422 case OMPD_requires:
12423 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
12426 llvm_unreachable("Unknown OpenMP directive");
12429 case OMPC_firstprivate:
12430 case OMPC_lastprivate:
12431 case OMPC_reduction:
12432 case OMPC_task_reduction:
12433 case OMPC_in_reduction:
12436 case OMPC_proc_bind:
12439 case OMPC_allocator:
12440 case OMPC_collapse:
12445 case OMPC_copyprivate:
12449 case OMPC_mergeable:
12450 case OMPC_threadprivate:
12451 case OMPC_allocate:
12469 case OMPC_defaultmap:
12474 case OMPC_use_device_ptr:
12475 case OMPC_use_device_addr:
12476 case OMPC_is_device_ptr:
12477 case OMPC_unified_address:
12478 case OMPC_unified_shared_memory:
12479 case OMPC_reverse_offload:
12480 case OMPC_dynamic_allocators:
12481 case OMPC_atomic_default_mem_order:
12482 case OMPC_device_type:
12484 case OMPC_nontemporal:
12488 case OMPC_inclusive:
12489 case OMPC_exclusive:
12490 case OMPC_uses_allocators:
12491 case OMPC_affinity:
12493 llvm_unreachable("Unexpected OpenMP clause.");
12495 return CaptureRegion;
12498 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
12499 Expr *Condition, SourceLocation StartLoc,
12500 SourceLocation LParenLoc,
12501 SourceLocation NameModifierLoc,
12502 SourceLocation ColonLoc,
12503 SourceLocation EndLoc) {
12504 Expr *ValExpr = Condition;
12505 Stmt *HelperValStmt = nullptr;
12506 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12507 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12508 !Condition->isInstantiationDependent() &&
12509 !Condition->containsUnexpandedParameterPack()) {
12510 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12511 if (Val.isInvalid())
12514 ValExpr = Val.get();
12516 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12517 CaptureRegion = getOpenMPCaptureRegionForClause(
12518 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
12519 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12520 ValExpr = MakeFullExpr(ValExpr).get();
12521 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12522 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12523 HelperValStmt = buildPreInits(Context, Captures);
12527 return new (Context)
12528 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
12529 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
12532 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
12533 SourceLocation StartLoc,
12534 SourceLocation LParenLoc,
12535 SourceLocation EndLoc) {
12536 Expr *ValExpr = Condition;
12537 Stmt *HelperValStmt = nullptr;
12538 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12539 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
12540 !Condition->isInstantiationDependent() &&
12541 !Condition->containsUnexpandedParameterPack()) {
12542 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
12543 if (Val.isInvalid())
12546 ValExpr = MakeFullExpr(Val.get()).get();
12548 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12550 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
12551 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12552 ValExpr = MakeFullExpr(ValExpr).get();
12553 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12554 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12555 HelperValStmt = buildPreInits(Context, Captures);
12559 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
12560 StartLoc, LParenLoc, EndLoc);
12563 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
12566 return ExprError();
12568 class IntConvertDiagnoser : public ICEConvertDiagnoser {
12570 IntConvertDiagnoser()
12571 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
12572 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
12573 QualType T) override {
12574 return S.Diag(Loc, diag::err_omp_not_integral) << T;
12576 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
12577 QualType T) override {
12578 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
12580 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
12582 QualType ConvTy) override {
12583 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
12585 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
12586 QualType ConvTy) override {
12587 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12588 << ConvTy->isEnumeralType() << ConvTy;
12590 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
12591 QualType T) override {
12592 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
12594 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
12595 QualType ConvTy) override {
12596 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
12597 << ConvTy->isEnumeralType() << ConvTy;
12599 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
12600 QualType) override {
12601 llvm_unreachable("conversion functions are permitted");
12603 } ConvertDiagnoser;
12604 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
12608 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
12609 bool StrictlyPositive, bool BuildCapture = false,
12610 OpenMPDirectiveKind DKind = OMPD_unknown,
12611 OpenMPDirectiveKind *CaptureRegion = nullptr,
12612 Stmt **HelperValStmt = nullptr) {
12613 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
12614 !ValExpr->isInstantiationDependent()) {
12615 SourceLocation Loc = ValExpr->getExprLoc();
12617 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
12618 if (Value.isInvalid())
12621 ValExpr = Value.get();
12622 // The expression must evaluate to a non-negative integer value.
12623 llvm::APSInt Result;
12624 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
12625 Result.isSigned() &&
12626 !((!StrictlyPositive && Result.isNonNegative()) ||
12627 (StrictlyPositive && Result.isStrictlyPositive()))) {
12628 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
12629 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12630 << ValExpr->getSourceRange();
12636 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
12637 if (*CaptureRegion != OMPD_unknown &&
12638 !SemaRef.CurContext->isDependentContext()) {
12639 ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
12640 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12641 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
12642 *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
12648 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
12649 SourceLocation StartLoc,
12650 SourceLocation LParenLoc,
12651 SourceLocation EndLoc) {
12652 Expr *ValExpr = NumThreads;
12653 Stmt *HelperValStmt = nullptr;
12655 // OpenMP [2.5, Restrictions]
12656 // The num_threads expression must evaluate to a positive integer value.
12657 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
12658 /*StrictlyPositive=*/true))
12661 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12662 OpenMPDirectiveKind CaptureRegion =
12663 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
12664 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12665 ValExpr = MakeFullExpr(ValExpr).get();
12666 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12667 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12668 HelperValStmt = buildPreInits(Context, Captures);
12671 return new (Context) OMPNumThreadsClause(
12672 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12675 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
12676 OpenMPClauseKind CKind,
12677 bool StrictlyPositive) {
12679 return ExprError();
12680 if (E->isValueDependent() || E->isTypeDependent() ||
12681 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
12683 llvm::APSInt Result;
12684 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
12685 if (ICE.isInvalid())
12686 return ExprError();
12687 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
12688 (!StrictlyPositive && !Result.isNonNegative())) {
12689 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
12690 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
12691 << E->getSourceRange();
12692 return ExprError();
12694 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
12695 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
12696 << E->getSourceRange();
12697 return ExprError();
12699 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
12700 DSAStack->setAssociatedLoops(Result.getExtValue());
12701 else if (CKind == OMPC_ordered)
12702 DSAStack->setAssociatedLoops(Result.getExtValue());
12706 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
12707 SourceLocation LParenLoc,
12708 SourceLocation EndLoc) {
12709 // OpenMP [2.8.1, simd construct, Description]
12710 // The parameter of the safelen clause must be a constant
12711 // positive integer expression.
12712 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
12713 if (Safelen.isInvalid())
12715 return new (Context)
12716 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
12719 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
12720 SourceLocation LParenLoc,
12721 SourceLocation EndLoc) {
12722 // OpenMP [2.8.1, simd construct, Description]
12723 // The parameter of the simdlen clause must be a constant
12724 // positive integer expression.
12725 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
12726 if (Simdlen.isInvalid())
12728 return new (Context)
12729 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
12732 /// Tries to find omp_allocator_handle_t type.
12733 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
12734 DSAStackTy *Stack) {
12735 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
12736 if (!OMPAllocatorHandleT.isNull())
12738 // Build the predefined allocator expressions.
12739 bool ErrorFound = false;
12740 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
12741 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
12742 StringRef Allocator =
12743 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
12744 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
12745 auto *VD = dyn_cast_or_null<ValueDecl>(
12746 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
12751 QualType AllocatorType =
12752 VD->getType().getNonLValueExprType(S.getASTContext());
12753 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
12754 if (!Res.isUsable()) {
12758 if (OMPAllocatorHandleT.isNull())
12759 OMPAllocatorHandleT = AllocatorType;
12760 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
12764 Stack->setAllocator(AllocatorKind, Res.get());
12767 S.Diag(Loc, diag::err_omp_implied_type_not_found)
12768 << "omp_allocator_handle_t";
12771 OMPAllocatorHandleT.addConst();
12772 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
12776 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
12777 SourceLocation LParenLoc,
12778 SourceLocation EndLoc) {
12779 // OpenMP [2.11.3, allocate Directive, Description]
12780 // allocator is an expression of omp_allocator_handle_t type.
12781 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
12784 ExprResult Allocator = DefaultLvalueConversion(A);
12785 if (Allocator.isInvalid())
12787 Allocator = PerformImplicitConversion(Allocator.get(),
12788 DSAStack->getOMPAllocatorHandleT(),
12789 Sema::AA_Initializing,
12790 /*AllowExplicit=*/true);
12791 if (Allocator.isInvalid())
12793 return new (Context)
12794 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
12797 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
12798 SourceLocation StartLoc,
12799 SourceLocation LParenLoc,
12800 SourceLocation EndLoc) {
12801 // OpenMP [2.7.1, loop construct, Description]
12802 // OpenMP [2.8.1, simd construct, Description]
12803 // OpenMP [2.9.6, distribute construct, Description]
12804 // The parameter of the collapse clause must be a constant
12805 // positive integer expression.
12806 ExprResult NumForLoopsResult =
12807 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
12808 if (NumForLoopsResult.isInvalid())
12810 return new (Context)
12811 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
12814 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
12815 SourceLocation EndLoc,
12816 SourceLocation LParenLoc,
12817 Expr *NumForLoops) {
12818 // OpenMP [2.7.1, loop construct, Description]
12819 // OpenMP [2.8.1, simd construct, Description]
12820 // OpenMP [2.9.6, distribute construct, Description]
12821 // The parameter of the ordered clause must be a constant
12822 // positive integer expression if any.
12823 if (NumForLoops && LParenLoc.isValid()) {
12824 ExprResult NumForLoopsResult =
12825 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
12826 if (NumForLoopsResult.isInvalid())
12828 NumForLoops = NumForLoopsResult.get();
12830 NumForLoops = nullptr;
12832 auto *Clause = OMPOrderedClause::Create(
12833 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
12834 StartLoc, LParenLoc, EndLoc);
12835 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
12839 OMPClause *Sema::ActOnOpenMPSimpleClause(
12840 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
12841 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12842 OMPClause *Res = nullptr;
12845 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
12846 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12848 case OMPC_proc_bind:
12849 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
12850 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12852 case OMPC_atomic_default_mem_order:
12853 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
12854 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
12855 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12858 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
12859 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12862 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
12863 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
12867 case OMPC_num_threads:
12870 case OMPC_allocator:
12871 case OMPC_collapse:
12872 case OMPC_schedule:
12874 case OMPC_firstprivate:
12875 case OMPC_lastprivate:
12877 case OMPC_reduction:
12878 case OMPC_task_reduction:
12879 case OMPC_in_reduction:
12883 case OMPC_copyprivate:
12887 case OMPC_mergeable:
12888 case OMPC_threadprivate:
12889 case OMPC_allocate:
12905 case OMPC_num_teams:
12906 case OMPC_thread_limit:
12907 case OMPC_priority:
12908 case OMPC_grainsize:
12910 case OMPC_num_tasks:
12912 case OMPC_dist_schedule:
12913 case OMPC_defaultmap:
12918 case OMPC_use_device_ptr:
12919 case OMPC_use_device_addr:
12920 case OMPC_is_device_ptr:
12921 case OMPC_unified_address:
12922 case OMPC_unified_shared_memory:
12923 case OMPC_reverse_offload:
12924 case OMPC_dynamic_allocators:
12925 case OMPC_device_type:
12927 case OMPC_nontemporal:
12930 case OMPC_inclusive:
12931 case OMPC_exclusive:
12932 case OMPC_uses_allocators:
12933 case OMPC_affinity:
12935 llvm_unreachable("Clause is not allowed.");
12941 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
12942 ArrayRef<unsigned> Exclude = llvm::None) {
12943 SmallString<256> Buffer;
12944 llvm::raw_svector_ostream Out(Buffer);
12945 unsigned Skipped = Exclude.size();
12946 auto S = Exclude.begin(), E = Exclude.end();
12947 for (unsigned I = First; I < Last; ++I) {
12948 if (std::find(S, E, I) != E) {
12952 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
12953 if (I + Skipped + 2 == Last)
12955 else if (I + Skipped + 1 != Last)
12958 return std::string(Out.str());
12961 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
12962 SourceLocation KindKwLoc,
12963 SourceLocation StartLoc,
12964 SourceLocation LParenLoc,
12965 SourceLocation EndLoc) {
12966 if (Kind == OMP_DEFAULT_unknown) {
12967 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12968 << getListOfPossibleValues(OMPC_default, /*First=*/0,
12969 /*Last=*/unsigned(OMP_DEFAULT_unknown))
12970 << getOpenMPClauseName(OMPC_default);
12975 case OMP_DEFAULT_none:
12976 DSAStack->setDefaultDSANone(KindKwLoc);
12978 case OMP_DEFAULT_shared:
12979 DSAStack->setDefaultDSAShared(KindKwLoc);
12981 case OMP_DEFAULT_firstprivate:
12982 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
12985 llvm_unreachable("DSA unexpected in OpenMP default clause");
12988 return new (Context)
12989 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
12992 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
12993 SourceLocation KindKwLoc,
12994 SourceLocation StartLoc,
12995 SourceLocation LParenLoc,
12996 SourceLocation EndLoc) {
12997 if (Kind == OMP_PROC_BIND_unknown) {
12998 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12999 << getListOfPossibleValues(OMPC_proc_bind,
13000 /*First=*/unsigned(OMP_PROC_BIND_master),
13002 << getOpenMPClauseName(OMPC_proc_bind);
13005 return new (Context)
13006 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13009 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
13010 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
13011 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
13012 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
13013 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13014 << getListOfPossibleValues(
13015 OMPC_atomic_default_mem_order, /*First=*/0,
13016 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
13017 << getOpenMPClauseName(OMPC_atomic_default_mem_order);
13020 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
13021 LParenLoc, EndLoc);
13024 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
13025 SourceLocation KindKwLoc,
13026 SourceLocation StartLoc,
13027 SourceLocation LParenLoc,
13028 SourceLocation EndLoc) {
13029 if (Kind == OMPC_ORDER_unknown) {
13030 static_assert(OMPC_ORDER_unknown > 0,
13031 "OMPC_ORDER_unknown not greater than 0");
13032 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13033 << getListOfPossibleValues(OMPC_order, /*First=*/0,
13034 /*Last=*/OMPC_ORDER_unknown)
13035 << getOpenMPClauseName(OMPC_order);
13038 return new (Context)
13039 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
13042 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
13043 SourceLocation KindKwLoc,
13044 SourceLocation StartLoc,
13045 SourceLocation LParenLoc,
13046 SourceLocation EndLoc) {
13047 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
13048 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
13049 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
13050 OMPC_DEPEND_depobj};
13051 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
13052 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
13053 /*Last=*/OMPC_DEPEND_unknown, Except)
13054 << getOpenMPClauseName(OMPC_update);
13057 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
13061 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
13062 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
13063 SourceLocation StartLoc, SourceLocation LParenLoc,
13064 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
13065 SourceLocation EndLoc) {
13066 OMPClause *Res = nullptr;
13068 case OMPC_schedule:
13069 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
13070 assert(Argument.size() == NumberOfElements &&
13071 ArgumentLoc.size() == NumberOfElements);
13072 Res = ActOnOpenMPScheduleClause(
13073 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
13074 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
13075 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
13076 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
13077 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
13080 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13081 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
13082 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
13085 case OMPC_dist_schedule:
13086 Res = ActOnOpenMPDistScheduleClause(
13087 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
13088 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
13090 case OMPC_defaultmap:
13091 enum { Modifier, DefaultmapKind };
13092 Res = ActOnOpenMPDefaultmapClause(
13093 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
13094 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
13095 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
13099 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
13100 Res = ActOnOpenMPDeviceClause(
13101 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
13102 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
13105 case OMPC_num_threads:
13108 case OMPC_allocator:
13109 case OMPC_collapse:
13111 case OMPC_proc_bind:
13113 case OMPC_firstprivate:
13114 case OMPC_lastprivate:
13116 case OMPC_reduction:
13117 case OMPC_task_reduction:
13118 case OMPC_in_reduction:
13122 case OMPC_copyprivate:
13126 case OMPC_mergeable:
13127 case OMPC_threadprivate:
13128 case OMPC_allocate:
13144 case OMPC_num_teams:
13145 case OMPC_thread_limit:
13146 case OMPC_priority:
13147 case OMPC_grainsize:
13149 case OMPC_num_tasks:
13155 case OMPC_use_device_ptr:
13156 case OMPC_use_device_addr:
13157 case OMPC_is_device_ptr:
13158 case OMPC_unified_address:
13159 case OMPC_unified_shared_memory:
13160 case OMPC_reverse_offload:
13161 case OMPC_dynamic_allocators:
13162 case OMPC_atomic_default_mem_order:
13163 case OMPC_device_type:
13165 case OMPC_nontemporal:
13169 case OMPC_inclusive:
13170 case OMPC_exclusive:
13171 case OMPC_uses_allocators:
13172 case OMPC_affinity:
13174 llvm_unreachable("Clause is not allowed.");
13179 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
13180 OpenMPScheduleClauseModifier M2,
13181 SourceLocation M1Loc, SourceLocation M2Loc) {
13182 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
13183 SmallVector<unsigned, 2> Excluded;
13184 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
13185 Excluded.push_back(M2);
13186 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
13187 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
13188 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
13189 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
13190 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
13191 << getListOfPossibleValues(OMPC_schedule,
13192 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
13193 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13195 << getOpenMPClauseName(OMPC_schedule);
13201 OMPClause *Sema::ActOnOpenMPScheduleClause(
13202 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
13203 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13204 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
13205 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
13206 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
13207 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
13209 // OpenMP, 2.7.1, Loop Construct, Restrictions
13210 // Either the monotonic modifier or the nonmonotonic modifier can be specified
13212 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
13213 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
13214 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
13215 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
13216 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
13217 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
13218 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
13219 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
13222 if (Kind == OMPC_SCHEDULE_unknown) {
13223 std::string Values;
13224 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
13225 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
13226 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13227 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
13230 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
13231 /*Last=*/OMPC_SCHEDULE_unknown);
13233 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13234 << Values << getOpenMPClauseName(OMPC_schedule);
13237 // OpenMP, 2.7.1, Loop Construct, Restrictions
13238 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
13239 // schedule(guided).
13240 // OpenMP 5.0 does not have this restriction.
13241 if (LangOpts.OpenMP < 50 &&
13242 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
13243 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
13244 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
13245 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
13246 diag::err_omp_schedule_nonmonotonic_static);
13249 Expr *ValExpr = ChunkSize;
13250 Stmt *HelperValStmt = nullptr;
13252 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13253 !ChunkSize->isInstantiationDependent() &&
13254 !ChunkSize->containsUnexpandedParameterPack()) {
13255 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13257 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13258 if (Val.isInvalid())
13261 ValExpr = Val.get();
13263 // OpenMP [2.7.1, Restrictions]
13264 // chunk_size must be a loop invariant integer expression with a positive
13266 llvm::APSInt Result;
13267 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
13268 if (Result.isSigned() && !Result.isStrictlyPositive()) {
13269 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13270 << "schedule" << 1 << ChunkSize->getSourceRange();
13273 } else if (getOpenMPCaptureRegionForClause(
13274 DSAStack->getCurrentDirective(), OMPC_schedule,
13275 LangOpts.OpenMP) != OMPD_unknown &&
13276 !CurContext->isDependentContext()) {
13277 ValExpr = MakeFullExpr(ValExpr).get();
13278 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13279 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13280 HelperValStmt = buildPreInits(Context, Captures);
13285 return new (Context)
13286 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
13287 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
13290 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
13291 SourceLocation StartLoc,
13292 SourceLocation EndLoc) {
13293 OMPClause *Res = nullptr;
13296 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
13299 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
13302 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
13304 case OMPC_mergeable:
13305 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
13308 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
13311 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
13314 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
13317 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
13320 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
13323 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
13326 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
13329 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
13332 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
13335 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
13338 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
13341 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
13343 case OMPC_unified_address:
13344 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
13346 case OMPC_unified_shared_memory:
13347 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13349 case OMPC_reverse_offload:
13350 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
13352 case OMPC_dynamic_allocators:
13353 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
13356 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc);
13360 case OMPC_num_threads:
13363 case OMPC_allocator:
13364 case OMPC_collapse:
13365 case OMPC_schedule:
13367 case OMPC_firstprivate:
13368 case OMPC_lastprivate:
13370 case OMPC_reduction:
13371 case OMPC_task_reduction:
13372 case OMPC_in_reduction:
13376 case OMPC_copyprivate:
13378 case OMPC_proc_bind:
13379 case OMPC_threadprivate:
13380 case OMPC_allocate:
13386 case OMPC_num_teams:
13387 case OMPC_thread_limit:
13388 case OMPC_priority:
13389 case OMPC_grainsize:
13390 case OMPC_num_tasks:
13392 case OMPC_dist_schedule:
13393 case OMPC_defaultmap:
13398 case OMPC_use_device_ptr:
13399 case OMPC_use_device_addr:
13400 case OMPC_is_device_ptr:
13401 case OMPC_atomic_default_mem_order:
13402 case OMPC_device_type:
13404 case OMPC_nontemporal:
13407 case OMPC_inclusive:
13408 case OMPC_exclusive:
13409 case OMPC_uses_allocators:
13410 case OMPC_affinity:
13412 llvm_unreachable("Clause is not allowed.");
13417 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
13418 SourceLocation EndLoc) {
13419 DSAStack->setNowaitRegion();
13420 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
13423 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
13424 SourceLocation EndLoc) {
13425 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
13428 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
13429 SourceLocation EndLoc) {
13430 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
13433 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
13434 SourceLocation EndLoc) {
13435 return new (Context) OMPReadClause(StartLoc, EndLoc);
13438 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
13439 SourceLocation EndLoc) {
13440 return new (Context) OMPWriteClause(StartLoc, EndLoc);
13443 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
13444 SourceLocation EndLoc) {
13445 return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
13448 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
13449 SourceLocation EndLoc) {
13450 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
13453 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
13454 SourceLocation EndLoc) {
13455 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
13458 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
13459 SourceLocation EndLoc) {
13460 return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
13463 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
13464 SourceLocation EndLoc) {
13465 return new (Context) OMPAcquireClause(StartLoc, EndLoc);
13468 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
13469 SourceLocation EndLoc) {
13470 return new (Context) OMPReleaseClause(StartLoc, EndLoc);
13473 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
13474 SourceLocation EndLoc) {
13475 return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
13478 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
13479 SourceLocation EndLoc) {
13480 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
13483 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
13484 SourceLocation EndLoc) {
13485 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
13488 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
13489 SourceLocation EndLoc) {
13490 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
13493 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
13494 SourceLocation EndLoc) {
13495 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
13498 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
13499 SourceLocation EndLoc) {
13500 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
13503 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
13504 SourceLocation EndLoc) {
13505 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
13508 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
13509 SourceLocation EndLoc) {
13510 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
13513 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc,
13514 SourceLocation EndLoc) {
13515 return new (Context) OMPDestroyClause(StartLoc, EndLoc);
13518 OMPClause *Sema::ActOnOpenMPVarListClause(
13519 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
13520 const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
13521 CXXScopeSpec &ReductionOrMapperIdScopeSpec,
13522 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
13523 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
13524 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
13525 SourceLocation ExtraModifierLoc) {
13526 SourceLocation StartLoc = Locs.StartLoc;
13527 SourceLocation LParenLoc = Locs.LParenLoc;
13528 SourceLocation EndLoc = Locs.EndLoc;
13529 OMPClause *Res = nullptr;
13532 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13534 case OMPC_firstprivate:
13535 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13537 case OMPC_lastprivate:
13538 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
13539 "Unexpected lastprivate modifier.");
13540 Res = ActOnOpenMPLastprivateClause(
13541 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
13542 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
13545 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
13547 case OMPC_reduction:
13548 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
13549 "Unexpected lastprivate modifier.");
13550 Res = ActOnOpenMPReductionClause(
13551 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
13552 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
13553 ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
13555 case OMPC_task_reduction:
13556 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13557 EndLoc, ReductionOrMapperIdScopeSpec,
13558 ReductionOrMapperId);
13560 case OMPC_in_reduction:
13561 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
13562 EndLoc, ReductionOrMapperIdScopeSpec,
13563 ReductionOrMapperId);
13566 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
13567 "Unexpected linear modifier.");
13568 Res = ActOnOpenMPLinearClause(
13569 VarList, DepModOrTailExpr, StartLoc, LParenLoc,
13570 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
13574 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
13575 LParenLoc, ColonLoc, EndLoc);
13578 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
13580 case OMPC_copyprivate:
13581 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
13584 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
13587 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
13588 "Unexpected depend modifier.");
13589 Res = ActOnOpenMPDependClause(
13590 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
13591 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
13594 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
13595 "Unexpected map modifier.");
13596 Res = ActOnOpenMPMapClause(
13597 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
13598 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
13599 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
13602 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
13603 ReductionOrMapperId, Locs);
13606 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
13607 ReductionOrMapperId, Locs);
13609 case OMPC_use_device_ptr:
13610 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
13612 case OMPC_use_device_addr:
13613 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
13615 case OMPC_is_device_ptr:
13616 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
13618 case OMPC_allocate:
13619 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
13620 LParenLoc, ColonLoc, EndLoc);
13622 case OMPC_nontemporal:
13623 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
13625 case OMPC_inclusive:
13626 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13628 case OMPC_exclusive:
13629 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
13631 case OMPC_affinity:
13632 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
13633 DepModOrTailExpr, VarList);
13638 case OMPC_num_threads:
13641 case OMPC_allocator:
13642 case OMPC_collapse:
13644 case OMPC_proc_bind:
13645 case OMPC_schedule:
13649 case OMPC_mergeable:
13650 case OMPC_threadprivate:
13663 case OMPC_num_teams:
13664 case OMPC_thread_limit:
13665 case OMPC_priority:
13666 case OMPC_grainsize:
13668 case OMPC_num_tasks:
13670 case OMPC_dist_schedule:
13671 case OMPC_defaultmap:
13674 case OMPC_unified_address:
13675 case OMPC_unified_shared_memory:
13676 case OMPC_reverse_offload:
13677 case OMPC_dynamic_allocators:
13678 case OMPC_atomic_default_mem_order:
13679 case OMPC_device_type:
13684 case OMPC_uses_allocators:
13686 llvm_unreachable("Clause is not allowed.");
13691 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
13692 ExprObjectKind OK, SourceLocation Loc) {
13693 ExprResult Res = BuildDeclRefExpr(
13694 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
13695 if (!Res.isUsable())
13696 return ExprError();
13697 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
13698 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
13699 if (!Res.isUsable())
13700 return ExprError();
13702 if (VK != VK_LValue && Res.get()->isGLValue()) {
13703 Res = DefaultLvalueConversion(Res.get());
13704 if (!Res.isUsable())
13705 return ExprError();
13710 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
13711 SourceLocation StartLoc,
13712 SourceLocation LParenLoc,
13713 SourceLocation EndLoc) {
13714 SmallVector<Expr *, 8> Vars;
13715 SmallVector<Expr *, 8> PrivateCopies;
13716 for (Expr *RefExpr : VarList) {
13717 assert(RefExpr && "NULL expr in OpenMP private clause.");
13718 SourceLocation ELoc;
13719 SourceRange ERange;
13720 Expr *SimpleRefExpr = RefExpr;
13721 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13723 // It will be analyzed later.
13724 Vars.push_back(RefExpr);
13725 PrivateCopies.push_back(nullptr);
13727 ValueDecl *D = Res.first;
13731 QualType Type = D->getType();
13732 auto *VD = dyn_cast<VarDecl>(D);
13734 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13735 // A variable that appears in a private clause must not have an incomplete
13736 // type or a reference type.
13737 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
13739 Type = Type.getNonReferenceType();
13741 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13742 // A variable that is privatized must not have a const-qualified type
13743 // unless it is of class type with a mutable member. This restriction does
13744 // not apply to the firstprivate clause.
13746 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
13747 // A variable that appears in a private clause must not have a
13748 // const-qualified type unless it is of class type with a mutable member.
13749 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
13752 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13754 // Variables with the predetermined data-sharing attributes may not be
13755 // listed in data-sharing attributes clauses, except for the cases
13756 // listed below. For these exceptions only, listing a predetermined
13757 // variable in a data-sharing attribute clause is allowed and overrides
13758 // the variable's predetermined data-sharing attributes.
13759 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13760 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
13761 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13762 << getOpenMPClauseName(OMPC_private);
13763 reportOriginalDsa(*this, DSAStack, D, DVar);
13767 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13768 // Variably modified types are not supported for tasks.
13769 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
13770 isOpenMPTaskingDirective(CurrDir)) {
13771 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13772 << getOpenMPClauseName(OMPC_private) << Type
13773 << getOpenMPDirectiveName(CurrDir);
13776 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
13777 Diag(D->getLocation(),
13778 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13783 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13784 // A list item cannot appear in both a map clause and a data-sharing
13785 // attribute clause on the same construct
13787 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
13788 // A list item cannot appear in both a map clause and a data-sharing
13789 // attribute clause on the same construct unless the construct is a
13790 // combined construct.
13791 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
13792 CurrDir == OMPD_target) {
13793 OpenMPClauseKind ConflictKind;
13794 if (DSAStack->checkMappableExprComponentListsForDecl(
13795 VD, /*CurrentRegionOnly=*/true,
13796 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
13797 OpenMPClauseKind WhereFoundClauseKind) -> bool {
13798 ConflictKind = WhereFoundClauseKind;
13801 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13802 << getOpenMPClauseName(OMPC_private)
13803 << getOpenMPClauseName(ConflictKind)
13804 << getOpenMPDirectiveName(CurrDir);
13805 reportOriginalDsa(*this, DSAStack, D, DVar);
13810 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
13811 // A variable of class type (or array thereof) that appears in a private
13812 // clause requires an accessible, unambiguous default constructor for the
13814 // Generate helper private variable and initialize it with the default
13815 // value. The address of the original variable is replaced by the address of
13816 // the new private variable in CodeGen. This new variable is not added to
13817 // IdResolver, so the code in the OpenMP region uses original variable for
13818 // proper diagnostics.
13819 Type = Type.getUnqualifiedType();
13820 VarDecl *VDPrivate =
13821 buildVarDecl(*this, ELoc, Type, D->getName(),
13822 D->hasAttrs() ? &D->getAttrs() : nullptr,
13823 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13824 ActOnUninitializedDecl(VDPrivate);
13825 if (VDPrivate->isInvalidDecl())
13827 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13828 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13830 DeclRefExpr *Ref = nullptr;
13831 if (!VD && !CurContext->isDependentContext())
13832 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13833 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
13834 Vars.push_back((VD || CurContext->isDependentContext())
13835 ? RefExpr->IgnoreParens()
13837 PrivateCopies.push_back(VDPrivateRefExpr);
13843 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
13848 class DiagsUninitializedSeveretyRAII {
13850 DiagnosticsEngine &Diags;
13851 SourceLocation SavedLoc;
13852 bool IsIgnored = false;
13855 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
13857 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
13859 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
13860 /*Map*/ diag::Severity::Ignored, Loc);
13863 ~DiagsUninitializedSeveretyRAII() {
13865 Diags.popMappings(SavedLoc);
13870 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
13871 SourceLocation StartLoc,
13872 SourceLocation LParenLoc,
13873 SourceLocation EndLoc) {
13874 SmallVector<Expr *, 8> Vars;
13875 SmallVector<Expr *, 8> PrivateCopies;
13876 SmallVector<Expr *, 8> Inits;
13877 SmallVector<Decl *, 4> ExprCaptures;
13878 bool IsImplicitClause =
13879 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
13880 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
13882 for (Expr *RefExpr : VarList) {
13883 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
13884 SourceLocation ELoc;
13885 SourceRange ERange;
13886 Expr *SimpleRefExpr = RefExpr;
13887 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13889 // It will be analyzed later.
13890 Vars.push_back(RefExpr);
13891 PrivateCopies.push_back(nullptr);
13892 Inits.push_back(nullptr);
13894 ValueDecl *D = Res.first;
13898 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
13899 QualType Type = D->getType();
13900 auto *VD = dyn_cast<VarDecl>(D);
13902 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13903 // A variable that appears in a private clause must not have an incomplete
13904 // type or a reference type.
13905 if (RequireCompleteType(ELoc, Type,
13906 diag::err_omp_firstprivate_incomplete_type))
13908 Type = Type.getNonReferenceType();
13910 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
13911 // A variable of class type (or array thereof) that appears in a private
13912 // clause requires an accessible, unambiguous copy constructor for the
13914 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
13916 // If an implicit firstprivate variable found it was checked already.
13917 DSAStackTy::DSAVarData TopDVar;
13918 if (!IsImplicitClause) {
13919 DSAStackTy::DSAVarData DVar =
13920 DSAStack->getTopDSA(D, /*FromParent=*/false);
13922 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13923 bool IsConstant = ElemType.isConstant(Context);
13924 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
13925 // A list item that specifies a given variable may not appear in more
13926 // than one clause on the same directive, except that a variable may be
13927 // specified in both firstprivate and lastprivate clauses.
13928 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13929 // A list item may appear in a firstprivate or lastprivate clause but not
13931 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
13932 (isOpenMPDistributeDirective(CurrDir) ||
13933 DVar.CKind != OMPC_lastprivate) &&
13935 Diag(ELoc, diag::err_omp_wrong_dsa)
13936 << getOpenMPClauseName(DVar.CKind)
13937 << getOpenMPClauseName(OMPC_firstprivate);
13938 reportOriginalDsa(*this, DSAStack, D, DVar);
13942 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13944 // Variables with the predetermined data-sharing attributes may not be
13945 // listed in data-sharing attributes clauses, except for the cases
13946 // listed below. For these exceptions only, listing a predetermined
13947 // variable in a data-sharing attribute clause is allowed and overrides
13948 // the variable's predetermined data-sharing attributes.
13949 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13950 // in a Construct, C/C++, p.2]
13951 // Variables with const-qualified type having no mutable member may be
13952 // listed in a firstprivate clause, even if they are static data members.
13953 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
13954 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
13955 Diag(ELoc, diag::err_omp_wrong_dsa)
13956 << getOpenMPClauseName(DVar.CKind)
13957 << getOpenMPClauseName(OMPC_firstprivate);
13958 reportOriginalDsa(*this, DSAStack, D, DVar);
13962 // OpenMP [2.9.3.4, Restrictions, p.2]
13963 // A list item that is private within a parallel region must not appear
13964 // in a firstprivate clause on a worksharing construct if any of the
13965 // worksharing regions arising from the worksharing construct ever bind
13966 // to any of the parallel regions arising from the parallel construct.
13967 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13968 // A list item that is private within a teams region must not appear in a
13969 // firstprivate clause on a distribute construct if any of the distribute
13970 // regions arising from the distribute construct ever bind to any of the
13971 // teams regions arising from the teams construct.
13972 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
13973 // A list item that appears in a reduction clause of a teams construct
13974 // must not appear in a firstprivate clause on a distribute construct if
13975 // any of the distribute regions arising from the distribute construct
13976 // ever bind to any of the teams regions arising from the teams construct.
13977 if ((isOpenMPWorksharingDirective(CurrDir) ||
13978 isOpenMPDistributeDirective(CurrDir)) &&
13979 !isOpenMPParallelDirective(CurrDir) &&
13980 !isOpenMPTeamsDirective(CurrDir)) {
13981 DVar = DSAStack->getImplicitDSA(D, true);
13982 if (DVar.CKind != OMPC_shared &&
13983 (isOpenMPParallelDirective(DVar.DKind) ||
13984 isOpenMPTeamsDirective(DVar.DKind) ||
13985 DVar.DKind == OMPD_unknown)) {
13986 Diag(ELoc, diag::err_omp_required_access)
13987 << getOpenMPClauseName(OMPC_firstprivate)
13988 << getOpenMPClauseName(OMPC_shared);
13989 reportOriginalDsa(*this, DSAStack, D, DVar);
13993 // OpenMP [2.9.3.4, Restrictions, p.3]
13994 // A list item that appears in a reduction clause of a parallel construct
13995 // must not appear in a firstprivate clause on a worksharing or task
13996 // construct if any of the worksharing or task regions arising from the
13997 // worksharing or task construct ever bind to any of the parallel regions
13998 // arising from the parallel construct.
13999 // OpenMP [2.9.3.4, Restrictions, p.4]
14000 // A list item that appears in a reduction clause in worksharing
14001 // construct must not appear in a firstprivate clause in a task construct
14002 // encountered during execution of any of the worksharing regions arising
14003 // from the worksharing construct.
14004 if (isOpenMPTaskingDirective(CurrDir)) {
14005 DVar = DSAStack->hasInnermostDSA(
14006 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
14007 [](OpenMPDirectiveKind K) {
14008 return isOpenMPParallelDirective(K) ||
14009 isOpenMPWorksharingDirective(K) ||
14010 isOpenMPTeamsDirective(K);
14012 /*FromParent=*/true);
14013 if (DVar.CKind == OMPC_reduction &&
14014 (isOpenMPParallelDirective(DVar.DKind) ||
14015 isOpenMPWorksharingDirective(DVar.DKind) ||
14016 isOpenMPTeamsDirective(DVar.DKind))) {
14017 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
14018 << getOpenMPDirectiveName(DVar.DKind);
14019 reportOriginalDsa(*this, DSAStack, D, DVar);
14024 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
14025 // A list item cannot appear in both a map clause and a data-sharing
14026 // attribute clause on the same construct
14028 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
14029 // A list item cannot appear in both a map clause and a data-sharing
14030 // attribute clause on the same construct unless the construct is a
14031 // combined construct.
14032 if ((LangOpts.OpenMP <= 45 &&
14033 isOpenMPTargetExecutionDirective(CurrDir)) ||
14034 CurrDir == OMPD_target) {
14035 OpenMPClauseKind ConflictKind;
14036 if (DSAStack->checkMappableExprComponentListsForDecl(
14037 VD, /*CurrentRegionOnly=*/true,
14039 OMPClauseMappableExprCommon::MappableExprComponentListRef,
14040 OpenMPClauseKind WhereFoundClauseKind) {
14041 ConflictKind = WhereFoundClauseKind;
14044 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14045 << getOpenMPClauseName(OMPC_firstprivate)
14046 << getOpenMPClauseName(ConflictKind)
14047 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14048 reportOriginalDsa(*this, DSAStack, D, DVar);
14054 // Variably modified types are not supported for tasks.
14055 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
14056 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
14057 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14058 << getOpenMPClauseName(OMPC_firstprivate) << Type
14059 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14062 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14063 Diag(D->getLocation(),
14064 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14069 Type = Type.getUnqualifiedType();
14070 VarDecl *VDPrivate =
14071 buildVarDecl(*this, ELoc, Type, D->getName(),
14072 D->hasAttrs() ? &D->getAttrs() : nullptr,
14073 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14074 // Generate helper private variable and initialize it with the value of the
14075 // original variable. The address of the original variable is replaced by
14076 // the address of the new private variable in the CodeGen. This new variable
14077 // is not added to IdResolver, so the code in the OpenMP region uses
14078 // original variable for proper diagnostics and variable capturing.
14079 Expr *VDInitRefExpr = nullptr;
14080 // For arrays generate initializer for single element and replace it by the
14081 // original array element in CodeGen.
14082 if (Type->isArrayType()) {
14084 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
14085 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
14086 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
14087 ElemType = ElemType.getUnqualifiedType();
14088 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
14089 ".firstprivate.temp");
14090 InitializedEntity Entity =
14091 InitializedEntity::InitializeVariable(VDInitTemp);
14092 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
14094 InitializationSequence InitSeq(*this, Entity, Kind, Init);
14095 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
14096 if (Result.isInvalid())
14097 VDPrivate->setInvalidDecl();
14099 VDPrivate->setInit(Result.getAs<Expr>());
14100 // Remove temp variable declaration.
14101 Context.Deallocate(VDInitTemp);
14103 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
14104 ".firstprivate.temp");
14105 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
14106 RefExpr->getExprLoc());
14107 AddInitializerToDecl(VDPrivate,
14108 DefaultLvalueConversion(VDInitRefExpr).get(),
14109 /*DirectInit=*/false);
14111 if (VDPrivate->isInvalidDecl()) {
14112 if (IsImplicitClause) {
14113 Diag(RefExpr->getExprLoc(),
14114 diag::note_omp_task_predetermined_firstprivate_here);
14118 CurContext->addDecl(VDPrivate);
14119 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
14120 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
14121 RefExpr->getExprLoc());
14122 DeclRefExpr *Ref = nullptr;
14123 if (!VD && !CurContext->isDependentContext()) {
14124 if (TopDVar.CKind == OMPC_lastprivate) {
14125 Ref = TopDVar.PrivateCopy;
14127 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14128 if (!isOpenMPCapturedDecl(D))
14129 ExprCaptures.push_back(Ref->getDecl());
14132 if (!IsImplicitClause)
14133 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
14134 Vars.push_back((VD || CurContext->isDependentContext())
14135 ? RefExpr->IgnoreParens()
14137 PrivateCopies.push_back(VDPrivateRefExpr);
14138 Inits.push_back(VDInitRefExpr);
14144 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14145 Vars, PrivateCopies, Inits,
14146 buildPreInits(Context, ExprCaptures));
14149 OMPClause *Sema::ActOnOpenMPLastprivateClause(
14150 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
14151 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
14152 SourceLocation LParenLoc, SourceLocation EndLoc) {
14153 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
14154 assert(ColonLoc.isValid() && "Colon location must be valid.");
14155 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
14156 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
14157 /*Last=*/OMPC_LASTPRIVATE_unknown)
14158 << getOpenMPClauseName(OMPC_lastprivate);
14162 SmallVector<Expr *, 8> Vars;
14163 SmallVector<Expr *, 8> SrcExprs;
14164 SmallVector<Expr *, 8> DstExprs;
14165 SmallVector<Expr *, 8> AssignmentOps;
14166 SmallVector<Decl *, 4> ExprCaptures;
14167 SmallVector<Expr *, 4> ExprPostUpdates;
14168 for (Expr *RefExpr : VarList) {
14169 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14170 SourceLocation ELoc;
14171 SourceRange ERange;
14172 Expr *SimpleRefExpr = RefExpr;
14173 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14175 // It will be analyzed later.
14176 Vars.push_back(RefExpr);
14177 SrcExprs.push_back(nullptr);
14178 DstExprs.push_back(nullptr);
14179 AssignmentOps.push_back(nullptr);
14181 ValueDecl *D = Res.first;
14185 QualType Type = D->getType();
14186 auto *VD = dyn_cast<VarDecl>(D);
14188 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
14189 // A variable that appears in a lastprivate clause must not have an
14190 // incomplete type or a reference type.
14191 if (RequireCompleteType(ELoc, Type,
14192 diag::err_omp_lastprivate_incomplete_type))
14194 Type = Type.getNonReferenceType();
14196 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14197 // A variable that is privatized must not have a const-qualified type
14198 // unless it is of class type with a mutable member. This restriction does
14199 // not apply to the firstprivate clause.
14201 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
14202 // A variable that appears in a lastprivate clause must not have a
14203 // const-qualified type unless it is of class type with a mutable member.
14204 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
14207 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
14208 // A list item that appears in a lastprivate clause with the conditional
14209 // modifier must be a scalar variable.
14210 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
14211 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
14212 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14213 VarDecl::DeclarationOnly;
14214 Diag(D->getLocation(),
14215 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14220 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
14221 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14223 // Variables with the predetermined data-sharing attributes may not be
14224 // listed in data-sharing attributes clauses, except for the cases
14226 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
14227 // A list item may appear in a firstprivate or lastprivate clause but not
14229 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14230 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
14231 (isOpenMPDistributeDirective(CurrDir) ||
14232 DVar.CKind != OMPC_firstprivate) &&
14233 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
14234 Diag(ELoc, diag::err_omp_wrong_dsa)
14235 << getOpenMPClauseName(DVar.CKind)
14236 << getOpenMPClauseName(OMPC_lastprivate);
14237 reportOriginalDsa(*this, DSAStack, D, DVar);
14241 // OpenMP [2.14.3.5, Restrictions, p.2]
14242 // A list item that is private within a parallel region, or that appears in
14243 // the reduction clause of a parallel construct, must not appear in a
14244 // lastprivate clause on a worksharing construct if any of the corresponding
14245 // worksharing regions ever binds to any of the corresponding parallel
14247 DSAStackTy::DSAVarData TopDVar = DVar;
14248 if (isOpenMPWorksharingDirective(CurrDir) &&
14249 !isOpenMPParallelDirective(CurrDir) &&
14250 !isOpenMPTeamsDirective(CurrDir)) {
14251 DVar = DSAStack->getImplicitDSA(D, true);
14252 if (DVar.CKind != OMPC_shared) {
14253 Diag(ELoc, diag::err_omp_required_access)
14254 << getOpenMPClauseName(OMPC_lastprivate)
14255 << getOpenMPClauseName(OMPC_shared);
14256 reportOriginalDsa(*this, DSAStack, D, DVar);
14261 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
14262 // A variable of class type (or array thereof) that appears in a
14263 // lastprivate clause requires an accessible, unambiguous default
14264 // constructor for the class type, unless the list item is also specified
14265 // in a firstprivate clause.
14266 // A variable of class type (or array thereof) that appears in a
14267 // lastprivate clause requires an accessible, unambiguous copy assignment
14268 // operator for the class type.
14269 Type = Context.getBaseElementType(Type).getNonReferenceType();
14270 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
14271 Type.getUnqualifiedType(), ".lastprivate.src",
14272 D->hasAttrs() ? &D->getAttrs() : nullptr);
14273 DeclRefExpr *PseudoSrcExpr =
14274 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
14276 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
14277 D->hasAttrs() ? &D->getAttrs() : nullptr);
14278 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14279 // For arrays generate assignment operation for single element and replace
14280 // it by the original array element in CodeGen.
14281 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
14282 PseudoDstExpr, PseudoSrcExpr);
14283 if (AssignmentOp.isInvalid())
14286 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14287 if (AssignmentOp.isInvalid())
14290 DeclRefExpr *Ref = nullptr;
14291 if (!VD && !CurContext->isDependentContext()) {
14292 if (TopDVar.CKind == OMPC_firstprivate) {
14293 Ref = TopDVar.PrivateCopy;
14295 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14296 if (!isOpenMPCapturedDecl(D))
14297 ExprCaptures.push_back(Ref->getDecl());
14299 if (TopDVar.CKind == OMPC_firstprivate ||
14300 (!isOpenMPCapturedDecl(D) &&
14301 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
14302 ExprResult RefRes = DefaultLvalueConversion(Ref);
14303 if (!RefRes.isUsable())
14305 ExprResult PostUpdateRes =
14306 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14308 if (!PostUpdateRes.isUsable())
14310 ExprPostUpdates.push_back(
14311 IgnoredValueConversions(PostUpdateRes.get()).get());
14314 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
14315 Vars.push_back((VD || CurContext->isDependentContext())
14316 ? RefExpr->IgnoreParens()
14318 SrcExprs.push_back(PseudoSrcExpr);
14319 DstExprs.push_back(PseudoDstExpr);
14320 AssignmentOps.push_back(AssignmentOp.get());
14326 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14327 Vars, SrcExprs, DstExprs, AssignmentOps,
14328 LPKind, LPKindLoc, ColonLoc,
14329 buildPreInits(Context, ExprCaptures),
14330 buildPostUpdate(*this, ExprPostUpdates));
14333 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
14334 SourceLocation StartLoc,
14335 SourceLocation LParenLoc,
14336 SourceLocation EndLoc) {
14337 SmallVector<Expr *, 8> Vars;
14338 for (Expr *RefExpr : VarList) {
14339 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
14340 SourceLocation ELoc;
14341 SourceRange ERange;
14342 Expr *SimpleRefExpr = RefExpr;
14343 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14345 // It will be analyzed later.
14346 Vars.push_back(RefExpr);
14348 ValueDecl *D = Res.first;
14352 auto *VD = dyn_cast<VarDecl>(D);
14353 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
14355 // Variables with the predetermined data-sharing attributes may not be
14356 // listed in data-sharing attributes clauses, except for the cases
14357 // listed below. For these exceptions only, listing a predetermined
14358 // variable in a data-sharing attribute clause is allowed and overrides
14359 // the variable's predetermined data-sharing attributes.
14360 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14361 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
14363 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14364 << getOpenMPClauseName(OMPC_shared);
14365 reportOriginalDsa(*this, DSAStack, D, DVar);
14369 DeclRefExpr *Ref = nullptr;
14370 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
14371 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14372 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
14373 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
14374 ? RefExpr->IgnoreParens()
14381 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
14385 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
14389 bool VisitDeclRefExpr(DeclRefExpr *E) {
14390 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
14391 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
14392 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
14394 if (DVar.CKind != OMPC_unknown)
14396 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
14397 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
14398 /*FromParent=*/true);
14399 return DVarPrivate.CKind != OMPC_unknown;
14403 bool VisitStmt(Stmt *S) {
14404 for (Stmt *Child : S->children()) {
14405 if (Child && Visit(Child))
14410 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
14415 // Transform MemberExpression for specified FieldDecl of current class to
14416 // DeclRefExpr to specified OMPCapturedExprDecl.
14417 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
14418 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
14419 ValueDecl *Field = nullptr;
14420 DeclRefExpr *CapturedExpr = nullptr;
14423 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
14424 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
14426 ExprResult TransformMemberExpr(MemberExpr *E) {
14427 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
14428 E->getMemberDecl() == Field) {
14429 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
14430 return CapturedExpr;
14432 return BaseTransform::TransformMemberExpr(E);
14434 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
14438 template <typename T, typename U>
14439 static T filterLookupForUDReductionAndMapper(
14440 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
14441 for (U &Set : Lookups) {
14442 for (auto *D : Set) {
14443 if (T Res = Gen(cast<ValueDecl>(D)))
14450 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
14451 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
14453 for (auto RD : D->redecls()) {
14454 // Don't bother with extra checks if we already know this one isn't visible.
14458 auto ND = cast<NamedDecl>(RD);
14459 if (LookupResult::isVisible(SemaRef, ND))
14467 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
14468 SourceLocation Loc, QualType Ty,
14469 SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
14470 // Find all of the associated namespaces and classes based on the
14471 // arguments we have.
14472 Sema::AssociatedNamespaceSet AssociatedNamespaces;
14473 Sema::AssociatedClassSet AssociatedClasses;
14474 OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
14475 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
14476 AssociatedClasses);
14478 // C++ [basic.lookup.argdep]p3:
14479 // Let X be the lookup set produced by unqualified lookup (3.4.1)
14480 // and let Y be the lookup set produced by argument dependent
14481 // lookup (defined as follows). If X contains [...] then Y is
14482 // empty. Otherwise Y is the set of declarations found in the
14483 // namespaces associated with the argument types as described
14484 // below. The set of declarations found by the lookup of the name
14485 // is the union of X and Y.
14487 // Here, we compute Y and add its members to the overloaded
14489 for (auto *NS : AssociatedNamespaces) {
14490 // When considering an associated namespace, the lookup is the
14491 // same as the lookup performed when the associated namespace is
14492 // used as a qualifier (3.4.3.2) except that:
14494 // -- Any using-directives in the associated namespace are
14497 // -- Any namespace-scope friend functions declared in
14498 // associated classes are visible within their respective
14499 // namespaces even if they are not visible during an ordinary
14501 DeclContext::lookup_result R = NS->lookup(Id.getName());
14502 for (auto *D : R) {
14503 auto *Underlying = D;
14504 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14505 Underlying = USD->getTargetDecl();
14507 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
14508 !isa<OMPDeclareMapperDecl>(Underlying))
14511 if (!SemaRef.isVisible(D)) {
14512 D = findAcceptableDecl(SemaRef, D);
14515 if (auto *USD = dyn_cast<UsingShadowDecl>(D))
14516 Underlying = USD->getTargetDecl();
14518 Lookups.emplace_back();
14519 Lookups.back().addDecl(Underlying);
14525 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
14526 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
14527 const DeclarationNameInfo &ReductionId, QualType Ty,
14528 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
14529 if (ReductionIdScopeSpec.isInvalid())
14530 return ExprError();
14531 SmallVector<UnresolvedSet<8>, 4> Lookups;
14533 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14534 Lookup.suppressDiagnostics();
14535 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
14536 NamedDecl *D = Lookup.getRepresentativeDecl();
14538 S = S->getParent();
14539 } while (S && !S->isDeclScope(D));
14541 S = S->getParent();
14542 Lookups.emplace_back();
14543 Lookups.back().append(Lookup.begin(), Lookup.end());
14546 } else if (auto *ULE =
14547 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
14548 Lookups.push_back(UnresolvedSet<8>());
14549 Decl *PrevD = nullptr;
14550 for (NamedDecl *D : ULE->decls()) {
14552 Lookups.push_back(UnresolvedSet<8>());
14553 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
14554 Lookups.back().addDecl(DRD);
14558 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
14559 Ty->isInstantiationDependentType() ||
14560 Ty->containsUnexpandedParameterPack() ||
14561 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
14562 return !D->isInvalidDecl() &&
14563 (D->getType()->isDependentType() ||
14564 D->getType()->isInstantiationDependentType() ||
14565 D->getType()->containsUnexpandedParameterPack());
14567 UnresolvedSet<8> ResSet;
14568 for (const UnresolvedSet<8> &Set : Lookups) {
14571 ResSet.append(Set.begin(), Set.end());
14572 // The last item marks the end of all declarations at the specified scope.
14573 ResSet.addDecl(Set[Set.size() - 1]);
14575 return UnresolvedLookupExpr::Create(
14576 SemaRef.Context, /*NamingClass=*/nullptr,
14577 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
14578 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
14580 // Lookup inside the classes.
14581 // C++ [over.match.oper]p3:
14582 // For a unary operator @ with an operand of a type whose
14583 // cv-unqualified version is T1, and for a binary operator @ with
14584 // a left operand of a type whose cv-unqualified version is T1 and
14585 // a right operand of a type whose cv-unqualified version is T2,
14586 // three sets of candidate functions, designated member
14587 // candidates, non-member candidates and built-in candidates, are
14588 // constructed as follows:
14589 // -- If T1 is a complete class type or a class currently being
14590 // defined, the set of member candidates is the result of the
14591 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
14592 // the set of member candidates is empty.
14593 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
14594 Lookup.suppressDiagnostics();
14595 if (const auto *TyRec = Ty->getAs<RecordType>()) {
14596 // Complete the type if it can be completed.
14597 // If the type is neither complete nor being defined, bail out now.
14598 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
14599 TyRec->getDecl()->getDefinition()) {
14601 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
14602 if (Lookup.empty()) {
14603 Lookups.emplace_back();
14604 Lookups.back().append(Lookup.begin(), Lookup.end());
14609 if (SemaRef.getLangOpts().CPlusPlus)
14610 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
14611 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14612 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
14613 if (!D->isInvalidDecl() &&
14614 SemaRef.Context.hasSameType(D->getType(), Ty))
14618 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
14620 if (SemaRef.getLangOpts().CPlusPlus) {
14621 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
14622 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
14623 if (!D->isInvalidDecl() &&
14624 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
14625 !Ty.isMoreQualifiedThan(D->getType()))
14629 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
14630 /*DetectVirtual=*/false);
14631 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
14632 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
14633 VD->getType().getUnqualifiedType()))) {
14634 if (SemaRef.CheckBaseClassAccess(
14635 Loc, VD->getType(), Ty, Paths.front(),
14636 /*DiagID=*/0) != Sema::AR_inaccessible) {
14637 SemaRef.BuildBasePathArray(Paths, BasePath);
14638 return SemaRef.BuildDeclRefExpr(
14639 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
14645 if (ReductionIdScopeSpec.isSet()) {
14646 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
14648 return ExprError();
14650 return ExprEmpty();
14654 /// Data for the reduction-based clauses.
14655 struct ReductionData {
14656 /// List of original reduction items.
14657 SmallVector<Expr *, 8> Vars;
14658 /// List of private copies of the reduction items.
14659 SmallVector<Expr *, 8> Privates;
14660 /// LHS expressions for the reduction_op expressions.
14661 SmallVector<Expr *, 8> LHSs;
14662 /// RHS expressions for the reduction_op expressions.
14663 SmallVector<Expr *, 8> RHSs;
14664 /// Reduction operation expression.
14665 SmallVector<Expr *, 8> ReductionOps;
14666 /// inscan copy operation expressions.
14667 SmallVector<Expr *, 8> InscanCopyOps;
14668 /// inscan copy temp array expressions for prefix sums.
14669 SmallVector<Expr *, 8> InscanCopyArrayTemps;
14670 /// inscan copy temp array element expressions for prefix sums.
14671 SmallVector<Expr *, 8> InscanCopyArrayElems;
14672 /// Taskgroup descriptors for the corresponding reduction items in
14673 /// in_reduction clauses.
14674 SmallVector<Expr *, 8> TaskgroupDescriptors;
14675 /// List of captures for clause.
14676 SmallVector<Decl *, 4> ExprCaptures;
14677 /// List of postupdate expressions.
14678 SmallVector<Expr *, 4> ExprPostUpdates;
14679 /// Reduction modifier.
14680 unsigned RedModifier = 0;
14681 ReductionData() = delete;
14682 /// Reserves required memory for the reduction data.
14683 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
14684 Vars.reserve(Size);
14685 Privates.reserve(Size);
14686 LHSs.reserve(Size);
14687 RHSs.reserve(Size);
14688 ReductionOps.reserve(Size);
14689 if (RedModifier == OMPC_REDUCTION_inscan) {
14690 InscanCopyOps.reserve(Size);
14691 InscanCopyArrayTemps.reserve(Size);
14692 InscanCopyArrayElems.reserve(Size);
14694 TaskgroupDescriptors.reserve(Size);
14695 ExprCaptures.reserve(Size);
14696 ExprPostUpdates.reserve(Size);
14698 /// Stores reduction item and reduction operation only (required for dependent
14699 /// reduction item).
14700 void push(Expr *Item, Expr *ReductionOp) {
14701 Vars.emplace_back(Item);
14702 Privates.emplace_back(nullptr);
14703 LHSs.emplace_back(nullptr);
14704 RHSs.emplace_back(nullptr);
14705 ReductionOps.emplace_back(ReductionOp);
14706 TaskgroupDescriptors.emplace_back(nullptr);
14707 if (RedModifier == OMPC_REDUCTION_inscan) {
14708 InscanCopyOps.push_back(nullptr);
14709 InscanCopyArrayTemps.push_back(nullptr);
14710 InscanCopyArrayElems.push_back(nullptr);
14713 /// Stores reduction data.
14714 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
14715 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
14716 Expr *CopyArrayElem) {
14717 Vars.emplace_back(Item);
14718 Privates.emplace_back(Private);
14719 LHSs.emplace_back(LHS);
14720 RHSs.emplace_back(RHS);
14721 ReductionOps.emplace_back(ReductionOp);
14722 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
14723 if (RedModifier == OMPC_REDUCTION_inscan) {
14724 InscanCopyOps.push_back(CopyOp);
14725 InscanCopyArrayTemps.push_back(CopyArrayTemp);
14726 InscanCopyArrayElems.push_back(CopyArrayElem);
14728 assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
14729 CopyArrayElem == nullptr &&
14730 "Copy operation must be used for inscan reductions only.");
14736 static bool checkOMPArraySectionConstantForReduction(
14737 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
14738 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
14739 const Expr *Length = OASE->getLength();
14740 if (Length == nullptr) {
14741 // For array sections of the form [1:] or [:], we would need to analyze
14742 // the lower bound...
14743 if (OASE->getColonLocFirst().isValid())
14746 // This is an array subscript which has implicit length 1!
14747 SingleElement = true;
14748 ArraySizes.push_back(llvm::APSInt::get(1));
14750 Expr::EvalResult Result;
14751 if (!Length->EvaluateAsInt(Result, Context))
14754 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14755 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
14756 ArraySizes.push_back(ConstantLengthValue);
14759 // Get the base of this array section and walk up from there.
14760 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
14762 // We require length = 1 for all array sections except the right-most to
14763 // guarantee that the memory region is contiguous and has no holes in it.
14764 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
14765 Length = TempOASE->getLength();
14766 if (Length == nullptr) {
14767 // For array sections of the form [1:] or [:], we would need to analyze
14768 // the lower bound...
14769 if (OASE->getColonLocFirst().isValid())
14772 // This is an array subscript which has implicit length 1!
14773 ArraySizes.push_back(llvm::APSInt::get(1));
14775 Expr::EvalResult Result;
14776 if (!Length->EvaluateAsInt(Result, Context))
14779 llvm::APSInt ConstantLengthValue = Result.Val.getInt();
14780 if (ConstantLengthValue.getSExtValue() != 1)
14783 ArraySizes.push_back(ConstantLengthValue);
14785 Base = TempOASE->getBase()->IgnoreParenImpCasts();
14788 // If we have a single element, we don't need to add the implicit lengths.
14789 if (!SingleElement) {
14790 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
14791 // Has implicit length 1!
14792 ArraySizes.push_back(llvm::APSInt::get(1));
14793 Base = TempASE->getBase()->IgnoreParenImpCasts();
14797 // This array section can be privatized as a single value or as a constant
14802 static bool actOnOMPReductionKindClause(
14803 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
14804 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14805 SourceLocation ColonLoc, SourceLocation EndLoc,
14806 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14807 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
14808 DeclarationName DN = ReductionId.getName();
14809 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
14810 BinaryOperatorKind BOK = BO_Comma;
14812 ASTContext &Context = S.Context;
14813 // OpenMP [2.14.3.6, reduction clause]
14815 // reduction-identifier is either an identifier or one of the following
14816 // operators: +, -, *, &, |, ^, && and ||
14818 // reduction-identifier is either an id-expression or one of the following
14819 // operators: +, -, *, &, |, ^, && and ||
14846 case OO_Array_Delete:
14855 case OO_GreaterEqual:
14857 case OO_MinusEqual:
14859 case OO_SlashEqual:
14860 case OO_PercentEqual:
14861 case OO_CaretEqual:
14865 case OO_GreaterGreater:
14866 case OO_LessLessEqual:
14867 case OO_GreaterGreaterEqual:
14868 case OO_EqualEqual:
14869 case OO_ExclaimEqual:
14872 case OO_MinusMinus:
14878 case OO_Conditional:
14880 case NUM_OVERLOADED_OPERATORS:
14881 llvm_unreachable("Unexpected reduction identifier");
14883 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
14884 if (II->isStr("max"))
14886 else if (II->isStr("min"))
14891 SourceRange ReductionIdRange;
14892 if (ReductionIdScopeSpec.isValid())
14893 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
14895 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
14896 ReductionIdRange.setEnd(ReductionId.getEndLoc());
14898 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
14899 bool FirstIter = true;
14900 for (Expr *RefExpr : VarList) {
14901 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
14902 // OpenMP [2.1, C/C++]
14903 // A list item is a variable or array section, subject to the restrictions
14904 // specified in Section 2.4 on page 42 and in each of the sections
14905 // describing clauses and directives for which a list appears.
14906 // OpenMP [2.14.3.3, Restrictions, p.1]
14907 // A variable that is part of another variable (as an array or
14908 // structure element) cannot appear in a private clause.
14909 if (!FirstIter && IR != ER)
14912 SourceLocation ELoc;
14913 SourceRange ERange;
14914 Expr *SimpleRefExpr = RefExpr;
14915 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
14916 /*AllowArraySection=*/true);
14918 // Try to find 'declare reduction' corresponding construct before using
14919 // builtin/overloaded operators.
14920 QualType Type = Context.DependentTy;
14921 CXXCastPath BasePath;
14922 ExprResult DeclareReductionRef = buildDeclareReductionRef(
14923 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
14924 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
14925 Expr *ReductionOp = nullptr;
14926 if (S.CurContext->isDependentContext() &&
14927 (DeclareReductionRef.isUnset() ||
14928 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
14929 ReductionOp = DeclareReductionRef.get();
14930 // It will be analyzed later.
14931 RD.push(RefExpr, ReductionOp);
14933 ValueDecl *D = Res.first;
14937 Expr *TaskgroupDescriptor = nullptr;
14939 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
14940 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
14942 Type = ASE->getType().getNonReferenceType();
14944 QualType BaseType =
14945 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
14946 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
14947 Type = ATy->getElementType();
14949 Type = BaseType->getPointeeType();
14950 Type = Type.getNonReferenceType();
14952 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
14954 auto *VD = dyn_cast<VarDecl>(D);
14956 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
14957 // A variable that appears in a private clause must not have an incomplete
14958 // type or a reference type.
14959 if (S.RequireCompleteType(ELoc, D->getType(),
14960 diag::err_omp_reduction_incomplete_type))
14962 // OpenMP [2.14.3.6, reduction clause, Restrictions]
14963 // A list item that appears in a reduction clause must not be
14964 // const-qualified.
14965 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
14966 /*AcceptIfMutable*/ false, ASE || OASE))
14969 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
14970 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
14971 // If a list-item is a reference type then it must bind to the same object
14972 // for all threads of the team.
14973 if (!ASE && !OASE) {
14975 VarDecl *VDDef = VD->getDefinition();
14976 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
14977 DSARefChecker Check(Stack);
14978 if (Check.Visit(VDDef->getInit())) {
14979 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
14980 << getOpenMPClauseName(ClauseKind) << ERange;
14981 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
14987 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
14989 // Variables with the predetermined data-sharing attributes may not be
14990 // listed in data-sharing attributes clauses, except for the cases
14991 // listed below. For these exceptions only, listing a predetermined
14992 // variable in a data-sharing attribute clause is allowed and overrides
14993 // the variable's predetermined data-sharing attributes.
14994 // OpenMP [2.14.3.6, Restrictions, p.3]
14995 // Any number of reduction clauses can be specified on the directive,
14996 // but a list item can appear only once in the reduction clauses for that
14998 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
14999 if (DVar.CKind == OMPC_reduction) {
15000 S.Diag(ELoc, diag::err_omp_once_referenced)
15001 << getOpenMPClauseName(ClauseKind);
15003 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
15006 if (DVar.CKind != OMPC_unknown) {
15007 S.Diag(ELoc, diag::err_omp_wrong_dsa)
15008 << getOpenMPClauseName(DVar.CKind)
15009 << getOpenMPClauseName(OMPC_reduction);
15010 reportOriginalDsa(S, Stack, D, DVar);
15014 // OpenMP [2.14.3.6, Restrictions, p.1]
15015 // A list item that appears in a reduction clause of a worksharing
15016 // construct must be shared in the parallel regions to which any of the
15017 // worksharing regions arising from the worksharing construct bind.
15018 if (isOpenMPWorksharingDirective(CurrDir) &&
15019 !isOpenMPParallelDirective(CurrDir) &&
15020 !isOpenMPTeamsDirective(CurrDir)) {
15021 DVar = Stack->getImplicitDSA(D, true);
15022 if (DVar.CKind != OMPC_shared) {
15023 S.Diag(ELoc, diag::err_omp_required_access)
15024 << getOpenMPClauseName(OMPC_reduction)
15025 << getOpenMPClauseName(OMPC_shared);
15026 reportOriginalDsa(S, Stack, D, DVar);
15032 // Try to find 'declare reduction' corresponding construct before using
15033 // builtin/overloaded operators.
15034 CXXCastPath BasePath;
15035 ExprResult DeclareReductionRef = buildDeclareReductionRef(
15036 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
15037 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
15038 if (DeclareReductionRef.isInvalid())
15040 if (S.CurContext->isDependentContext() &&
15041 (DeclareReductionRef.isUnset() ||
15042 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
15043 RD.push(RefExpr, DeclareReductionRef.get());
15046 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
15047 // Not allowed reduction identifier is found.
15048 S.Diag(ReductionId.getBeginLoc(),
15049 diag::err_omp_unknown_reduction_identifier)
15050 << Type << ReductionIdRange;
15054 // OpenMP [2.14.3.6, reduction clause, Restrictions]
15055 // The type of a list item that appears in a reduction clause must be valid
15056 // for the reduction-identifier. For a max or min reduction in C, the type
15057 // of the list item must be an allowed arithmetic data type: char, int,
15058 // float, double, or _Bool, possibly modified with long, short, signed, or
15059 // unsigned. For a max or min reduction in C++, the type of the list item
15060 // must be an allowed arithmetic data type: char, wchar_t, int, float,
15061 // double, or bool, possibly modified with long, short, signed, or unsigned.
15062 if (DeclareReductionRef.isUnset()) {
15063 if ((BOK == BO_GT || BOK == BO_LT) &&
15064 !(Type->isScalarType() ||
15065 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
15066 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
15067 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
15068 if (!ASE && !OASE) {
15069 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15070 VarDecl::DeclarationOnly;
15071 S.Diag(D->getLocation(),
15072 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15077 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
15078 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
15079 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
15080 << getOpenMPClauseName(ClauseKind);
15081 if (!ASE && !OASE) {
15082 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15083 VarDecl::DeclarationOnly;
15084 S.Diag(D->getLocation(),
15085 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15092 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
15093 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
15094 D->hasAttrs() ? &D->getAttrs() : nullptr);
15095 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
15096 D->hasAttrs() ? &D->getAttrs() : nullptr);
15097 QualType PrivateTy = Type;
15099 // Try if we can determine constant lengths for all array sections and avoid
15101 bool ConstantLengthOASE = false;
15103 bool SingleElement;
15104 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
15105 ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
15106 Context, OASE, SingleElement, ArraySizes);
15108 // If we don't have a single element, we must emit a constant array type.
15109 if (ConstantLengthOASE && !SingleElement) {
15110 for (llvm::APSInt &Size : ArraySizes)
15111 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
15113 /*IndexTypeQuals=*/0);
15117 if ((OASE && !ConstantLengthOASE) ||
15119 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
15120 if (!Context.getTargetInfo().isVLASupported()) {
15121 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
15122 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15123 S.Diag(ELoc, diag::note_vla_unsupported);
15126 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
15127 S.targetDiag(ELoc, diag::note_vla_unsupported);
15130 // For arrays/array sections only:
15131 // Create pseudo array type for private copy. The size for this array will
15132 // be generated during codegen.
15133 // For array subscripts or single variables Private Ty is the same as Type
15134 // (type of the variable or single array element).
15135 PrivateTy = Context.getVariableArrayType(
15137 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
15138 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
15139 } else if (!ASE && !OASE &&
15140 Context.getAsArrayType(D->getType().getNonReferenceType())) {
15141 PrivateTy = D->getType().getNonReferenceType();
15144 VarDecl *PrivateVD =
15145 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15146 D->hasAttrs() ? &D->getAttrs() : nullptr,
15147 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15148 // Add initializer for private variable.
15149 Expr *Init = nullptr;
15150 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
15151 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
15152 if (DeclareReductionRef.isUsable()) {
15153 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
15154 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
15155 if (DRD->getInitializer()) {
15156 S.ActOnUninitializedDecl(PrivateVD);
15158 RHSVD->setInit(DRDRef);
15159 RHSVD->setInitStyle(VarDecl::CallInit);
15167 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
15168 if (Type->isScalarType() || Type->isAnyComplexType())
15169 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
15173 if (Type->isScalarType() || Type->isAnyComplexType()) {
15174 // '*' and '&&' reduction ops - initializer is '1'.
15175 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
15179 // '&' reduction op - initializer is '~0'.
15180 QualType OrigType = Type;
15181 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
15182 Type = ComplexTy->getElementType();
15183 if (Type->isRealFloatingType()) {
15184 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
15185 Context.getFloatTypeSemantics(Type),
15186 Context.getTypeSize(Type));
15187 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15189 } else if (Type->isScalarType()) {
15190 uint64_t Size = Context.getTypeSize(Type);
15191 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
15192 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
15193 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15195 if (Init && OrigType->isAnyComplexType()) {
15196 // Init = 0xFFFF + 0xFFFFi;
15197 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
15198 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
15205 // 'min' reduction op - initializer is 'Largest representable number in
15206 // the reduction list item type'.
15207 // 'max' reduction op - initializer is 'Least representable number in
15208 // the reduction list item type'.
15209 if (Type->isIntegerType() || Type->isPointerType()) {
15210 bool IsSigned = Type->hasSignedIntegerRepresentation();
15211 uint64_t Size = Context.getTypeSize(Type);
15213 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
15214 llvm::APInt InitValue =
15215 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
15216 : llvm::APInt::getMinValue(Size)
15217 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
15218 : llvm::APInt::getMaxValue(Size);
15219 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
15220 if (Type->isPointerType()) {
15221 // Cast to pointer type.
15222 ExprResult CastExpr = S.BuildCStyleCastExpr(
15223 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
15224 if (CastExpr.isInvalid())
15226 Init = CastExpr.get();
15228 } else if (Type->isRealFloatingType()) {
15229 llvm::APFloat InitValue = llvm::APFloat::getLargest(
15230 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
15231 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
15260 llvm_unreachable("Unexpected reduction operation");
15263 if (Init && DeclareReductionRef.isUnset()) {
15264 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
15265 // Store initializer for single element in private copy. Will be used
15267 PrivateVD->setInit(RHSVD->getInit());
15268 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15269 } else if (!Init) {
15270 S.ActOnUninitializedDecl(RHSVD);
15271 // Store initializer for single element in private copy. Will be used
15273 PrivateVD->setInit(RHSVD->getInit());
15274 PrivateVD->setInitStyle(RHSVD->getInitStyle());
15276 if (RHSVD->isInvalidDecl())
15278 if (!RHSVD->hasInit() &&
15279 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
15280 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
15281 << Type << ReductionIdRange;
15282 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15283 VarDecl::DeclarationOnly;
15284 S.Diag(D->getLocation(),
15285 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15289 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
15290 ExprResult ReductionOp;
15291 if (DeclareReductionRef.isUsable()) {
15292 QualType RedTy = DeclareReductionRef.get()->getType();
15293 QualType PtrRedTy = Context.getPointerType(RedTy);
15294 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
15295 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
15296 if (!BasePath.empty()) {
15297 LHS = S.DefaultLvalueConversion(LHS.get());
15298 RHS = S.DefaultLvalueConversion(RHS.get());
15299 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15300 CK_UncheckedDerivedToBase, LHS.get(),
15301 &BasePath, LHS.get()->getValueKind());
15302 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
15303 CK_UncheckedDerivedToBase, RHS.get(),
15304 &BasePath, RHS.get()->getValueKind());
15306 FunctionProtoType::ExtProtoInfo EPI;
15307 QualType Params[] = {PtrRedTy, PtrRedTy};
15308 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
15309 auto *OVE = new (Context) OpaqueValueExpr(
15310 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
15311 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
15312 Expr *Args[] = {LHS.get(), RHS.get()};
15314 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
15316 ReductionOp = S.BuildBinOp(
15317 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
15318 if (ReductionOp.isUsable()) {
15319 if (BOK != BO_LT && BOK != BO_GT) {
15321 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15322 BO_Assign, LHSDRE, ReductionOp.get());
15324 auto *ConditionalOp = new (Context)
15325 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
15326 Type, VK_LValue, OK_Ordinary);
15328 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
15329 BO_Assign, LHSDRE, ConditionalOp);
15331 if (ReductionOp.isUsable())
15332 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
15333 /*DiscardedValue*/ false);
15335 if (!ReductionOp.isUsable())
15339 // Add copy operations for inscan reductions.
15341 ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
15342 if (ClauseKind == OMPC_reduction &&
15343 RD.RedModifier == OMPC_REDUCTION_inscan) {
15344 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
15345 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
15347 if (!CopyOpRes.isUsable())
15350 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
15351 if (!CopyOpRes.isUsable())
15353 // For simd directive and simd-based directives in simd mode no need to
15354 // construct temp array, need just a single temp element.
15355 if (Stack->getCurrentDirective() == OMPD_simd ||
15356 (S.getLangOpts().OpenMPSimd &&
15357 isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
15358 VarDecl *TempArrayVD =
15359 buildVarDecl(S, ELoc, PrivateTy, D->getName(),
15360 D->hasAttrs() ? &D->getAttrs() : nullptr);
15361 // Add a constructor to the temp decl.
15362 S.ActOnUninitializedDecl(TempArrayVD);
15363 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
15365 // Build temp array for prefix sum.
15366 auto *Dim = new (S.Context)
15367 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15369 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
15370 /*IndexTypeQuals=*/0, {ELoc, ELoc});
15371 VarDecl *TempArrayVD =
15372 buildVarDecl(S, ELoc, ArrayTy, D->getName(),
15373 D->hasAttrs() ? &D->getAttrs() : nullptr);
15374 // Add a constructor to the temp decl.
15375 S.ActOnUninitializedDecl(TempArrayVD);
15376 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
15378 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
15379 auto *Idx = new (S.Context)
15380 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
15381 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
15386 // OpenMP [2.15.4.6, Restrictions, p.2]
15387 // A list item that appears in an in_reduction clause of a task construct
15388 // must appear in a task_reduction clause of a construct associated with a
15389 // taskgroup region that includes the participating task in its taskgroup
15390 // set. The construct associated with the innermost region that meets this
15391 // condition must specify the same reduction-identifier as the in_reduction
15393 if (ClauseKind == OMPC_in_reduction) {
15394 SourceRange ParentSR;
15395 BinaryOperatorKind ParentBOK;
15396 const Expr *ParentReductionOp = nullptr;
15397 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
15398 DSAStackTy::DSAVarData ParentBOKDSA =
15399 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
15401 DSAStackTy::DSAVarData ParentReductionOpDSA =
15402 Stack->getTopMostTaskgroupReductionData(
15403 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
15404 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
15405 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
15406 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
15407 (DeclareReductionRef.isUsable() && IsParentBOK) ||
15408 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
15409 bool EmitError = true;
15410 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
15411 llvm::FoldingSetNodeID RedId, ParentRedId;
15412 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
15413 DeclareReductionRef.get()->Profile(RedId, Context,
15414 /*Canonical=*/true);
15415 EmitError = RedId != ParentRedId;
15418 S.Diag(ReductionId.getBeginLoc(),
15419 diag::err_omp_reduction_identifier_mismatch)
15420 << ReductionIdRange << RefExpr->getSourceRange();
15421 S.Diag(ParentSR.getBegin(),
15422 diag::note_omp_previous_reduction_identifier)
15424 << (IsParentBOK ? ParentBOKDSA.RefExpr
15425 : ParentReductionOpDSA.RefExpr)
15426 ->getSourceRange();
15430 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
15433 DeclRefExpr *Ref = nullptr;
15434 Expr *VarsExpr = RefExpr->IgnoreParens();
15435 if (!VD && !S.CurContext->isDependentContext()) {
15437 TransformExprToCaptures RebuildToCapture(S, D);
15439 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
15440 Ref = RebuildToCapture.getCapturedExpr();
15442 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
15444 if (!S.isOpenMPCapturedDecl(D)) {
15445 RD.ExprCaptures.emplace_back(Ref->getDecl());
15446 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15447 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
15448 if (!RefRes.isUsable())
15450 ExprResult PostUpdateRes =
15451 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15453 if (!PostUpdateRes.isUsable())
15455 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
15456 Stack->getCurrentDirective() == OMPD_taskgroup) {
15457 S.Diag(RefExpr->getExprLoc(),
15458 diag::err_omp_reduction_non_addressable_expression)
15459 << RefExpr->getSourceRange();
15462 RD.ExprPostUpdates.emplace_back(
15463 S.IgnoredValueConversions(PostUpdateRes.get()).get());
15467 // All reduction items are still marked as reduction (to do not increase
15468 // code base size).
15469 unsigned Modifier = RD.RedModifier;
15470 // Consider task_reductions as reductions with task modifier. Required for
15471 // correct analysis of in_reduction clauses.
15472 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
15473 Modifier = OMPC_REDUCTION_task;
15474 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier);
15475 if (Modifier == OMPC_REDUCTION_task &&
15476 (CurrDir == OMPD_taskgroup ||
15477 ((isOpenMPParallelDirective(CurrDir) ||
15478 isOpenMPWorksharingDirective(CurrDir)) &&
15479 !isOpenMPSimdDirective(CurrDir)))) {
15480 if (DeclareReductionRef.isUsable())
15481 Stack->addTaskgroupReductionData(D, ReductionIdRange,
15482 DeclareReductionRef.get());
15484 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
15486 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
15487 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
15488 TempArrayElem.get());
15490 return RD.Vars.empty();
15493 OMPClause *Sema::ActOnOpenMPReductionClause(
15494 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
15495 SourceLocation StartLoc, SourceLocation LParenLoc,
15496 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
15497 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15498 ArrayRef<Expr *> UnresolvedReductions) {
15499 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
15500 Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
15501 << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
15502 /*Last=*/OMPC_REDUCTION_unknown)
15503 << getOpenMPClauseName(OMPC_reduction);
15506 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
15507 // A reduction clause with the inscan reduction-modifier may only appear on a
15508 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
15509 // construct, a parallel worksharing-loop construct or a parallel
15510 // worksharing-loop SIMD construct.
15511 if (Modifier == OMPC_REDUCTION_inscan &&
15512 (DSAStack->getCurrentDirective() != OMPD_for &&
15513 DSAStack->getCurrentDirective() != OMPD_for_simd &&
15514 DSAStack->getCurrentDirective() != OMPD_simd &&
15515 DSAStack->getCurrentDirective() != OMPD_parallel_for &&
15516 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
15517 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
15521 ReductionData RD(VarList.size(), Modifier);
15522 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
15523 StartLoc, LParenLoc, ColonLoc, EndLoc,
15524 ReductionIdScopeSpec, ReductionId,
15525 UnresolvedReductions, RD))
15528 return OMPReductionClause::Create(
15529 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
15530 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15531 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
15532 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
15533 buildPreInits(Context, RD.ExprCaptures),
15534 buildPostUpdate(*this, RD.ExprPostUpdates));
15537 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
15538 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15539 SourceLocation ColonLoc, SourceLocation EndLoc,
15540 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15541 ArrayRef<Expr *> UnresolvedReductions) {
15542 ReductionData RD(VarList.size());
15543 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
15544 StartLoc, LParenLoc, ColonLoc, EndLoc,
15545 ReductionIdScopeSpec, ReductionId,
15546 UnresolvedReductions, RD))
15549 return OMPTaskReductionClause::Create(
15550 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15551 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15552 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
15553 buildPreInits(Context, RD.ExprCaptures),
15554 buildPostUpdate(*this, RD.ExprPostUpdates));
15557 OMPClause *Sema::ActOnOpenMPInReductionClause(
15558 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
15559 SourceLocation ColonLoc, SourceLocation EndLoc,
15560 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
15561 ArrayRef<Expr *> UnresolvedReductions) {
15562 ReductionData RD(VarList.size());
15563 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
15564 StartLoc, LParenLoc, ColonLoc, EndLoc,
15565 ReductionIdScopeSpec, ReductionId,
15566 UnresolvedReductions, RD))
15569 return OMPInReductionClause::Create(
15570 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
15571 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
15572 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
15573 buildPreInits(Context, RD.ExprCaptures),
15574 buildPostUpdate(*this, RD.ExprPostUpdates));
15577 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
15578 SourceLocation LinLoc) {
15579 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
15580 LinKind == OMPC_LINEAR_unknown) {
15581 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
15587 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
15588 OpenMPLinearClauseKind LinKind, QualType Type,
15589 bool IsDeclareSimd) {
15590 const auto *VD = dyn_cast_or_null<VarDecl>(D);
15591 // A variable must not have an incomplete type or a reference type.
15592 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
15594 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
15595 !Type->isReferenceType()) {
15596 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
15597 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
15600 Type = Type.getNonReferenceType();
15602 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15603 // A variable that is privatized must not have a const-qualified type
15604 // unless it is of class type with a mutable member. This restriction does
15605 // not apply to the firstprivate clause, nor to the linear clause on
15606 // declarative directives (like declare simd).
15607 if (!IsDeclareSimd &&
15608 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
15611 // A list item must be of integral or pointer type.
15612 Type = Type.getUnqualifiedType().getCanonicalType();
15613 const auto *Ty = Type.getTypePtrOrNull();
15614 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
15615 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
15616 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
15620 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15621 Diag(D->getLocation(),
15622 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15630 OMPClause *Sema::ActOnOpenMPLinearClause(
15631 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
15632 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
15633 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15634 SmallVector<Expr *, 8> Vars;
15635 SmallVector<Expr *, 8> Privates;
15636 SmallVector<Expr *, 8> Inits;
15637 SmallVector<Decl *, 4> ExprCaptures;
15638 SmallVector<Expr *, 4> ExprPostUpdates;
15639 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
15640 LinKind = OMPC_LINEAR_val;
15641 for (Expr *RefExpr : VarList) {
15642 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15643 SourceLocation ELoc;
15644 SourceRange ERange;
15645 Expr *SimpleRefExpr = RefExpr;
15646 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15648 // It will be analyzed later.
15649 Vars.push_back(RefExpr);
15650 Privates.push_back(nullptr);
15651 Inits.push_back(nullptr);
15653 ValueDecl *D = Res.first;
15657 QualType Type = D->getType();
15658 auto *VD = dyn_cast<VarDecl>(D);
15660 // OpenMP [2.14.3.7, linear clause]
15661 // A list-item cannot appear in more than one linear clause.
15662 // A list-item that appears in a linear clause cannot appear in any
15663 // other data-sharing attribute clause.
15664 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15665 if (DVar.RefExpr) {
15666 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15667 << getOpenMPClauseName(OMPC_linear);
15668 reportOriginalDsa(*this, DSAStack, D, DVar);
15672 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
15674 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15676 // Build private copy of original var.
15678 buildVarDecl(*this, ELoc, Type, D->getName(),
15679 D->hasAttrs() ? &D->getAttrs() : nullptr,
15680 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15681 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
15682 // Build var to save initial value.
15683 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
15685 DeclRefExpr *Ref = nullptr;
15686 if (!VD && !CurContext->isDependentContext()) {
15687 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15688 if (!isOpenMPCapturedDecl(D)) {
15689 ExprCaptures.push_back(Ref->getDecl());
15690 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
15691 ExprResult RefRes = DefaultLvalueConversion(Ref);
15692 if (!RefRes.isUsable())
15694 ExprResult PostUpdateRes =
15695 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
15696 SimpleRefExpr, RefRes.get());
15697 if (!PostUpdateRes.isUsable())
15699 ExprPostUpdates.push_back(
15700 IgnoredValueConversions(PostUpdateRes.get()).get());
15704 if (LinKind == OMPC_LINEAR_uval)
15705 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
15707 InitExpr = VD ? SimpleRefExpr : Ref;
15708 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
15709 /*DirectInit=*/false);
15710 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
15712 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
15713 Vars.push_back((VD || CurContext->isDependentContext())
15714 ? RefExpr->IgnoreParens()
15716 Privates.push_back(PrivateRef);
15717 Inits.push_back(InitRef);
15723 Expr *StepExpr = Step;
15724 Expr *CalcStepExpr = nullptr;
15725 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
15726 !Step->isInstantiationDependent() &&
15727 !Step->containsUnexpandedParameterPack()) {
15728 SourceLocation StepLoc = Step->getBeginLoc();
15729 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
15730 if (Val.isInvalid())
15732 StepExpr = Val.get();
15734 // Build var to save the step value.
15736 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
15737 ExprResult SaveRef =
15738 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
15739 ExprResult CalcStep =
15740 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
15741 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
15743 // Warn about zero linear step (it would be probably better specified as
15744 // making corresponding variables 'const').
15745 llvm::APSInt Result;
15746 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
15747 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
15748 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
15749 << (Vars.size() > 1);
15750 if (!IsConstant && CalcStep.isUsable()) {
15751 // Calculate the step beforehand instead of doing this on each iteration.
15752 // (This is not used if the number of iterations may be kfold-ed).
15753 CalcStepExpr = CalcStep.get();
15757 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
15758 ColonLoc, EndLoc, Vars, Privates, Inits,
15759 StepExpr, CalcStepExpr,
15760 buildPreInits(Context, ExprCaptures),
15761 buildPostUpdate(*this, ExprPostUpdates));
15764 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
15765 Expr *NumIterations, Sema &SemaRef,
15766 Scope *S, DSAStackTy *Stack) {
15767 // Walk the vars and build update/final expressions for the CodeGen.
15768 SmallVector<Expr *, 8> Updates;
15769 SmallVector<Expr *, 8> Finals;
15770 SmallVector<Expr *, 8> UsedExprs;
15771 Expr *Step = Clause.getStep();
15772 Expr *CalcStep = Clause.getCalcStep();
15773 // OpenMP [2.14.3.7, linear clause]
15774 // If linear-step is not specified it is assumed to be 1.
15776 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
15778 Step = cast<BinaryOperator>(CalcStep)->getLHS();
15779 bool HasErrors = false;
15780 auto CurInit = Clause.inits().begin();
15781 auto CurPrivate = Clause.privates().begin();
15782 OpenMPLinearClauseKind LinKind = Clause.getModifier();
15783 for (Expr *RefExpr : Clause.varlists()) {
15784 SourceLocation ELoc;
15785 SourceRange ERange;
15786 Expr *SimpleRefExpr = RefExpr;
15787 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
15788 ValueDecl *D = Res.first;
15789 if (Res.second || !D) {
15790 Updates.push_back(nullptr);
15791 Finals.push_back(nullptr);
15795 auto &&Info = Stack->isLoopControlVariable(D);
15796 // OpenMP [2.15.11, distribute simd Construct]
15797 // A list item may not appear in a linear clause, unless it is the loop
15798 // iteration variable.
15799 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
15800 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
15802 diag::err_omp_linear_distribute_var_non_loop_iteration);
15803 Updates.push_back(nullptr);
15804 Finals.push_back(nullptr);
15808 Expr *InitExpr = *CurInit;
15810 // Build privatized reference to the current linear var.
15811 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
15813 if (LinKind == OMPC_LINEAR_uval)
15814 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
15817 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
15818 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
15819 /*RefersToCapture=*/true);
15821 // Build update: Var = InitExpr + IV * Step
15824 Update = buildCounterUpdate(
15825 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
15826 /*Subtract=*/false, /*IsNonRectangularLB=*/false);
15828 Update = *CurPrivate;
15829 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
15830 /*DiscardedValue*/ false);
15832 // Build final: Var = InitExpr + NumIterations * Step
15836 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
15837 InitExpr, NumIterations, Step, /*Subtract=*/false,
15838 /*IsNonRectangularLB=*/false);
15840 Final = *CurPrivate;
15841 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
15842 /*DiscardedValue*/ false);
15844 if (!Update.isUsable() || !Final.isUsable()) {
15845 Updates.push_back(nullptr);
15846 Finals.push_back(nullptr);
15847 UsedExprs.push_back(nullptr);
15850 Updates.push_back(Update.get());
15851 Finals.push_back(Final.get());
15853 UsedExprs.push_back(SimpleRefExpr);
15858 if (Expr *S = Clause.getStep())
15859 UsedExprs.push_back(S);
15860 // Fill the remaining part with the nullptr.
15861 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
15862 Clause.setUpdates(Updates);
15863 Clause.setFinals(Finals);
15864 Clause.setUsedExprs(UsedExprs);
15868 OMPClause *Sema::ActOnOpenMPAlignedClause(
15869 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
15870 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
15871 SmallVector<Expr *, 8> Vars;
15872 for (Expr *RefExpr : VarList) {
15873 assert(RefExpr && "NULL expr in OpenMP linear clause.");
15874 SourceLocation ELoc;
15875 SourceRange ERange;
15876 Expr *SimpleRefExpr = RefExpr;
15877 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15879 // It will be analyzed later.
15880 Vars.push_back(RefExpr);
15882 ValueDecl *D = Res.first;
15886 QualType QType = D->getType();
15887 auto *VD = dyn_cast<VarDecl>(D);
15889 // OpenMP [2.8.1, simd construct, Restrictions]
15890 // The type of list items appearing in the aligned clause must be
15891 // array, pointer, reference to array, or reference to pointer.
15892 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
15893 const Type *Ty = QType.getTypePtrOrNull();
15894 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
15895 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
15896 << QType << getLangOpts().CPlusPlus << ERange;
15899 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15900 Diag(D->getLocation(),
15901 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15906 // OpenMP [2.8.1, simd construct, Restrictions]
15907 // A list-item cannot appear in more than one aligned clause.
15908 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
15909 Diag(ELoc, diag::err_omp_used_in_clause_twice)
15910 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
15911 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
15912 << getOpenMPClauseName(OMPC_aligned);
15916 DeclRefExpr *Ref = nullptr;
15917 if (!VD && isOpenMPCapturedDecl(D))
15918 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15919 Vars.push_back(DefaultFunctionArrayConversion(
15920 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
15924 // OpenMP [2.8.1, simd construct, Description]
15925 // The parameter of the aligned clause, alignment, must be a constant
15926 // positive integer expression.
15927 // If no optional parameter is specified, implementation-defined default
15928 // alignments for SIMD instructions on the target platforms are assumed.
15929 if (Alignment != nullptr) {
15930 ExprResult AlignResult =
15931 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
15932 if (AlignResult.isInvalid())
15934 Alignment = AlignResult.get();
15939 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
15940 EndLoc, Vars, Alignment);
15943 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
15944 SourceLocation StartLoc,
15945 SourceLocation LParenLoc,
15946 SourceLocation EndLoc) {
15947 SmallVector<Expr *, 8> Vars;
15948 SmallVector<Expr *, 8> SrcExprs;
15949 SmallVector<Expr *, 8> DstExprs;
15950 SmallVector<Expr *, 8> AssignmentOps;
15951 for (Expr *RefExpr : VarList) {
15952 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
15953 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
15954 // It will be analyzed later.
15955 Vars.push_back(RefExpr);
15956 SrcExprs.push_back(nullptr);
15957 DstExprs.push_back(nullptr);
15958 AssignmentOps.push_back(nullptr);
15962 SourceLocation ELoc = RefExpr->getExprLoc();
15963 // OpenMP [2.1, C/C++]
15964 // A list item is a variable name.
15965 // OpenMP [2.14.4.1, Restrictions, p.1]
15966 // A list item that appears in a copyin clause must be threadprivate.
15967 auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
15968 if (!DE || !isa<VarDecl>(DE->getDecl())) {
15969 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
15970 << 0 << RefExpr->getSourceRange();
15974 Decl *D = DE->getDecl();
15975 auto *VD = cast<VarDecl>(D);
15977 QualType Type = VD->getType();
15978 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
15979 // It will be analyzed later.
15980 Vars.push_back(DE);
15981 SrcExprs.push_back(nullptr);
15982 DstExprs.push_back(nullptr);
15983 AssignmentOps.push_back(nullptr);
15987 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
15988 // A list item that appears in a copyin clause must be threadprivate.
15989 if (!DSAStack->isThreadPrivate(VD)) {
15990 Diag(ELoc, diag::err_omp_required_access)
15991 << getOpenMPClauseName(OMPC_copyin)
15992 << getOpenMPDirectiveName(OMPD_threadprivate);
15996 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
15997 // A variable of class type (or array thereof) that appears in a
15998 // copyin clause requires an accessible, unambiguous copy assignment
15999 // operator for the class type.
16000 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16002 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
16003 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16004 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
16005 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
16007 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
16008 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
16009 DeclRefExpr *PseudoDstExpr =
16010 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
16011 // For arrays generate assignment operation for single element and replace
16012 // it by the original array element in CodeGen.
16013 ExprResult AssignmentOp =
16014 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
16016 if (AssignmentOp.isInvalid())
16018 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
16019 /*DiscardedValue*/ false);
16020 if (AssignmentOp.isInvalid())
16023 DSAStack->addDSA(VD, DE, OMPC_copyin);
16024 Vars.push_back(DE);
16025 SrcExprs.push_back(PseudoSrcExpr);
16026 DstExprs.push_back(PseudoDstExpr);
16027 AssignmentOps.push_back(AssignmentOp.get());
16033 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16034 SrcExprs, DstExprs, AssignmentOps);
16037 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
16038 SourceLocation StartLoc,
16039 SourceLocation LParenLoc,
16040 SourceLocation EndLoc) {
16041 SmallVector<Expr *, 8> Vars;
16042 SmallVector<Expr *, 8> SrcExprs;
16043 SmallVector<Expr *, 8> DstExprs;
16044 SmallVector<Expr *, 8> AssignmentOps;
16045 for (Expr *RefExpr : VarList) {
16046 assert(RefExpr && "NULL expr in OpenMP linear clause.");
16047 SourceLocation ELoc;
16048 SourceRange ERange;
16049 Expr *SimpleRefExpr = RefExpr;
16050 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16052 // It will be analyzed later.
16053 Vars.push_back(RefExpr);
16054 SrcExprs.push_back(nullptr);
16055 DstExprs.push_back(nullptr);
16056 AssignmentOps.push_back(nullptr);
16058 ValueDecl *D = Res.first;
16062 QualType Type = D->getType();
16063 auto *VD = dyn_cast<VarDecl>(D);
16065 // OpenMP [2.14.4.2, Restrictions, p.2]
16066 // A list item that appears in a copyprivate clause may not appear in a
16067 // private or firstprivate clause on the single construct.
16068 if (!VD || !DSAStack->isThreadPrivate(VD)) {
16069 DSAStackTy::DSAVarData DVar =
16070 DSAStack->getTopDSA(D, /*FromParent=*/false);
16071 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
16073 Diag(ELoc, diag::err_omp_wrong_dsa)
16074 << getOpenMPClauseName(DVar.CKind)
16075 << getOpenMPClauseName(OMPC_copyprivate);
16076 reportOriginalDsa(*this, DSAStack, D, DVar);
16080 // OpenMP [2.11.4.2, Restrictions, p.1]
16081 // All list items that appear in a copyprivate clause must be either
16082 // threadprivate or private in the enclosing context.
16083 if (DVar.CKind == OMPC_unknown) {
16084 DVar = DSAStack->getImplicitDSA(D, false);
16085 if (DVar.CKind == OMPC_shared) {
16086 Diag(ELoc, diag::err_omp_required_access)
16087 << getOpenMPClauseName(OMPC_copyprivate)
16088 << "threadprivate or private in the enclosing context";
16089 reportOriginalDsa(*this, DSAStack, D, DVar);
16095 // Variably modified types are not supported.
16096 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
16097 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16098 << getOpenMPClauseName(OMPC_copyprivate) << Type
16099 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
16102 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
16103 Diag(D->getLocation(),
16104 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16109 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
16110 // A variable of class type (or array thereof) that appears in a
16111 // copyin clause requires an accessible, unambiguous copy assignment
16112 // operator for the class type.
16113 Type = Context.getBaseElementType(Type.getNonReferenceType())
16114 .getUnqualifiedType();
16116 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
16117 D->hasAttrs() ? &D->getAttrs() : nullptr);
16118 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
16120 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
16121 D->hasAttrs() ? &D->getAttrs() : nullptr);
16122 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16123 ExprResult AssignmentOp = BuildBinOp(
16124 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
16125 if (AssignmentOp.isInvalid())
16128 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16129 if (AssignmentOp.isInvalid())
16132 // No need to mark vars as copyprivate, they are already threadprivate or
16133 // implicitly private.
16134 assert(VD || isOpenMPCapturedDecl(D));
16136 VD ? RefExpr->IgnoreParens()
16137 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
16138 SrcExprs.push_back(PseudoSrcExpr);
16139 DstExprs.push_back(PseudoDstExpr);
16140 AssignmentOps.push_back(AssignmentOp.get());
16146 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16147 Vars, SrcExprs, DstExprs, AssignmentOps);
16150 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
16151 SourceLocation StartLoc,
16152 SourceLocation LParenLoc,
16153 SourceLocation EndLoc) {
16154 if (VarList.empty())
16157 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
16160 /// Tries to find omp_depend_t. type.
16161 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
16162 bool Diagnose = true) {
16163 QualType OMPDependT = Stack->getOMPDependT();
16164 if (!OMPDependT.isNull())
16166 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
16167 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16168 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16170 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
16173 Stack->setOMPDependT(PT.get());
16177 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
16178 SourceLocation LParenLoc,
16179 SourceLocation EndLoc) {
16183 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
16185 // OpenMP 5.0, 2.17.10.1 depobj Construct
16186 // depobj is an lvalue expression of type omp_depend_t.
16187 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
16188 !Depobj->isInstantiationDependent() &&
16189 !Depobj->containsUnexpandedParameterPack() &&
16190 (OMPDependTFound &&
16191 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
16192 /*CompareUnqualified=*/true))) {
16193 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16194 << 0 << Depobj->getType() << Depobj->getSourceRange();
16197 if (!Depobj->isLValue()) {
16198 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
16199 << 1 << Depobj->getSourceRange();
16202 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
16206 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
16207 SourceLocation DepLoc, SourceLocation ColonLoc,
16208 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
16209 SourceLocation LParenLoc, SourceLocation EndLoc) {
16210 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
16211 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
16212 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16213 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
16216 if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
16217 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16218 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
16219 DepKind == OMPC_DEPEND_sink ||
16220 ((LangOpts.OpenMP < 50 ||
16221 DSAStack->getCurrentDirective() == OMPD_depobj) &&
16222 DepKind == OMPC_DEPEND_depobj))) {
16223 SmallVector<unsigned, 3> Except;
16224 Except.push_back(OMPC_DEPEND_source);
16225 Except.push_back(OMPC_DEPEND_sink);
16226 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
16227 Except.push_back(OMPC_DEPEND_depobj);
16228 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
16229 ? "depend modifier(iterator) or "
16231 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
16232 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
16233 /*Last=*/OMPC_DEPEND_unknown,
16235 << getOpenMPClauseName(OMPC_depend);
16239 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
16240 Diag(DepModifier->getExprLoc(),
16241 diag::err_omp_depend_sink_source_with_modifier);
16245 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
16246 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
16248 SmallVector<Expr *, 8> Vars;
16249 DSAStackTy::OperatorOffsetTy OpsOffs;
16250 llvm::APSInt DepCounter(/*BitWidth=*/32);
16251 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
16252 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
16253 if (const Expr *OrderedCountExpr =
16254 DSAStack->getParentOrderedRegionParam().first) {
16255 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
16256 TotalDepCount.setIsUnsigned(/*Val=*/true);
16259 for (Expr *RefExpr : VarList) {
16260 assert(RefExpr && "NULL expr in OpenMP shared clause.");
16261 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
16262 // It will be analyzed later.
16263 Vars.push_back(RefExpr);
16267 SourceLocation ELoc = RefExpr->getExprLoc();
16268 Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
16269 if (DepKind == OMPC_DEPEND_sink) {
16270 if (DSAStack->getParentOrderedRegionParam().first &&
16271 DepCounter >= TotalDepCount) {
16272 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
16276 // OpenMP [2.13.9, Summary]
16277 // depend(dependence-type : vec), where dependence-type is:
16278 // 'sink' and where vec is the iteration vector, which has the form:
16279 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
16280 // where n is the value specified by the ordered clause in the loop
16281 // directive, xi denotes the loop iteration variable of the i-th nested
16282 // loop associated with the loop directive, and di is a constant
16283 // non-negative integer.
16284 if (CurContext->isDependentContext()) {
16285 // It will be analyzed later.
16286 Vars.push_back(RefExpr);
16289 SimpleExpr = SimpleExpr->IgnoreImplicit();
16290 OverloadedOperatorKind OOK = OO_None;
16291 SourceLocation OOLoc;
16292 Expr *LHS = SimpleExpr;
16293 Expr *RHS = nullptr;
16294 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
16295 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
16296 OOLoc = BO->getOperatorLoc();
16297 LHS = BO->getLHS()->IgnoreParenImpCasts();
16298 RHS = BO->getRHS()->IgnoreParenImpCasts();
16299 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
16300 OOK = OCE->getOperator();
16301 OOLoc = OCE->getOperatorLoc();
16302 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16303 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
16304 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
16305 OOK = MCE->getMethodDecl()
16308 .getCXXOverloadedOperator();
16309 OOLoc = MCE->getCallee()->getExprLoc();
16310 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
16311 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
16313 SourceLocation ELoc;
16314 SourceRange ERange;
16315 auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
16317 // It will be analyzed later.
16318 Vars.push_back(RefExpr);
16320 ValueDecl *D = Res.first;
16324 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
16325 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
16329 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
16330 RHS, OMPC_depend, /*StrictlyPositive=*/false);
16331 if (RHSRes.isInvalid())
16334 if (!CurContext->isDependentContext() &&
16335 DSAStack->getParentOrderedRegionParam().first &&
16336 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
16337 const ValueDecl *VD =
16338 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
16340 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
16343 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
16346 OpsOffs.emplace_back(RHS, OOK);
16348 bool OMPDependTFound = LangOpts.OpenMP >= 50;
16349 if (OMPDependTFound)
16350 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
16351 DepKind == OMPC_DEPEND_depobj);
16352 if (DepKind == OMPC_DEPEND_depobj) {
16353 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16354 // List items used in depend clauses with the depobj dependence type
16355 // must be expressions of the omp_depend_t type.
16356 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16357 !RefExpr->isInstantiationDependent() &&
16358 !RefExpr->containsUnexpandedParameterPack() &&
16359 (OMPDependTFound &&
16360 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
16361 RefExpr->getType()))) {
16362 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16363 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
16366 if (!RefExpr->isLValue()) {
16367 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
16368 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
16372 // OpenMP 5.0 [2.17.11, Restrictions]
16373 // List items used in depend clauses cannot be zero-length array
16375 QualType ExprTy = RefExpr->getType().getNonReferenceType();
16376 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
16378 QualType BaseType =
16379 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16380 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16381 ExprTy = ATy->getElementType();
16383 ExprTy = BaseType->getPointeeType();
16384 ExprTy = ExprTy.getNonReferenceType();
16385 const Expr *Length = OASE->getLength();
16386 Expr::EvalResult Result;
16387 if (Length && !Length->isValueDependent() &&
16388 Length->EvaluateAsInt(Result, Context) &&
16389 Result.Val.getInt().isNullValue()) {
16391 diag::err_omp_depend_zero_length_array_section_not_allowed)
16392 << SimpleExpr->getSourceRange();
16397 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
16398 // List items used in depend clauses with the in, out, inout or
16399 // mutexinoutset dependence types cannot be expressions of the
16400 // omp_depend_t type.
16401 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
16402 !RefExpr->isInstantiationDependent() &&
16403 !RefExpr->containsUnexpandedParameterPack() &&
16404 (OMPDependTFound &&
16405 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
16406 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16407 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
16408 << RefExpr->getSourceRange();
16412 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
16413 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
16414 (ASE && !ASE->getBase()->isTypeDependent() &&
16417 .getNonReferenceType()
16418 ->isPointerType() &&
16419 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
16420 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16421 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16422 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16428 Sema::TentativeAnalysisScope Trap(*this);
16429 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
16430 RefExpr->IgnoreParenImpCasts());
16432 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
16433 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
16434 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
16435 << (LangOpts.OpenMP >= 50 ? 1 : 0)
16436 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
16441 Vars.push_back(RefExpr->IgnoreParenImpCasts());
16444 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
16445 TotalDepCount > VarList.size() &&
16446 DSAStack->getParentOrderedRegionParam().first &&
16447 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
16448 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
16449 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
16451 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
16455 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16456 DepModifier, DepKind, DepLoc, ColonLoc,
16457 Vars, TotalDepCount.getZExtValue());
16458 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
16459 DSAStack->isParentOrderedRegion())
16460 DSAStack->addDoacrossDependClause(C, OpsOffs);
16464 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
16465 Expr *Device, SourceLocation StartLoc,
16466 SourceLocation LParenLoc,
16467 SourceLocation ModifierLoc,
16468 SourceLocation EndLoc) {
16469 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
16470 "Unexpected device modifier in OpenMP < 50.");
16472 bool ErrorFound = false;
16473 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
16474 std::string Values =
16475 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
16476 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
16477 << Values << getOpenMPClauseName(OMPC_device);
16481 Expr *ValExpr = Device;
16482 Stmt *HelperValStmt = nullptr;
16484 // OpenMP [2.9.1, Restrictions]
16485 // The device expression must evaluate to a non-negative integer value.
16486 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
16487 /*StrictlyPositive=*/false) ||
16492 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16493 OpenMPDirectiveKind CaptureRegion =
16494 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
16495 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16496 ValExpr = MakeFullExpr(ValExpr).get();
16497 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16498 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16499 HelperValStmt = buildPreInits(Context, Captures);
16502 return new (Context)
16503 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16504 LParenLoc, ModifierLoc, EndLoc);
16507 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
16508 DSAStackTy *Stack, QualType QTy,
16509 bool FullCheck = true) {
16511 if (QTy->isIncompleteType(&ND)) {
16512 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
16515 if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
16516 !QTy.isTriviallyCopyableType(SemaRef.Context))
16517 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
16521 /// Return true if it can be proven that the provided array expression
16522 /// (array section or array subscript) does NOT specify the whole size of the
16523 /// array whose base type is \a BaseQTy.
16524 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
16526 QualType BaseQTy) {
16527 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16529 // If this is an array subscript, it refers to the whole size if the size of
16530 // the dimension is constant and equals 1. Also, an array section assumes the
16531 // format of an array subscript if no colon is used.
16532 if (isa<ArraySubscriptExpr>(E) ||
16533 (OASE && OASE->getColonLocFirst().isInvalid())) {
16534 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16535 return ATy->getSize().getSExtValue() != 1;
16536 // Size can't be evaluated statically.
16540 assert(OASE && "Expecting array section if not an array subscript.");
16541 const Expr *LowerBound = OASE->getLowerBound();
16542 const Expr *Length = OASE->getLength();
16544 // If there is a lower bound that does not evaluates to zero, we are not
16545 // covering the whole dimension.
16547 Expr::EvalResult Result;
16548 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
16549 return false; // Can't get the integer value as a constant.
16551 llvm::APSInt ConstLowerBound = Result.Val.getInt();
16552 if (ConstLowerBound.getSExtValue())
16556 // If we don't have a length we covering the whole dimension.
16560 // If the base is a pointer, we don't have a way to get the size of the
16562 if (BaseQTy->isPointerType())
16565 // We can only check if the length is the same as the size of the dimension
16566 // if we have a constant array.
16567 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
16571 Expr::EvalResult Result;
16572 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16573 return false; // Can't get the integer value as a constant.
16575 llvm::APSInt ConstLength = Result.Val.getInt();
16576 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
16579 // Return true if it can be proven that the provided array expression (array
16580 // section or array subscript) does NOT specify a single element of the array
16581 // whose base type is \a BaseQTy.
16582 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
16584 QualType BaseQTy) {
16585 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
16587 // An array subscript always refer to a single element. Also, an array section
16588 // assumes the format of an array subscript if no colon is used.
16589 if (isa<ArraySubscriptExpr>(E) ||
16590 (OASE && OASE->getColonLocFirst().isInvalid()))
16593 assert(OASE && "Expecting array section if not an array subscript.");
16594 const Expr *Length = OASE->getLength();
16596 // If we don't have a length we have to check if the array has unitary size
16597 // for this dimension. Also, we should always expect a length if the base type
16600 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
16601 return ATy->getSize().getSExtValue() != 1;
16602 // We cannot assume anything.
16606 // Check if the length evaluates to 1.
16607 Expr::EvalResult Result;
16608 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
16609 return false; // Can't get the integer value as a constant.
16611 llvm::APSInt ConstLength = Result.Val.getInt();
16612 return ConstLength.getSExtValue() != 1;
16615 // The base of elements of list in a map clause have to be either:
16616 // - a reference to variable or field.
16617 // - a member expression.
16618 // - an array expression.
16620 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
16621 // reference to 'r'.
16628 // #pragma omp target map (S.Arr[:12]);
16632 // We want to retrieve the member expression 'this->S';
16634 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
16635 // If a list item is an array section, it must specify contiguous storage.
16637 // For this restriction it is sufficient that we make sure only references
16638 // to variables or fields and array expressions, and that no array sections
16639 // exist except in the rightmost expression (unless they cover the whole
16640 // dimension of the array). E.g. these would be invalid:
16642 // r.ArrS[3:5].Arr[6:7]
16646 // but these would be valid:
16647 // r.ArrS[3].Arr[6:7]
16651 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
16653 OpenMPClauseKind CKind = OMPC_unknown;
16654 OMPClauseMappableExprCommon::MappableExprComponentList &Components;
16655 bool NoDiagnose = false;
16656 const Expr *RelevantExpr = nullptr;
16657 bool AllowUnitySizeArraySection = true;
16658 bool AllowWholeSizeArraySection = true;
16659 SourceLocation ELoc;
16660 SourceRange ERange;
16662 void emitErrorMsg() {
16663 // If nothing else worked, this is not a valid map clause expression.
16664 if (SemaRef.getLangOpts().OpenMP < 50) {
16666 diag::err_omp_expected_named_var_member_or_array_expression)
16669 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
16670 << getOpenMPClauseName(CKind) << ERange;
16675 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
16676 if (!isa<VarDecl>(DRE->getDecl())) {
16680 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16681 RelevantExpr = DRE;
16682 // Record the component.
16683 Components.emplace_back(DRE, DRE->getDecl());
16687 bool VisitMemberExpr(MemberExpr *ME) {
16689 Expr *BaseE = ME->getBase()->IgnoreParenCasts();
16691 if (isa<CXXThisExpr>(BaseE)) {
16692 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16693 // We found a base expression: this->Val.
16699 if (!isa<FieldDecl>(ME->getMemberDecl())) {
16701 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
16702 << ME->getSourceRange();
16710 auto *FD = cast<FieldDecl>(ME->getMemberDecl());
16712 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
16713 // A bit-field cannot appear in a map clause.
16715 if (FD->isBitField()) {
16717 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
16718 << ME->getSourceRange() << getOpenMPClauseName(CKind);
16726 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16727 // If the type of a list item is a reference to a type T then the type
16728 // will be considered to be T for all purposes of this clause.
16729 QualType CurType = BaseE->getType().getNonReferenceType();
16731 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
16732 // A list item cannot be a variable that is a member of a structure with
16735 if (CurType->isUnionType()) {
16737 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
16738 << ME->getSourceRange();
16741 return RelevantExpr || Visit(E);
16744 // If we got a member expression, we should not expect any array section
16747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
16748 // If a list item is an element of a structure, only the rightmost symbol
16749 // of the variable reference can be an array section.
16751 AllowUnitySizeArraySection = false;
16752 AllowWholeSizeArraySection = false;
16754 // Record the component.
16755 Components.emplace_back(ME, FD);
16756 return RelevantExpr || Visit(E);
16759 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
16760 Expr *E = AE->getBase()->IgnoreParenImpCasts();
16762 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
16764 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16765 << 0 << AE->getSourceRange();
16768 return RelevantExpr || Visit(E);
16771 // If we got an array subscript that express the whole dimension we
16772 // can have any array expressions before. If it only expressing part of
16773 // the dimension, we can only have unitary-size array expressions.
16774 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
16776 AllowWholeSizeArraySection = false;
16778 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
16779 Expr::EvalResult Result;
16780 if (!AE->getIdx()->isValueDependent() &&
16781 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
16782 !Result.Val.getInt().isNullValue()) {
16783 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16784 diag::err_omp_invalid_map_this_expr);
16785 SemaRef.Diag(AE->getIdx()->getExprLoc(),
16786 diag::note_omp_invalid_subscript_on_this_ptr_map);
16788 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16792 // Record the component - we don't have any declaration associated.
16793 Components.emplace_back(AE, nullptr);
16795 return RelevantExpr || Visit(E);
16798 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
16799 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
16800 Expr *E = OASE->getBase()->IgnoreParenImpCasts();
16802 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
16804 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16805 // If the type of a list item is a reference to a type T then the type
16806 // will be considered to be T for all purposes of this clause.
16807 if (CurType->isReferenceType())
16808 CurType = CurType->getPointeeType();
16810 bool IsPointer = CurType->isAnyPointerType();
16812 if (!IsPointer && !CurType->isArrayType()) {
16813 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
16814 << 0 << OASE->getSourceRange();
16819 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
16821 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
16823 if (AllowWholeSizeArraySection) {
16824 // Any array section is currently allowed. Allowing a whole size array
16825 // section implies allowing a unity array section as well.
16827 // If this array section refers to the whole dimension we can still
16828 // accept other array sections before this one, except if the base is a
16829 // pointer. Otherwise, only unitary sections are accepted.
16830 if (NotWhole || IsPointer)
16831 AllowWholeSizeArraySection = false;
16832 } else if (AllowUnitySizeArraySection && NotUnity) {
16833 // A unity or whole array section is not allowed and that is not
16834 // compatible with the properties of the current array section.
16836 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
16837 << OASE->getSourceRange();
16841 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
16842 Expr::EvalResult ResultR;
16843 Expr::EvalResult ResultL;
16844 if (!OASE->getLength()->isValueDependent() &&
16845 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
16846 !ResultR.Val.getInt().isOneValue()) {
16847 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16848 diag::err_omp_invalid_map_this_expr);
16849 SemaRef.Diag(OASE->getLength()->getExprLoc(),
16850 diag::note_omp_invalid_length_on_this_ptr_mapping);
16852 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
16853 OASE->getLowerBound()->EvaluateAsInt(ResultL,
16854 SemaRef.getASTContext()) &&
16855 !ResultL.Val.getInt().isNullValue()) {
16856 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16857 diag::err_omp_invalid_map_this_expr);
16858 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
16859 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
16861 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16865 // Record the component - we don't have any declaration associated.
16866 Components.emplace_back(OASE, nullptr);
16867 return RelevantExpr || Visit(E);
16869 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
16870 Expr *Base = E->getBase();
16872 // Record the component - we don't have any declaration associated.
16873 Components.emplace_back(E, nullptr);
16875 return Visit(Base->IgnoreParenImpCasts());
16878 bool VisitUnaryOperator(UnaryOperator *UO) {
16879 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
16880 UO->getOpcode() != UO_Deref) {
16884 if (!RelevantExpr) {
16885 // Record the component if haven't found base decl.
16886 Components.emplace_back(UO, nullptr);
16888 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
16890 bool VisitBinaryOperator(BinaryOperator *BO) {
16891 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
16896 // Pointer arithmetic is the only thing we expect to happen here so after we
16897 // make sure the binary operator is a pointer type, the we only thing need
16898 // to to is to visit the subtree that has the same type as root (so that we
16899 // know the other subtree is just an offset)
16900 Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
16901 Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
16902 Components.emplace_back(BO, nullptr);
16903 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
16904 RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
16905 "Either LHS or RHS have base decl inside");
16906 if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
16907 return RelevantExpr || Visit(LE);
16908 return RelevantExpr || Visit(RE);
16910 bool VisitCXXThisExpr(CXXThisExpr *CTE) {
16911 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
16912 RelevantExpr = CTE;
16913 Components.emplace_back(CTE, nullptr);
16916 bool VisitStmt(Stmt *) {
16920 const Expr *getFoundBase() const {
16921 return RelevantExpr;
16923 explicit MapBaseChecker(
16924 Sema &SemaRef, OpenMPClauseKind CKind,
16925 OMPClauseMappableExprCommon::MappableExprComponentList &Components,
16926 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
16927 : SemaRef(SemaRef), CKind(CKind), Components(Components),
16928 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
16932 /// Return the expression of the base of the mappable expression or null if it
16933 /// cannot be determined and do all the necessary checks to see if the expression
16934 /// is valid as a standalone mappable expression. In the process, record all the
16935 /// components of the expression.
16936 static const Expr *checkMapClauseExpressionBase(
16937 Sema &SemaRef, Expr *E,
16938 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
16939 OpenMPClauseKind CKind, bool NoDiagnose) {
16940 SourceLocation ELoc = E->getExprLoc();
16941 SourceRange ERange = E->getSourceRange();
16942 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc,
16944 if (Checker.Visit(E->IgnoreParens()))
16945 return Checker.getFoundBase();
16949 // Return true if expression E associated with value VD has conflicts with other
16950 // map information.
16951 static bool checkMapConflicts(
16952 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
16953 bool CurrentRegionOnly,
16954 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
16955 OpenMPClauseKind CKind) {
16957 SourceLocation ELoc = E->getExprLoc();
16958 SourceRange ERange = E->getSourceRange();
16960 // In order to easily check the conflicts we need to match each component of
16961 // the expression under test with the components of the expressions that are
16962 // already in the stack.
16964 assert(!CurComponents.empty() && "Map clause expression with no components!");
16965 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
16966 "Map clause expression with unexpected base!");
16968 // Variables to help detecting enclosing problems in data environment nests.
16969 bool IsEnclosedByDataEnvironmentExpr = false;
16970 const Expr *EnclosingExpr = nullptr;
16972 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
16973 VD, CurrentRegionOnly,
16974 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
16975 ERange, CKind, &EnclosingExpr,
16976 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
16978 OpenMPClauseKind) {
16979 assert(!StackComponents.empty() &&
16980 "Map clause expression with no components!");
16981 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
16982 "Map clause expression with unexpected base!");
16985 // The whole expression in the stack.
16986 const Expr *RE = StackComponents.front().getAssociatedExpression();
16988 // Expressions must start from the same base. Here we detect at which
16989 // point both expressions diverge from each other and see if we can
16990 // detect if the memory referred to both expressions is contiguous and
16992 auto CI = CurComponents.rbegin();
16993 auto CE = CurComponents.rend();
16994 auto SI = StackComponents.rbegin();
16995 auto SE = StackComponents.rend();
16996 for (; CI != CE && SI != SE; ++CI, ++SI) {
16998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
16999 // At most one list item can be an array item derived from a given
17000 // variable in map clauses of the same construct.
17001 if (CurrentRegionOnly &&
17002 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
17003 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
17004 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
17005 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
17006 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
17007 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
17008 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
17009 diag::err_omp_multiple_array_items_in_map_clause)
17010 << CI->getAssociatedExpression()->getSourceRange();
17011 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
17012 diag::note_used_here)
17013 << SI->getAssociatedExpression()->getSourceRange();
17017 // Do both expressions have the same kind?
17018 if (CI->getAssociatedExpression()->getStmtClass() !=
17019 SI->getAssociatedExpression()->getStmtClass())
17022 // Are we dealing with different variables/fields?
17023 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
17026 // Check if the extra components of the expressions in the enclosing
17027 // data environment are redundant for the current base declaration.
17028 // If they are, the maps completely overlap, which is legal.
17029 for (; SI != SE; ++SI) {
17031 if (const auto *ASE =
17032 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
17033 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
17034 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
17035 SI->getAssociatedExpression())) {
17036 const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
17038 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
17039 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
17040 SI->getAssociatedExpression())) {
17041 Type = OASE->getBase()->getType()->getPointeeType();
17043 if (Type.isNull() || Type->isAnyPointerType() ||
17044 checkArrayExpressionDoesNotReferToWholeSize(
17045 SemaRef, SI->getAssociatedExpression(), Type))
17049 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17050 // List items of map clauses in the same construct must not share
17051 // original storage.
17053 // If the expressions are exactly the same or one is a subset of the
17054 // other, it means they are sharing storage.
17055 if (CI == CE && SI == SE) {
17056 if (CurrentRegionOnly) {
17057 if (CKind == OMPC_map) {
17058 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17060 assert(CKind == OMPC_to || CKind == OMPC_from);
17061 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17064 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17065 << RE->getSourceRange();
17068 // If we find the same expression in the enclosing data environment,
17070 IsEnclosedByDataEnvironmentExpr = true;
17074 QualType DerivedType =
17075 std::prev(CI)->getAssociatedDeclaration()->getType();
17076 SourceLocation DerivedLoc =
17077 std::prev(CI)->getAssociatedExpression()->getExprLoc();
17079 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17080 // If the type of a list item is a reference to a type T then the type
17081 // will be considered to be T for all purposes of this clause.
17082 DerivedType = DerivedType.getNonReferenceType();
17084 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
17085 // A variable for which the type is pointer and an array section
17086 // derived from that variable must not appear as list items of map
17087 // clauses of the same construct.
17089 // Also, cover one of the cases in:
17090 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17091 // If any part of the original storage of a list item has corresponding
17092 // storage in the device data environment, all of the original storage
17093 // must have corresponding storage in the device data environment.
17095 if (DerivedType->isAnyPointerType()) {
17096 if (CI == CE || SI == SE) {
17099 diag::err_omp_pointer_mapped_along_with_derived_section)
17101 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17102 << RE->getSourceRange();
17105 if (CI->getAssociatedExpression()->getStmtClass() !=
17106 SI->getAssociatedExpression()->getStmtClass() ||
17107 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
17108 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
17109 assert(CI != CE && SI != SE);
17110 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
17112 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17113 << RE->getSourceRange();
17118 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
17119 // List items of map clauses in the same construct must not share
17120 // original storage.
17122 // An expression is a subset of the other.
17123 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
17124 if (CKind == OMPC_map) {
17125 if (CI != CE || SI != SE) {
17126 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
17129 CI != CE ? CurComponents.begin() : StackComponents.begin();
17130 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
17132 while (It != End && !It->getAssociatedDeclaration())
17133 std::advance(It, 1);
17134 assert(It != End &&
17135 "Expected at least one component with the declaration.");
17136 if (It != Begin && It->getAssociatedDeclaration()
17138 .getCanonicalType()
17139 ->isAnyPointerType()) {
17140 IsEnclosedByDataEnvironmentExpr = false;
17141 EnclosingExpr = nullptr;
17145 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
17147 assert(CKind == OMPC_to || CKind == OMPC_from);
17148 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
17151 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
17152 << RE->getSourceRange();
17156 // The current expression uses the same base as other expression in the
17157 // data environment but does not contain it completely.
17158 if (!CurrentRegionOnly && SI != SE)
17159 EnclosingExpr = RE;
17161 // The current expression is a subset of the expression in the data
17163 IsEnclosedByDataEnvironmentExpr |=
17164 (!CurrentRegionOnly && CI != CE && SI == SE);
17169 if (CurrentRegionOnly)
17172 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
17173 // If any part of the original storage of a list item has corresponding
17174 // storage in the device data environment, all of the original storage must
17175 // have corresponding storage in the device data environment.
17176 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
17177 // If a list item is an element of a structure, and a different element of
17178 // the structure has a corresponding list item in the device data environment
17179 // prior to a task encountering the construct associated with the map clause,
17180 // then the list item must also have a corresponding list item in the device
17181 // data environment prior to the task encountering the construct.
17183 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
17185 diag::err_omp_original_storage_is_shared_and_does_not_contain)
17187 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
17188 << EnclosingExpr->getSourceRange();
17195 // Look up the user-defined mapper given the mapper name and mapped type, and
17196 // build a reference to it.
17197 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
17198 CXXScopeSpec &MapperIdScopeSpec,
17199 const DeclarationNameInfo &MapperId,
17201 Expr *UnresolvedMapper) {
17202 if (MapperIdScopeSpec.isInvalid())
17203 return ExprError();
17204 // Get the actual type for the array type.
17205 if (Type->isArrayType()) {
17206 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
17207 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
17209 // Find all user-defined mappers with the given MapperId.
17210 SmallVector<UnresolvedSet<8>, 4> Lookups;
17211 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
17212 Lookup.suppressDiagnostics();
17214 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
17215 NamedDecl *D = Lookup.getRepresentativeDecl();
17216 while (S && !S->isDeclScope(D))
17217 S = S->getParent();
17219 S = S->getParent();
17220 Lookups.emplace_back();
17221 Lookups.back().append(Lookup.begin(), Lookup.end());
17224 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
17225 // Extract the user-defined mappers with the given MapperId.
17226 Lookups.push_back(UnresolvedSet<8>());
17227 for (NamedDecl *D : ULE->decls()) {
17228 auto *DMD = cast<OMPDeclareMapperDecl>(D);
17229 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
17230 Lookups.back().addDecl(DMD);
17233 // Defer the lookup for dependent types. The results will be passed through
17234 // UnresolvedMapper on instantiation.
17235 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
17236 Type->isInstantiationDependentType() ||
17237 Type->containsUnexpandedParameterPack() ||
17238 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17239 return !D->isInvalidDecl() &&
17240 (D->getType()->isDependentType() ||
17241 D->getType()->isInstantiationDependentType() ||
17242 D->getType()->containsUnexpandedParameterPack());
17244 UnresolvedSet<8> URS;
17245 for (const UnresolvedSet<8> &Set : Lookups) {
17248 URS.append(Set.begin(), Set.end());
17250 return UnresolvedLookupExpr::Create(
17251 SemaRef.Context, /*NamingClass=*/nullptr,
17252 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
17253 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
17255 SourceLocation Loc = MapperId.getLoc();
17256 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17257 // The type must be of struct, union or class type in C and C++
17258 if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
17259 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
17260 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
17261 return ExprError();
17263 // Perform argument dependent lookup.
17264 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
17265 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
17266 // Return the first user-defined mapper with the desired type.
17267 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17268 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
17269 if (!D->isInvalidDecl() &&
17270 SemaRef.Context.hasSameType(D->getType(), Type))
17274 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17275 // Find the first user-defined mapper with a type derived from the desired
17277 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17278 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
17279 if (!D->isInvalidDecl() &&
17280 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
17281 !Type.isMoreQualifiedThan(D->getType()))
17285 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17286 /*DetectVirtual=*/false);
17287 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
17288 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17289 VD->getType().getUnqualifiedType()))) {
17290 if (SemaRef.CheckBaseClassAccess(
17291 Loc, VD->getType(), Type, Paths.front(),
17292 /*DiagID=*/0) != Sema::AR_inaccessible) {
17293 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
17298 // Report error if a mapper is specified, but cannot be found.
17299 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
17300 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
17301 << Type << MapperId.getName();
17302 return ExprError();
17304 return ExprEmpty();
17308 // Utility struct that gathers all the related lists associated with a mappable
17310 struct MappableVarListInfo {
17311 // The list of expressions.
17312 ArrayRef<Expr *> VarList;
17313 // The list of processed expressions.
17314 SmallVector<Expr *, 16> ProcessedVarList;
17315 // The mappble components for each expression.
17316 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
17317 // The base declaration of the variable.
17318 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
17319 // The reference to the user-defined mapper associated with every expression.
17320 SmallVector<Expr *, 16> UDMapperList;
17322 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
17323 // We have a list of components and base declarations for each entry in the
17325 VarComponents.reserve(VarList.size());
17326 VarBaseDeclarations.reserve(VarList.size());
17331 // Check the validity of the provided variable list for the provided clause kind
17332 // \a CKind. In the check process the valid expressions, mappable expression
17333 // components, variables, and user-defined mappers are extracted and used to
17334 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
17335 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
17336 // and \a MapperId are expected to be valid if the clause kind is 'map'.
17337 static void checkMappableExpressionList(
17338 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
17339 MappableVarListInfo &MVLI, SourceLocation StartLoc,
17340 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
17341 ArrayRef<Expr *> UnresolvedMappers,
17342 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
17343 bool IsMapTypeImplicit = false) {
17344 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
17345 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
17346 "Unexpected clause kind with mappable expressions!");
17348 // If the identifier of user-defined mapper is not specified, it is "default".
17349 // We do not change the actual name in this clause to distinguish whether a
17350 // mapper is specified explicitly, i.e., it is not explicitly specified when
17351 // MapperId.getName() is empty.
17352 if (!MapperId.getName() || MapperId.getName().isEmpty()) {
17353 auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
17354 MapperId.setName(DeclNames.getIdentifier(
17355 &SemaRef.getASTContext().Idents.get("default")));
17358 // Iterators to find the current unresolved mapper expression.
17359 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
17360 bool UpdateUMIt = false;
17361 Expr *UnresolvedMapper = nullptr;
17363 // Keep track of the mappable components and base declarations in this clause.
17364 // Each entry in the list is going to have a list of components associated. We
17365 // record each set of the components so that we can build the clause later on.
17366 // In the end we should have the same amount of declarations and component
17369 for (Expr *RE : MVLI.VarList) {
17370 assert(RE && "Null expr in omp to/from/map clause");
17371 SourceLocation ELoc = RE->getExprLoc();
17373 // Find the current unresolved mapper expression.
17374 if (UpdateUMIt && UMIt != UMEnd) {
17378 "Expect the size of UnresolvedMappers to match with that of VarList");
17382 UnresolvedMapper = *UMIt;
17384 const Expr *VE = RE->IgnoreParenLValueCasts();
17386 if (VE->isValueDependent() || VE->isTypeDependent() ||
17387 VE->isInstantiationDependent() ||
17388 VE->containsUnexpandedParameterPack()) {
17389 // Try to find the associated user-defined mapper.
17390 ExprResult ER = buildUserDefinedMapperRef(
17391 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17392 VE->getType().getCanonicalType(), UnresolvedMapper);
17393 if (ER.isInvalid())
17395 MVLI.UDMapperList.push_back(ER.get());
17396 // We can only analyze this information once the missing information is
17398 MVLI.ProcessedVarList.push_back(RE);
17402 Expr *SimpleExpr = RE->IgnoreParenCasts();
17404 if (!RE->isLValue()) {
17405 if (SemaRef.getLangOpts().OpenMP < 50) {
17407 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
17408 << RE->getSourceRange();
17410 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
17411 << getOpenMPClauseName(CKind) << RE->getSourceRange();
17416 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
17417 ValueDecl *CurDeclaration = nullptr;
17419 // Obtain the array or member expression bases if required. Also, fill the
17420 // components array with all the components identified in the process.
17421 const Expr *BE = checkMapClauseExpressionBase(
17422 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
17426 assert(!CurComponents.empty() &&
17427 "Invalid mappable expression information.");
17429 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
17430 // Add store "this" pointer to class in DSAStackTy for future checking
17431 DSAS->addMappedClassesQualTypes(TE->getType());
17432 // Try to find the associated user-defined mapper.
17433 ExprResult ER = buildUserDefinedMapperRef(
17434 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17435 VE->getType().getCanonicalType(), UnresolvedMapper);
17436 if (ER.isInvalid())
17438 MVLI.UDMapperList.push_back(ER.get());
17439 // Skip restriction checking for variable or field declarations
17440 MVLI.ProcessedVarList.push_back(RE);
17441 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17442 MVLI.VarComponents.back().append(CurComponents.begin(),
17443 CurComponents.end());
17444 MVLI.VarBaseDeclarations.push_back(nullptr);
17448 // For the following checks, we rely on the base declaration which is
17449 // expected to be associated with the last component. The declaration is
17450 // expected to be a variable or a field (if 'this' is being mapped).
17451 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
17452 assert(CurDeclaration && "Null decl on map clause.");
17454 CurDeclaration->isCanonicalDecl() &&
17455 "Expecting components to have associated only canonical declarations.");
17457 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
17458 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
17460 assert((VD || FD) && "Only variables or fields are expected here!");
17463 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
17464 // threadprivate variables cannot appear in a map clause.
17465 // OpenMP 4.5 [2.10.5, target update Construct]
17466 // threadprivate variables cannot appear in a from clause.
17467 if (VD && DSAS->isThreadPrivate(VD)) {
17468 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17469 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
17470 << getOpenMPClauseName(CKind);
17471 reportOriginalDsa(SemaRef, DSAS, VD, DVar);
17475 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17476 // A list item cannot appear in both a map clause and a data-sharing
17477 // attribute clause on the same construct.
17479 // Check conflicts with other map clause expressions. We check the conflicts
17480 // with the current construct separately from the enclosing data
17481 // environment, because the restrictions are different. We only have to
17482 // check conflicts across regions for the map clauses.
17483 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17484 /*CurrentRegionOnly=*/true, CurComponents, CKind))
17486 if (CKind == OMPC_map &&
17487 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
17488 /*CurrentRegionOnly=*/false, CurComponents, CKind))
17491 // OpenMP 4.5 [2.10.5, target update Construct]
17492 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
17493 // If the type of a list item is a reference to a type T then the type will
17494 // be considered to be T for all purposes of this clause.
17495 auto I = llvm::find_if(
17497 [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
17498 return MC.getAssociatedDeclaration();
17500 assert(I != CurComponents.end() && "Null decl on map clause.");
17502 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
17503 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
17504 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
17506 Type = ASE->getType().getNonReferenceType();
17508 QualType BaseType =
17509 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17510 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17511 Type = ATy->getElementType();
17513 Type = BaseType->getPointeeType();
17514 Type = Type.getNonReferenceType();
17515 } else if (OAShE) {
17516 Type = OAShE->getBase()->getType()->getPointeeType();
17518 Type = VE->getType();
17521 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
17522 // A list item in a to or from clause must have a mappable type.
17523 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
17524 // A list item must have a mappable type.
17525 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
17529 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
17531 if (CKind == OMPC_map) {
17532 // target enter data
17533 // OpenMP [2.10.2, Restrictions, p. 99]
17534 // A map-type must be specified in all map clauses and must be either
17536 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
17537 if (DKind == OMPD_target_enter_data &&
17538 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
17539 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17540 << (IsMapTypeImplicit ? 1 : 0)
17541 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17542 << getOpenMPDirectiveName(DKind);
17546 // target exit_data
17547 // OpenMP [2.10.3, Restrictions, p. 102]
17548 // A map-type must be specified in all map clauses and must be either
17549 // from, release, or delete.
17550 if (DKind == OMPD_target_exit_data &&
17551 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
17552 MapType == OMPC_MAP_delete)) {
17553 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17554 << (IsMapTypeImplicit ? 1 : 0)
17555 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17556 << getOpenMPDirectiveName(DKind);
17560 // target, target data
17561 // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
17562 // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
17563 // A map-type in a map clause must be to, from, tofrom or alloc
17564 if ((DKind == OMPD_target_data ||
17565 isOpenMPTargetExecutionDirective(DKind)) &&
17566 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
17567 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
17568 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
17569 << (IsMapTypeImplicit ? 1 : 0)
17570 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
17571 << getOpenMPDirectiveName(DKind);
17575 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17576 // A list item cannot appear in both a map clause and a data-sharing
17577 // attribute clause on the same construct
17579 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17580 // A list item cannot appear in both a map clause and a data-sharing
17581 // attribute clause on the same construct unless the construct is a
17582 // combined construct.
17583 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
17584 isOpenMPTargetExecutionDirective(DKind)) ||
17585 DKind == OMPD_target)) {
17586 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
17587 if (isOpenMPPrivate(DVar.CKind)) {
17588 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17589 << getOpenMPClauseName(DVar.CKind)
17590 << getOpenMPClauseName(OMPC_map)
17591 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
17592 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
17598 // Try to find the associated user-defined mapper.
17599 ExprResult ER = buildUserDefinedMapperRef(
17600 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
17601 Type.getCanonicalType(), UnresolvedMapper);
17602 if (ER.isInvalid())
17604 MVLI.UDMapperList.push_back(ER.get());
17606 // Save the current expression.
17607 MVLI.ProcessedVarList.push_back(RE);
17609 // Store the components in the stack so that they can be used to check
17610 // against other clauses later on.
17611 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
17612 /*WhereFoundClauseKind=*/OMPC_map);
17614 // Save the components and declaration to create the clause. For purposes of
17615 // the clause creation, any component list that has has base 'this' uses
17616 // null as base declaration.
17617 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17618 MVLI.VarComponents.back().append(CurComponents.begin(),
17619 CurComponents.end());
17620 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
17625 OMPClause *Sema::ActOnOpenMPMapClause(
17626 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
17627 ArrayRef<SourceLocation> MapTypeModifiersLoc,
17628 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
17629 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
17630 SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
17631 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
17632 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown,
17633 OMPC_MAP_MODIFIER_unknown,
17634 OMPC_MAP_MODIFIER_unknown};
17635 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
17637 // Process map-type-modifiers, flag errors for duplicate modifiers.
17638 unsigned Count = 0;
17639 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
17640 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
17641 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
17642 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
17645 assert(Count < NumberOfOMPMapClauseModifiers &&
17646 "Modifiers exceed the allowed number of map type modifiers");
17647 Modifiers[Count] = MapTypeModifiers[I];
17648 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
17652 MappableVarListInfo MVLI(VarList);
17653 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
17654 MapperIdScopeSpec, MapperId, UnresolvedMappers,
17655 MapType, IsMapTypeImplicit);
17657 // We need to produce a map clause even if we don't have variables so that
17658 // other diagnostics related with non-existing map clauses are accurate.
17659 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
17660 MVLI.VarBaseDeclarations, MVLI.VarComponents,
17661 MVLI.UDMapperList, Modifiers, ModifiersLoc,
17662 MapperIdScopeSpec.getWithLocInContext(Context),
17663 MapperId, MapType, IsMapTypeImplicit, MapLoc);
17666 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
17667 TypeResult ParsedType) {
17668 assert(ParsedType.isUsable());
17670 QualType ReductionType = GetTypeFromParser(ParsedType.get());
17671 if (ReductionType.isNull())
17674 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
17675 // A type name in a declare reduction directive cannot be a function type, an
17676 // array type, a reference type, or a type qualified with const, volatile or
17678 if (ReductionType.hasQualifiers()) {
17679 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
17683 if (ReductionType->isFunctionType()) {
17684 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
17687 if (ReductionType->isReferenceType()) {
17688 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
17691 if (ReductionType->isArrayType()) {
17692 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
17695 return ReductionType;
17698 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
17699 Scope *S, DeclContext *DC, DeclarationName Name,
17700 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
17701 AccessSpecifier AS, Decl *PrevDeclInScope) {
17702 SmallVector<Decl *, 8> Decls;
17703 Decls.reserve(ReductionTypes.size());
17705 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
17706 forRedeclarationInCurContext());
17707 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
17708 // A reduction-identifier may not be re-declared in the current scope for the
17709 // same type or for a type that is compatible according to the base language
17711 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17712 OMPDeclareReductionDecl *PrevDRD = nullptr;
17713 bool InCompoundScope = true;
17714 if (S != nullptr) {
17715 // Find previous declaration with the same name not referenced in other
17717 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17719 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17720 LookupName(Lookup, S);
17721 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17722 /*AllowInlineNamespace=*/false);
17723 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
17724 LookupResult::Filter Filter = Lookup.makeFilter();
17725 while (Filter.hasNext()) {
17726 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
17727 if (InCompoundScope) {
17728 auto I = UsedAsPrevious.find(PrevDecl);
17729 if (I == UsedAsPrevious.end())
17730 UsedAsPrevious[PrevDecl] = false;
17731 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
17732 UsedAsPrevious[D] = true;
17734 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17735 PrevDecl->getLocation();
17738 if (InCompoundScope) {
17739 for (const auto &PrevData : UsedAsPrevious) {
17740 if (!PrevData.second) {
17741 PrevDRD = PrevData.first;
17746 } else if (PrevDeclInScope != nullptr) {
17747 auto *PrevDRDInScope = PrevDRD =
17748 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
17750 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
17751 PrevDRDInScope->getLocation();
17752 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
17753 } while (PrevDRDInScope != nullptr);
17755 for (const auto &TyData : ReductionTypes) {
17756 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
17757 bool Invalid = false;
17758 if (I != PreviousRedeclTypes.end()) {
17759 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
17761 Diag(I->second, diag::note_previous_definition);
17764 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
17765 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
17766 Name, TyData.first, PrevDRD);
17768 DRD->setAccess(AS);
17769 Decls.push_back(DRD);
17771 DRD->setInvalidDecl();
17776 return DeclGroupPtrTy::make(
17777 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
17780 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
17781 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17783 // Enter new function scope.
17784 PushFunctionScope();
17785 setFunctionHasBranchProtectedScope();
17786 getCurFunction()->setHasOMPDeclareReductionCombiner();
17789 PushDeclContext(S, DRD);
17793 PushExpressionEvaluationContext(
17794 ExpressionEvaluationContext::PotentiallyEvaluated);
17796 QualType ReductionType = DRD->getType();
17797 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
17798 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
17799 // uses semantics of argument handles by value, but it should be passed by
17800 // reference. C lang does not support references, so pass all parameters as
17802 // Create 'T omp_in;' variable.
17803 VarDecl *OmpInParm =
17804 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
17805 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
17806 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
17807 // uses semantics of argument handles by value, but it should be passed by
17808 // reference. C lang does not support references, so pass all parameters as
17810 // Create 'T omp_out;' variable.
17811 VarDecl *OmpOutParm =
17812 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
17813 if (S != nullptr) {
17814 PushOnScopeChains(OmpInParm, S);
17815 PushOnScopeChains(OmpOutParm, S);
17817 DRD->addDecl(OmpInParm);
17818 DRD->addDecl(OmpOutParm);
17821 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
17823 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
17824 DRD->setCombinerData(InE, OutE);
17827 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
17828 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17829 DiscardCleanupsInEvaluationContext();
17830 PopExpressionEvaluationContext();
17833 PopFunctionScopeInfo();
17835 if (Combiner != nullptr)
17836 DRD->setCombiner(Combiner);
17838 DRD->setInvalidDecl();
17841 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
17842 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17844 // Enter new function scope.
17845 PushFunctionScope();
17846 setFunctionHasBranchProtectedScope();
17849 PushDeclContext(S, DRD);
17853 PushExpressionEvaluationContext(
17854 ExpressionEvaluationContext::PotentiallyEvaluated);
17856 QualType ReductionType = DRD->getType();
17857 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
17858 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
17859 // uses semantics of argument handles by value, but it should be passed by
17860 // reference. C lang does not support references, so pass all parameters as
17862 // Create 'T omp_priv;' variable.
17863 VarDecl *OmpPrivParm =
17864 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
17865 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
17866 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
17867 // uses semantics of argument handles by value, but it should be passed by
17868 // reference. C lang does not support references, so pass all parameters as
17870 // Create 'T omp_orig;' variable.
17871 VarDecl *OmpOrigParm =
17872 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
17873 if (S != nullptr) {
17874 PushOnScopeChains(OmpPrivParm, S);
17875 PushOnScopeChains(OmpOrigParm, S);
17877 DRD->addDecl(OmpPrivParm);
17878 DRD->addDecl(OmpOrigParm);
17881 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
17883 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
17884 DRD->setInitializerData(OrigE, PrivE);
17885 return OmpPrivParm;
17888 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
17889 VarDecl *OmpPrivParm) {
17890 auto *DRD = cast<OMPDeclareReductionDecl>(D);
17891 DiscardCleanupsInEvaluationContext();
17892 PopExpressionEvaluationContext();
17895 PopFunctionScopeInfo();
17897 if (Initializer != nullptr) {
17898 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
17899 } else if (OmpPrivParm->hasInit()) {
17900 DRD->setInitializer(OmpPrivParm->getInit(),
17901 OmpPrivParm->isDirectInit()
17902 ? OMPDeclareReductionDecl::DirectInit
17903 : OMPDeclareReductionDecl::CopyInit);
17905 DRD->setInvalidDecl();
17909 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
17910 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
17911 for (Decl *D : DeclReductions.get()) {
17914 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
17915 /*AddToContext=*/false);
17917 D->setInvalidDecl();
17920 return DeclReductions;
17923 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
17924 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
17925 QualType T = TInfo->getType();
17926 if (D.isInvalidType())
17929 if (getLangOpts().CPlusPlus) {
17930 // Check that there are no default arguments (C++ only).
17931 CheckExtraCXXDefaultArguments(D);
17934 return CreateParsedType(T, TInfo);
17937 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
17938 TypeResult ParsedType) {
17939 assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
17941 QualType MapperType = GetTypeFromParser(ParsedType.get());
17942 assert(!MapperType.isNull() && "Expect valid mapper type");
17944 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17945 // The type must be of struct, union or class type in C and C++
17946 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
17947 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
17953 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart(
17954 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
17955 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
17956 Decl *PrevDeclInScope) {
17957 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
17958 forRedeclarationInCurContext());
17959 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
17960 // A mapper-identifier may not be redeclared in the current scope for the
17961 // same type or for a type that is compatible according to the base language
17963 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
17964 OMPDeclareMapperDecl *PrevDMD = nullptr;
17965 bool InCompoundScope = true;
17966 if (S != nullptr) {
17967 // Find previous declaration with the same name not referenced in other
17969 FunctionScopeInfo *ParentFn = getEnclosingFunction();
17971 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
17972 LookupName(Lookup, S);
17973 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
17974 /*AllowInlineNamespace=*/false);
17975 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
17976 LookupResult::Filter Filter = Lookup.makeFilter();
17977 while (Filter.hasNext()) {
17978 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
17979 if (InCompoundScope) {
17980 auto I = UsedAsPrevious.find(PrevDecl);
17981 if (I == UsedAsPrevious.end())
17982 UsedAsPrevious[PrevDecl] = false;
17983 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
17984 UsedAsPrevious[D] = true;
17986 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
17987 PrevDecl->getLocation();
17990 if (InCompoundScope) {
17991 for (const auto &PrevData : UsedAsPrevious) {
17992 if (!PrevData.second) {
17993 PrevDMD = PrevData.first;
17998 } else if (PrevDeclInScope) {
17999 auto *PrevDMDInScope = PrevDMD =
18000 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
18002 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
18003 PrevDMDInScope->getLocation();
18004 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
18005 } while (PrevDMDInScope != nullptr);
18007 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
18008 bool Invalid = false;
18009 if (I != PreviousRedeclTypes.end()) {
18010 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
18011 << MapperType << Name;
18012 Diag(I->second, diag::note_previous_definition);
18015 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
18016 MapperType, VN, PrevDMD);
18018 DMD->setAccess(AS);
18020 DMD->setInvalidDecl();
18022 // Enter new function scope.
18023 PushFunctionScope();
18024 setFunctionHasBranchProtectedScope();
18031 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD,
18033 QualType MapperType,
18034 SourceLocation StartLoc,
18035 DeclarationName VN) {
18036 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
18038 PushOnScopeChains(VD, S);
18041 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
18042 DMD->setMapperVarRef(MapperVarRefExpr);
18045 Sema::DeclGroupPtrTy
18046 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S,
18047 ArrayRef<OMPClause *> ClauseList) {
18049 PopFunctionScopeInfo();
18053 PushOnScopeChains(D, S, /*AddToContext=*/false);
18054 D->CreateClauses(Context, ClauseList);
18057 return DeclGroupPtrTy::make(DeclGroupRef(D));
18060 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
18061 SourceLocation StartLoc,
18062 SourceLocation LParenLoc,
18063 SourceLocation EndLoc) {
18064 Expr *ValExpr = NumTeams;
18065 Stmt *HelperValStmt = nullptr;
18067 // OpenMP [teams Constrcut, Restrictions]
18068 // The num_teams expression must evaluate to a positive integer value.
18069 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
18070 /*StrictlyPositive=*/true))
18073 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18074 OpenMPDirectiveKind CaptureRegion =
18075 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
18076 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18077 ValExpr = MakeFullExpr(ValExpr).get();
18078 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18079 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18080 HelperValStmt = buildPreInits(Context, Captures);
18083 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
18084 StartLoc, LParenLoc, EndLoc);
18087 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
18088 SourceLocation StartLoc,
18089 SourceLocation LParenLoc,
18090 SourceLocation EndLoc) {
18091 Expr *ValExpr = ThreadLimit;
18092 Stmt *HelperValStmt = nullptr;
18094 // OpenMP [teams Constrcut, Restrictions]
18095 // The thread_limit expression must evaluate to a positive integer value.
18096 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
18097 /*StrictlyPositive=*/true))
18100 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18101 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
18102 DKind, OMPC_thread_limit, LangOpts.OpenMP);
18103 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18104 ValExpr = MakeFullExpr(ValExpr).get();
18105 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18106 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18107 HelperValStmt = buildPreInits(Context, Captures);
18110 return new (Context) OMPThreadLimitClause(
18111 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18114 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
18115 SourceLocation StartLoc,
18116 SourceLocation LParenLoc,
18117 SourceLocation EndLoc) {
18118 Expr *ValExpr = Priority;
18119 Stmt *HelperValStmt = nullptr;
18120 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18122 // OpenMP [2.9.1, task Constrcut]
18123 // The priority-value is a non-negative numerical scalar expression.
18124 if (!isNonNegativeIntegerValue(
18125 ValExpr, *this, OMPC_priority,
18126 /*StrictlyPositive=*/false, /*BuildCapture=*/true,
18127 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18130 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
18131 StartLoc, LParenLoc, EndLoc);
18134 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
18135 SourceLocation StartLoc,
18136 SourceLocation LParenLoc,
18137 SourceLocation EndLoc) {
18138 Expr *ValExpr = Grainsize;
18139 Stmt *HelperValStmt = nullptr;
18140 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18142 // OpenMP [2.9.2, taskloop Constrcut]
18143 // The parameter of the grainsize clause must be a positive integer
18145 if (!isNonNegativeIntegerValue(
18146 ValExpr, *this, OMPC_grainsize,
18147 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18148 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18151 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
18152 StartLoc, LParenLoc, EndLoc);
18155 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
18156 SourceLocation StartLoc,
18157 SourceLocation LParenLoc,
18158 SourceLocation EndLoc) {
18159 Expr *ValExpr = NumTasks;
18160 Stmt *HelperValStmt = nullptr;
18161 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18163 // OpenMP [2.9.2, taskloop Constrcut]
18164 // The parameter of the num_tasks clause must be a positive integer
18166 if (!isNonNegativeIntegerValue(
18167 ValExpr, *this, OMPC_num_tasks,
18168 /*StrictlyPositive=*/true, /*BuildCapture=*/true,
18169 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
18172 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
18173 StartLoc, LParenLoc, EndLoc);
18176 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
18177 SourceLocation LParenLoc,
18178 SourceLocation EndLoc) {
18179 // OpenMP [2.13.2, critical construct, Description]
18180 // ... where hint-expression is an integer constant expression that evaluates
18181 // to a valid lock hint.
18182 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
18183 if (HintExpr.isInvalid())
18185 return new (Context)
18186 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
18189 /// Tries to find omp_event_handle_t type.
18190 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
18191 DSAStackTy *Stack) {
18192 QualType OMPEventHandleT = Stack->getOMPEventHandleT();
18193 if (!OMPEventHandleT.isNull())
18195 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
18196 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18197 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18198 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
18201 Stack->setOMPEventHandleT(PT.get());
18205 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
18206 SourceLocation LParenLoc,
18207 SourceLocation EndLoc) {
18208 if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
18209 !Evt->isInstantiationDependent() &&
18210 !Evt->containsUnexpandedParameterPack()) {
18211 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
18213 // OpenMP 5.0, 2.10.1 task Construct.
18214 // event-handle is a variable of the omp_event_handle_t type.
18215 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
18217 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18218 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18221 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
18223 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18224 << "omp_event_handle_t" << 0 << Evt->getSourceRange();
18227 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
18229 VD->getType().isConstant(Context)) {
18230 Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
18231 << "omp_event_handle_t" << 1 << VD->getType()
18232 << Evt->getSourceRange();
18235 // OpenMP 5.0, 2.10.1 task Construct
18236 // [detach clause]... The event-handle will be considered as if it was
18237 // specified on a firstprivate clause.
18238 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
18239 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18241 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
18242 << getOpenMPClauseName(DVar.CKind)
18243 << getOpenMPClauseName(OMPC_firstprivate);
18244 reportOriginalDsa(*this, DSAStack, VD, DVar);
18249 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
18252 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
18253 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
18254 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
18255 SourceLocation EndLoc) {
18256 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
18257 std::string Values;
18259 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
18261 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18262 << Values << getOpenMPClauseName(OMPC_dist_schedule);
18265 Expr *ValExpr = ChunkSize;
18266 Stmt *HelperValStmt = nullptr;
18268 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
18269 !ChunkSize->isInstantiationDependent() &&
18270 !ChunkSize->containsUnexpandedParameterPack()) {
18271 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
18273 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
18274 if (Val.isInvalid())
18277 ValExpr = Val.get();
18279 // OpenMP [2.7.1, Restrictions]
18280 // chunk_size must be a loop invariant integer expression with a positive
18282 llvm::APSInt Result;
18283 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
18284 if (Result.isSigned() && !Result.isStrictlyPositive()) {
18285 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
18286 << "dist_schedule" << ChunkSize->getSourceRange();
18289 } else if (getOpenMPCaptureRegionForClause(
18290 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
18291 LangOpts.OpenMP) != OMPD_unknown &&
18292 !CurContext->isDependentContext()) {
18293 ValExpr = MakeFullExpr(ValExpr).get();
18294 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18295 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18296 HelperValStmt = buildPreInits(Context, Captures);
18301 return new (Context)
18302 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
18303 Kind, ValExpr, HelperValStmt);
18306 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
18307 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
18308 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
18309 SourceLocation KindLoc, SourceLocation EndLoc) {
18310 if (getLangOpts().OpenMP < 50) {
18311 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
18312 Kind != OMPC_DEFAULTMAP_scalar) {
18314 SourceLocation Loc;
18316 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
18317 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18318 OMPC_DEFAULTMAP_MODIFIER_tofrom);
18321 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
18322 OMPC_DEFAULTMAP_scalar);
18326 Diag(Loc, diag::err_omp_unexpected_clause_value)
18327 << Value << getOpenMPClauseName(OMPC_defaultmap);
18331 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
18332 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
18333 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
18334 if (!isDefaultmapKind || !isDefaultmapModifier) {
18335 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
18336 "'firstprivate', 'none', 'default'";
18337 std::string KindValue = "'scalar', 'aggregate', 'pointer'";
18338 if (!isDefaultmapKind && isDefaultmapModifier) {
18339 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18340 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18341 } else if (isDefaultmapKind && !isDefaultmapModifier) {
18342 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18343 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18345 Diag(MLoc, diag::err_omp_unexpected_clause_value)
18346 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
18347 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
18348 << KindValue << getOpenMPClauseName(OMPC_defaultmap);
18353 // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
18354 // At most one defaultmap clause for each category can appear on the
18356 if (DSAStack->checkDefaultmapCategory(Kind)) {
18357 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
18361 if (Kind == OMPC_DEFAULTMAP_unknown) {
18362 // Variable category is not specified - mark all categories.
18363 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
18364 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
18365 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
18367 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
18370 return new (Context)
18371 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
18374 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
18375 DeclContext *CurLexicalContext = getCurLexicalContext();
18376 if (!CurLexicalContext->isFileContext() &&
18377 !CurLexicalContext->isExternCContext() &&
18378 !CurLexicalContext->isExternCXXContext() &&
18379 !isa<CXXRecordDecl>(CurLexicalContext) &&
18380 !isa<ClassTemplateDecl>(CurLexicalContext) &&
18381 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
18382 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
18383 Diag(Loc, diag::err_omp_region_not_file_context);
18386 ++DeclareTargetNestingLevel;
18390 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
18391 assert(DeclareTargetNestingLevel > 0 &&
18392 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
18393 --DeclareTargetNestingLevel;
18397 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec,
18398 const DeclarationNameInfo &Id,
18399 NamedDeclSetType &SameDirectiveDecls) {
18400 LookupResult Lookup(*this, Id, LookupOrdinaryName);
18401 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
18403 if (Lookup.isAmbiguous())
18405 Lookup.suppressDiagnostics();
18407 if (!Lookup.isSingleResult()) {
18408 VarOrFuncDeclFilterCCC CCC(*this);
18409 if (TypoCorrection Corrected =
18410 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
18411 CTK_ErrorRecovery)) {
18412 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
18414 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
18418 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
18422 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
18423 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
18424 !isa<FunctionTemplateDecl>(ND)) {
18425 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
18428 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
18429 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
18433 void Sema::ActOnOpenMPDeclareTargetName(
18434 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
18435 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
18436 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
18437 isa<FunctionTemplateDecl>(ND)) &&
18438 "Expected variable, function or function template.");
18440 // Diagnose marking after use as it may lead to incorrect diagnosis and
18442 if (LangOpts.OpenMP >= 50 &&
18443 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
18444 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
18446 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
18447 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
18448 if (DevTy.hasValue() && *DevTy != DT) {
18449 Diag(Loc, diag::err_omp_device_type_mismatch)
18450 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
18451 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
18454 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18455 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
18457 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
18458 SourceRange(Loc, Loc));
18460 if (ASTMutationListener *ML = Context.getASTMutationListener())
18461 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
18462 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
18463 } else if (*Res != MT) {
18464 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
18468 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
18469 Sema &SemaRef, Decl *D) {
18470 if (!D || !isa<VarDecl>(D))
18472 auto *VD = cast<VarDecl>(D);
18473 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18474 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18475 if (SemaRef.LangOpts.OpenMP >= 50 &&
18476 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
18477 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
18478 VD->hasGlobalStorage()) {
18479 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
18480 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
18481 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
18482 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
18483 // If a lambda declaration and definition appears between a
18484 // declare target directive and the matching end declare target
18485 // directive, all variables that are captured by the lambda
18486 // expression must also appear in a to clause.
18487 SemaRef.Diag(VD->getLocation(),
18488 diag::err_omp_lambda_capture_in_declare_target_not_to);
18489 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
18494 if (MapTy.hasValue())
18496 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
18497 SemaRef.Diag(SL, diag::note_used_here) << SR;
18500 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
18501 Sema &SemaRef, DSAStackTy *Stack,
18503 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
18504 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
18505 /*FullCheck=*/false);
18508 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
18509 SourceLocation IdLoc) {
18510 if (!D || D->isInvalidDecl())
18512 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
18513 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
18514 if (auto *VD = dyn_cast<VarDecl>(D)) {
18515 // Only global variables can be marked as declare target.
18516 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
18517 !VD->isStaticDataMember())
18519 // 2.10.6: threadprivate variable cannot appear in a declare target
18521 if (DSAStack->isThreadPrivate(VD)) {
18522 Diag(SL, diag::err_omp_threadprivate_in_target);
18523 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
18527 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
18528 D = FTD->getTemplatedDecl();
18529 if (auto *FD = dyn_cast<FunctionDecl>(D)) {
18530 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
18531 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
18532 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
18533 Diag(IdLoc, diag::err_omp_function_in_link_clause);
18534 Diag(FD->getLocation(), diag::note_defined_here) << FD;
18538 if (auto *VD = dyn_cast<ValueDecl>(D)) {
18539 // Problem if any with var declared with incomplete type will be reported
18540 // as normal, so no need to check it here.
18541 if ((E || !VD->getType()->isIncompleteType()) &&
18542 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
18544 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
18545 // Checking declaration inside declare target region.
18546 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
18547 isa<FunctionTemplateDecl>(D)) {
18548 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
18549 Context, OMPDeclareTargetDeclAttr::MT_To,
18550 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
18552 if (ASTMutationListener *ML = Context.getASTMutationListener())
18553 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
18560 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
18563 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
18564 CXXScopeSpec &MapperIdScopeSpec,
18565 DeclarationNameInfo &MapperId,
18566 const OMPVarListLocTy &Locs,
18567 ArrayRef<Expr *> UnresolvedMappers) {
18568 MappableVarListInfo MVLI(VarList);
18569 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
18570 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18571 if (MVLI.ProcessedVarList.empty())
18574 return OMPToClause::Create(
18575 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18576 MVLI.VarComponents, MVLI.UDMapperList,
18577 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18580 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
18581 CXXScopeSpec &MapperIdScopeSpec,
18582 DeclarationNameInfo &MapperId,
18583 const OMPVarListLocTy &Locs,
18584 ArrayRef<Expr *> UnresolvedMappers) {
18585 MappableVarListInfo MVLI(VarList);
18586 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
18587 MapperIdScopeSpec, MapperId, UnresolvedMappers);
18588 if (MVLI.ProcessedVarList.empty())
18591 return OMPFromClause::Create(
18592 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
18593 MVLI.VarComponents, MVLI.UDMapperList,
18594 MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
18597 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
18598 const OMPVarListLocTy &Locs) {
18599 MappableVarListInfo MVLI(VarList);
18600 SmallVector<Expr *, 8> PrivateCopies;
18601 SmallVector<Expr *, 8> Inits;
18603 for (Expr *RefExpr : VarList) {
18604 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
18605 SourceLocation ELoc;
18606 SourceRange ERange;
18607 Expr *SimpleRefExpr = RefExpr;
18608 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18610 // It will be analyzed later.
18611 MVLI.ProcessedVarList.push_back(RefExpr);
18612 PrivateCopies.push_back(nullptr);
18613 Inits.push_back(nullptr);
18615 ValueDecl *D = Res.first;
18619 QualType Type = D->getType();
18620 Type = Type.getNonReferenceType().getUnqualifiedType();
18622 auto *VD = dyn_cast<VarDecl>(D);
18624 // Item should be a pointer or reference to pointer.
18625 if (!Type->isPointerType()) {
18626 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
18627 << 0 << RefExpr->getSourceRange();
18631 // Build the private variable and the expression that refers to it.
18633 buildVarDecl(*this, ELoc, Type, D->getName(),
18634 D->hasAttrs() ? &D->getAttrs() : nullptr,
18635 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18636 if (VDPrivate->isInvalidDecl())
18639 CurContext->addDecl(VDPrivate);
18640 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18641 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18643 // Add temporary variable to initialize the private copy of the pointer.
18645 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
18646 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
18647 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
18648 AddInitializerToDecl(VDPrivate,
18649 DefaultLvalueConversion(VDInitRefExpr).get(),
18650 /*DirectInit=*/false);
18652 // If required, build a capture to implement the privatization initialized
18653 // with the current list item value.
18654 DeclRefExpr *Ref = nullptr;
18656 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18657 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18658 PrivateCopies.push_back(VDPrivateRefExpr);
18659 Inits.push_back(VDInitRefExpr);
18661 // We need to add a data sharing attribute for this variable to make sure it
18662 // is correctly captured. A variable that shows up in a use_device_ptr has
18663 // similar properties of a first private variable.
18664 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18666 // Create a mappable component for the list item. List items in this clause
18667 // only need a component.
18668 MVLI.VarBaseDeclarations.push_back(D);
18669 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18670 MVLI.VarComponents.back().push_back(
18671 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
18674 if (MVLI.ProcessedVarList.empty())
18677 return OMPUseDevicePtrClause::Create(
18678 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
18679 MVLI.VarBaseDeclarations, MVLI.VarComponents);
18682 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
18683 const OMPVarListLocTy &Locs) {
18684 MappableVarListInfo MVLI(VarList);
18686 for (Expr *RefExpr : VarList) {
18687 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
18688 SourceLocation ELoc;
18689 SourceRange ERange;
18690 Expr *SimpleRefExpr = RefExpr;
18691 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18692 /*AllowArraySection=*/true);
18694 // It will be analyzed later.
18695 MVLI.ProcessedVarList.push_back(RefExpr);
18697 ValueDecl *D = Res.first;
18700 auto *VD = dyn_cast<VarDecl>(D);
18702 // If required, build a capture to implement the privatization initialized
18703 // with the current list item value.
18704 DeclRefExpr *Ref = nullptr;
18706 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18707 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
18709 // We need to add a data sharing attribute for this variable to make sure it
18710 // is correctly captured. A variable that shows up in a use_device_addr has
18711 // similar properties of a first private variable.
18712 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18714 // Create a mappable component for the list item. List items in this clause
18715 // only need a component.
18716 MVLI.VarBaseDeclarations.push_back(D);
18717 MVLI.VarComponents.emplace_back();
18718 Expr *Component = SimpleRefExpr;
18719 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
18720 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
18721 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
18722 MVLI.VarComponents.back().push_back(
18723 OMPClauseMappableExprCommon::MappableComponent(Component, D));
18726 if (MVLI.ProcessedVarList.empty())
18729 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18730 MVLI.VarBaseDeclarations,
18731 MVLI.VarComponents);
18734 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
18735 const OMPVarListLocTy &Locs) {
18736 MappableVarListInfo MVLI(VarList);
18737 for (Expr *RefExpr : VarList) {
18738 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
18739 SourceLocation ELoc;
18740 SourceRange ERange;
18741 Expr *SimpleRefExpr = RefExpr;
18742 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18744 // It will be analyzed later.
18745 MVLI.ProcessedVarList.push_back(RefExpr);
18747 ValueDecl *D = Res.first;
18751 QualType Type = D->getType();
18752 // item should be a pointer or array or reference to pointer or array
18753 if (!Type.getNonReferenceType()->isPointerType() &&
18754 !Type.getNonReferenceType()->isArrayType()) {
18755 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
18756 << 0 << RefExpr->getSourceRange();
18760 // Check if the declaration in the clause does not show up in any data
18761 // sharing attribute.
18762 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18763 if (isOpenMPPrivate(DVar.CKind)) {
18764 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18765 << getOpenMPClauseName(DVar.CKind)
18766 << getOpenMPClauseName(OMPC_is_device_ptr)
18767 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18768 reportOriginalDsa(*this, DSAStack, D, DVar);
18772 const Expr *ConflictExpr;
18773 if (DSAStack->checkMappableExprComponentListsForDecl(
18774 D, /*CurrentRegionOnly=*/true,
18776 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
18777 OpenMPClauseKind) -> bool {
18778 ConflictExpr = R.front().getAssociatedExpression();
18781 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
18782 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
18783 << ConflictExpr->getSourceRange();
18787 // Store the components in the stack so that they can be used to check
18788 // against other clauses later on.
18789 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
18790 DSAStack->addMappableExpressionComponents(
18791 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
18793 // Record the expression we've just processed.
18794 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
18796 // Create a mappable component for the list item. List items in this clause
18797 // only need a component. We use a null declaration to signal fields in
18799 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
18800 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
18801 "Unexpected device pointer expression!");
18802 MVLI.VarBaseDeclarations.push_back(
18803 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
18804 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
18805 MVLI.VarComponents.back().push_back(MC);
18808 if (MVLI.ProcessedVarList.empty())
18811 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
18812 MVLI.VarBaseDeclarations,
18813 MVLI.VarComponents);
18816 OMPClause *Sema::ActOnOpenMPAllocateClause(
18817 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18818 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
18820 // OpenMP [2.11.4 allocate Clause, Description]
18821 // allocator is an expression of omp_allocator_handle_t type.
18822 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
18825 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
18826 if (AllocatorRes.isInvalid())
18828 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
18829 DSAStack->getOMPAllocatorHandleT(),
18830 Sema::AA_Initializing,
18831 /*AllowExplicit=*/true);
18832 if (AllocatorRes.isInvalid())
18834 Allocator = AllocatorRes.get();
18836 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
18837 // allocate clauses that appear on a target construct or on constructs in a
18838 // target region must specify an allocator expression unless a requires
18839 // directive with the dynamic_allocators clause is present in the same
18840 // compilation unit.
18841 if (LangOpts.OpenMPIsDevice &&
18842 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
18843 targetDiag(StartLoc, diag::err_expected_allocator_expression);
18845 // Analyze and build list of variables.
18846 SmallVector<Expr *, 8> Vars;
18847 for (Expr *RefExpr : VarList) {
18848 assert(RefExpr && "NULL expr in OpenMP private clause.");
18849 SourceLocation ELoc;
18850 SourceRange ERange;
18851 Expr *SimpleRefExpr = RefExpr;
18852 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18854 // It will be analyzed later.
18855 Vars.push_back(RefExpr);
18857 ValueDecl *D = Res.first;
18861 auto *VD = dyn_cast<VarDecl>(D);
18862 DeclRefExpr *Ref = nullptr;
18863 if (!VD && !CurContext->isDependentContext())
18864 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18865 Vars.push_back((VD || CurContext->isDependentContext())
18866 ? RefExpr->IgnoreParens()
18874 DSAStack->addInnerAllocatorExpr(Allocator);
18875 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
18876 ColonLoc, EndLoc, Vars);
18879 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
18880 SourceLocation StartLoc,
18881 SourceLocation LParenLoc,
18882 SourceLocation EndLoc) {
18883 SmallVector<Expr *, 8> Vars;
18884 for (Expr *RefExpr : VarList) {
18885 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18886 SourceLocation ELoc;
18887 SourceRange ERange;
18888 Expr *SimpleRefExpr = RefExpr;
18889 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18891 // It will be analyzed later.
18892 Vars.push_back(RefExpr);
18893 ValueDecl *D = Res.first;
18897 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
18898 // A list-item cannot appear in more than one nontemporal clause.
18899 if (const Expr *PrevRef =
18900 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
18901 Diag(ELoc, diag::err_omp_used_in_clause_twice)
18902 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
18903 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
18904 << getOpenMPClauseName(OMPC_nontemporal);
18908 Vars.push_back(RefExpr);
18914 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18918 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
18919 SourceLocation StartLoc,
18920 SourceLocation LParenLoc,
18921 SourceLocation EndLoc) {
18922 SmallVector<Expr *, 8> Vars;
18923 for (Expr *RefExpr : VarList) {
18924 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18925 SourceLocation ELoc;
18926 SourceRange ERange;
18927 Expr *SimpleRefExpr = RefExpr;
18928 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18929 /*AllowArraySection=*/true);
18931 // It will be analyzed later.
18932 Vars.push_back(RefExpr);
18933 ValueDecl *D = Res.first;
18937 const DSAStackTy::DSAVarData DVar =
18938 DSAStack->getTopDSA(D, /*FromParent=*/true);
18939 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
18940 // A list item that appears in the inclusive or exclusive clause must appear
18941 // in a reduction clause with the inscan modifier on the enclosing
18942 // worksharing-loop, worksharing-loop SIMD, or simd construct.
18943 if (DVar.CKind != OMPC_reduction ||
18944 DVar.Modifier != OMPC_REDUCTION_inscan)
18945 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
18946 << RefExpr->getSourceRange();
18948 if (DSAStack->getParentDirective() != OMPD_unknown)
18949 DSAStack->markDeclAsUsedInScanDirective(D);
18950 Vars.push_back(RefExpr);
18956 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18959 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
18960 SourceLocation StartLoc,
18961 SourceLocation LParenLoc,
18962 SourceLocation EndLoc) {
18963 SmallVector<Expr *, 8> Vars;
18964 for (Expr *RefExpr : VarList) {
18965 assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
18966 SourceLocation ELoc;
18967 SourceRange ERange;
18968 Expr *SimpleRefExpr = RefExpr;
18969 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
18970 /*AllowArraySection=*/true);
18972 // It will be analyzed later.
18973 Vars.push_back(RefExpr);
18974 ValueDecl *D = Res.first;
18978 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
18979 DSAStackTy::DSAVarData DVar;
18980 if (ParentDirective != OMPD_unknown)
18981 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
18982 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
18983 // A list item that appears in the inclusive or exclusive clause must appear
18984 // in a reduction clause with the inscan modifier on the enclosing
18985 // worksharing-loop, worksharing-loop SIMD, or simd construct.
18986 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
18987 DVar.Modifier != OMPC_REDUCTION_inscan) {
18988 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
18989 << RefExpr->getSourceRange();
18991 DSAStack->markDeclAsUsedInScanDirective(D);
18993 Vars.push_back(RefExpr);
18999 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
19002 /// Tries to find omp_alloctrait_t type.
19003 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
19004 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
19005 if (!OMPAlloctraitT.isNull())
19007 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
19008 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
19009 if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19010 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
19013 Stack->setOMPAlloctraitT(PT.get());
19017 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
19018 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
19019 ArrayRef<UsesAllocatorsData> Data) {
19020 // OpenMP [2.12.5, target Construct]
19021 // allocator is an identifier of omp_allocator_handle_t type.
19022 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
19024 // OpenMP [2.12.5, target Construct]
19025 // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
19028 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
19029 !findOMPAlloctraitT(*this, StartLoc, DSAStack))
19031 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
19032 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
19033 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
19034 StringRef Allocator =
19035 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
19036 DeclarationName AllocatorName = &Context.Idents.get(Allocator);
19037 PredefinedAllocators.insert(LookupSingleName(
19038 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
19041 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
19042 for (const UsesAllocatorsData &D : Data) {
19043 Expr *AllocatorExpr = nullptr;
19044 // Check allocator expression.
19045 if (D.Allocator->isTypeDependent()) {
19046 AllocatorExpr = D.Allocator;
19048 // Traits were specified - need to assign new allocator to the specified
19049 // allocator, so it must be an lvalue.
19050 AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
19051 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
19052 bool IsPredefinedAllocator = false;
19054 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
19056 !(Context.hasSameUnqualifiedType(
19057 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
19058 Context.typesAreCompatible(AllocatorExpr->getType(),
19059 DSAStack->getOMPAllocatorHandleT(),
19060 /*CompareUnqualified=*/true)) ||
19061 (!IsPredefinedAllocator &&
19062 (AllocatorExpr->getType().isConstant(Context) ||
19063 !AllocatorExpr->isLValue()))) {
19064 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
19065 << "omp_allocator_handle_t" << (DRE ? 1 : 0)
19066 << AllocatorExpr->getType() << D.Allocator->getSourceRange();
19069 // OpenMP [2.12.5, target Construct]
19070 // Predefined allocators appearing in a uses_allocators clause cannot have
19071 // traits specified.
19072 if (IsPredefinedAllocator && D.AllocatorTraits) {
19073 Diag(D.AllocatorTraits->getExprLoc(),
19074 diag::err_omp_predefined_allocator_with_traits)
19075 << D.AllocatorTraits->getSourceRange();
19076 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
19077 << cast<NamedDecl>(DRE->getDecl())->getName()
19078 << D.Allocator->getSourceRange();
19081 // OpenMP [2.12.5, target Construct]
19082 // Non-predefined allocators appearing in a uses_allocators clause must
19083 // have traits specified.
19084 if (!IsPredefinedAllocator && !D.AllocatorTraits) {
19085 Diag(D.Allocator->getExprLoc(),
19086 diag::err_omp_nonpredefined_allocator_without_traits);
19089 // No allocator traits - just convert it to rvalue.
19090 if (!D.AllocatorTraits)
19091 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
19092 DSAStack->addUsesAllocatorsDecl(
19094 IsPredefinedAllocator
19095 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
19096 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
19098 Expr *AllocatorTraitsExpr = nullptr;
19099 if (D.AllocatorTraits) {
19100 if (D.AllocatorTraits->isTypeDependent()) {
19101 AllocatorTraitsExpr = D.AllocatorTraits;
19103 // OpenMP [2.12.5, target Construct]
19104 // Arrays that contain allocator traits that appear in a uses_allocators
19105 // clause must be constant arrays, have constant values and be defined
19106 // in the same scope as the construct in which the clause appears.
19107 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
19108 // Check that traits expr is a constant array.
19110 if (const ArrayType *Ty =
19111 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
19112 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
19113 TraitTy = ConstArrayTy->getElementType();
19114 if (TraitTy.isNull() ||
19115 !(Context.hasSameUnqualifiedType(TraitTy,
19116 DSAStack->getOMPAlloctraitT()) ||
19117 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
19118 /*CompareUnqualified=*/true))) {
19119 Diag(D.AllocatorTraits->getExprLoc(),
19120 diag::err_omp_expected_array_alloctraits)
19121 << AllocatorTraitsExpr->getType();
19124 // Do not map by default allocator traits if it is a standalone
19126 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
19127 DSAStack->addUsesAllocatorsDecl(
19129 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
19132 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
19133 NewD.Allocator = AllocatorExpr;
19134 NewD.AllocatorTraits = AllocatorTraitsExpr;
19135 NewD.LParenLoc = D.LParenLoc;
19136 NewD.RParenLoc = D.RParenLoc;
19138 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19142 OMPClause *Sema::ActOnOpenMPAffinityClause(
19143 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
19144 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
19145 SmallVector<Expr *, 8> Vars;
19146 for (Expr *RefExpr : Locators) {
19147 assert(RefExpr && "NULL expr in OpenMP shared clause.");
19148 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
19149 // It will be analyzed later.
19150 Vars.push_back(RefExpr);
19154 SourceLocation ELoc = RefExpr->getExprLoc();
19155 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
19157 if (!SimpleExpr->isLValue()) {
19158 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19159 << 1 << 0 << RefExpr->getSourceRange();
19165 Sema::TentativeAnalysisScope Trap(*this);
19166 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
19168 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19169 !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19170 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19171 << 1 << 0 << RefExpr->getSourceRange();
19174 Vars.push_back(SimpleExpr);
19177 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19178 EndLoc, Modifier, Vars);