1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// \brief This file implements semantic analysis for OpenMP directives and
13 //===----------------------------------------------------------------------===//
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/ASTMutationListener.h"
18 #include "clang/AST/CXXInheritance.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/Basic/OpenMPKinds.h"
26 #include "clang/Sema/Initialization.h"
27 #include "clang/Sema/Lookup.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
30 #include "clang/Sema/SemaInternal.h"
31 #include "llvm/ADT/PointerEmbeddedInt.h"
32 using namespace clang;
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
38 static Expr *CheckMapClauseExpressionBase(
39 Sema &SemaRef, Expr *E,
40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
41 OpenMPClauseKind CKind, bool NoDiagnose);
44 /// \brief Default data sharing attributes, which can be applied to directive.
45 enum DefaultDataSharingAttributes {
46 DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
47 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
48 DSA_shared = 1 << 1, /// \brief Default data sharing attribute 'shared'.
51 /// Attributes of the defaultmap clause.
52 enum DefaultMapAttributes {
53 DMA_unspecified, /// Default mapping is not specified.
54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
57 /// \brief Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy final {
61 struct DSAVarData final {
62 OpenMPDirectiveKind DKind = OMPD_unknown;
63 OpenMPClauseKind CKind = OMPC_unknown;
64 Expr *RefExpr = nullptr;
65 DeclRefExpr *PrivateCopy = nullptr;
66 SourceLocation ImplicitDSALoc;
67 DSAVarData() = default;
68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
69 DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
70 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
71 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73 typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>
77 struct DSAInfo final {
78 OpenMPClauseKind Attributes = OMPC_unknown;
79 /// Pointer to a reference expression and a flag which shows that the
80 /// variable is marked as lastprivate(true) or not (false).
81 llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
82 DeclRefExpr *PrivateCopy = nullptr;
84 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
85 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
86 typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
87 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
88 /// Struct that associates a component with the clause kind where they are
90 struct MappedExprComponentTy {
91 OMPClauseMappableExprCommon::MappableExprComponentLists Components;
92 OpenMPClauseKind Kind = OMPC_unknown;
94 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
95 MappedExprComponentsTy;
96 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
98 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
100 struct ReductionData {
101 typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType;
102 SourceRange ReductionRange;
103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104 ReductionData() = default;
105 void set(BinaryOperatorKind BO, SourceRange RR) {
109 void set(const Expr *RefExpr, SourceRange RR) {
111 ReductionOp = RefExpr;
114 typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy;
116 struct SharingMapTy final {
117 DeclSAMapTy SharingMap;
118 DeclReductionMapTy ReductionMap;
119 AlignedMapTy AlignedMap;
120 MappedExprComponentsTy MappedExprComponents;
121 LoopControlVariablesMapTy LCVMap;
122 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
123 SourceLocation DefaultAttrLoc;
124 DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
125 SourceLocation DefaultMapAttrLoc;
126 OpenMPDirectiveKind Directive = OMPD_unknown;
127 DeclarationNameInfo DirectiveName;
128 Scope *CurScope = nullptr;
129 SourceLocation ConstructLoc;
130 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
131 /// get the data (loop counters etc.) about enclosing loop-based construct.
132 /// This data is required during codegen.
133 DoacrossDependMapTy DoacrossDepends;
134 /// \brief first argument (Expr *) contains optional argument of the
135 /// 'ordered' clause, the second one is true if the regions has 'ordered'
136 /// clause, false otherwise.
137 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
138 bool NowaitRegion = false;
139 bool CancelRegion = false;
140 unsigned AssociatedLoops = 1;
141 SourceLocation InnerTeamsRegionLoc;
142 /// Reference to the taskgroup task_reduction reference expression.
143 Expr *TaskgroupReductionRef = nullptr;
144 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
145 Scope *CurScope, SourceLocation Loc)
146 : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
148 SharingMapTy() = default;
151 typedef SmallVector<SharingMapTy, 4> StackTy;
153 /// \brief Stack of used declaration and their data-sharing attributes.
154 DeclSAMapTy Threadprivates;
155 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
156 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
157 /// \brief true, if check for DSA must be from parent directive, false, if
158 /// from current directive.
159 OpenMPClauseKind ClauseKindMode = OMPC_unknown;
161 bool ForceCapturing = false;
162 CriticalsWithHintsTy Criticals;
164 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
166 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D);
168 /// \brief Checks if the variable is a local for OpenMP region.
169 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
171 bool isStackEmpty() const {
172 return Stack.empty() ||
173 Stack.back().second != CurrentNonCapturingFunctionScope ||
174 Stack.back().first.empty();
178 explicit DSAStackTy(Sema &S) : SemaRef(S) {}
180 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
181 OpenMPClauseKind getClauseParsingMode() const {
182 assert(isClauseParsingMode() && "Must be in clause parsing mode.");
183 return ClauseKindMode;
185 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
187 bool isForceVarCapturing() const { return ForceCapturing; }
188 void setForceVarCapturing(bool V) { ForceCapturing = V; }
190 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
191 Scope *CurScope, SourceLocation Loc) {
193 Stack.back().second != CurrentNonCapturingFunctionScope)
194 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
195 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
196 Stack.back().first.back().DefaultAttrLoc = Loc;
200 assert(!Stack.back().first.empty() &&
201 "Data-sharing attributes stack is empty!");
202 Stack.back().first.pop_back();
205 /// Start new OpenMP region stack in new non-capturing function.
206 void pushFunction() {
207 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
208 assert(!isa<CapturingScopeInfo>(CurFnScope));
209 CurrentNonCapturingFunctionScope = CurFnScope;
211 /// Pop region stack for non-capturing function.
212 void popFunction(const FunctionScopeInfo *OldFSI) {
213 if (!Stack.empty() && Stack.back().second == OldFSI) {
214 assert(Stack.back().first.empty());
217 CurrentNonCapturingFunctionScope = nullptr;
218 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
219 if (!isa<CapturingScopeInfo>(FSI)) {
220 CurrentNonCapturingFunctionScope = FSI;
226 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
227 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
229 const std::pair<OMPCriticalDirective *, llvm::APSInt>
230 getCriticalWithHint(const DeclarationNameInfo &Name) const {
231 auto I = Criticals.find(Name.getAsString());
232 if (I != Criticals.end())
234 return std::make_pair(nullptr, llvm::APSInt());
236 /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
237 /// add it and return NULL; otherwise return previous occurrence's expression
239 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE);
241 /// \brief Register specified variable as loop control variable.
242 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture);
243 /// \brief Check if the specified variable is a loop control variable for
245 /// \return The index of the loop control variable in the list of associated
246 /// for-loops (from outer to inner).
247 LCDeclInfo isLoopControlVariable(ValueDecl *D);
248 /// \brief Check if the specified variable is a loop control variable for
250 /// \return The index of the loop control variable in the list of associated
251 /// for-loops (from outer to inner).
252 LCDeclInfo isParentLoopControlVariable(ValueDecl *D);
253 /// \brief Get the loop control variable for the I-th loop (or nullptr) in
254 /// parent directive.
255 ValueDecl *getParentLoopControlVariable(unsigned I);
257 /// \brief Adds explicit data sharing attribute to the specified declaration.
258 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
259 DeclRefExpr *PrivateCopy = nullptr);
261 /// Adds additional information for the reduction items with the reduction id
262 /// represented as an operator.
263 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
264 BinaryOperatorKind BOK);
265 /// Adds additional information for the reduction items with the reduction id
266 /// represented as reduction identifier.
267 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
268 const Expr *ReductionRef);
269 /// Returns the location and reduction operation from the innermost parent
270 /// region for the given \p D.
271 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
272 BinaryOperatorKind &BOK,
273 Expr *&TaskgroupDescriptor);
274 /// Returns the location and reduction operation from the innermost parent
275 /// region for the given \p D.
276 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
277 const Expr *&ReductionRef,
278 Expr *&TaskgroupDescriptor);
279 /// Return reduction reference expression for the current taskgroup.
280 Expr *getTaskgroupReductionRef() const {
281 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
282 "taskgroup reference expression requested for non taskgroup "
284 return Stack.back().first.back().TaskgroupReductionRef;
286 /// Checks if the given \p VD declaration is actually a taskgroup reduction
287 /// descriptor variable at the \p Level of OpenMP regions.
288 bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const {
289 return Stack.back().first[Level].TaskgroupReductionRef &&
290 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
294 /// \brief Returns data sharing attributes from top of the stack for the
295 /// specified declaration.
296 DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
297 /// \brief Returns data-sharing attributes for the specified declaration.
298 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent);
299 /// \brief Checks if the specified variables has data-sharing attributes which
300 /// match specified \a CPred predicate in any directive which matches \a DPred
302 DSAVarData hasDSA(ValueDecl *D,
303 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
304 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
306 /// \brief Checks if the specified variables has data-sharing attributes which
307 /// match specified \a CPred predicate in any innermost directive which
308 /// matches \a DPred predicate.
310 hasInnermostDSA(ValueDecl *D,
311 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
312 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
314 /// \brief Checks if the specified variables has explicit data-sharing
315 /// attributes which match specified \a CPred predicate at the specified
317 bool hasExplicitDSA(ValueDecl *D,
318 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
319 unsigned Level, bool NotLastprivate = false);
321 /// \brief Returns true if the directive at level \Level matches in the
322 /// specified \a DPred predicate.
323 bool hasExplicitDirective(
324 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
327 /// \brief Finds a directive which matches specified \a DPred predicate.
328 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind,
329 const DeclarationNameInfo &,
330 SourceLocation)> &DPred,
333 /// \brief Returns currently analyzed directive.
334 OpenMPDirectiveKind getCurrentDirective() const {
335 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
337 /// \brief Returns directive kind at specified level.
338 OpenMPDirectiveKind getDirective(unsigned Level) const {
339 assert(!isStackEmpty() && "No directive at specified level.");
340 return Stack.back().first[Level].Directive;
342 /// \brief Returns parent directive.
343 OpenMPDirectiveKind getParentDirective() const {
344 if (isStackEmpty() || Stack.back().first.size() == 1)
346 return std::next(Stack.back().first.rbegin())->Directive;
349 /// \brief Set default data sharing attribute to none.
350 void setDefaultDSANone(SourceLocation Loc) {
351 assert(!isStackEmpty());
352 Stack.back().first.back().DefaultAttr = DSA_none;
353 Stack.back().first.back().DefaultAttrLoc = Loc;
355 /// \brief Set default data sharing attribute to shared.
356 void setDefaultDSAShared(SourceLocation Loc) {
357 assert(!isStackEmpty());
358 Stack.back().first.back().DefaultAttr = DSA_shared;
359 Stack.back().first.back().DefaultAttrLoc = Loc;
361 /// Set default data mapping attribute to 'tofrom:scalar'.
362 void setDefaultDMAToFromScalar(SourceLocation Loc) {
363 assert(!isStackEmpty());
364 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
365 Stack.back().first.back().DefaultMapAttrLoc = Loc;
368 DefaultDataSharingAttributes getDefaultDSA() const {
369 return isStackEmpty() ? DSA_unspecified
370 : Stack.back().first.back().DefaultAttr;
372 SourceLocation getDefaultDSALocation() const {
373 return isStackEmpty() ? SourceLocation()
374 : Stack.back().first.back().DefaultAttrLoc;
376 DefaultMapAttributes getDefaultDMA() const {
377 return isStackEmpty() ? DMA_unspecified
378 : Stack.back().first.back().DefaultMapAttr;
380 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
381 return Stack.back().first[Level].DefaultMapAttr;
383 SourceLocation getDefaultDMALocation() const {
384 return isStackEmpty() ? SourceLocation()
385 : Stack.back().first.back().DefaultMapAttrLoc;
388 /// \brief Checks if the specified variable is a threadprivate.
389 bool isThreadPrivate(VarDecl *D) {
390 DSAVarData DVar = getTopDSA(D, false);
391 return isOpenMPThreadPrivate(DVar.CKind);
394 /// \brief Marks current region as ordered (it has an 'ordered' clause).
395 void setOrderedRegion(bool IsOrdered, Expr *Param) {
396 assert(!isStackEmpty());
397 Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
398 Stack.back().first.back().OrderedRegion.setPointer(Param);
400 /// \brief Returns true, if parent region is ordered (has associated
401 /// 'ordered' clause), false - otherwise.
402 bool isParentOrderedRegion() const {
403 if (isStackEmpty() || Stack.back().first.size() == 1)
405 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
407 /// \brief Returns optional parameter for the ordered region.
408 Expr *getParentOrderedRegionParam() const {
409 if (isStackEmpty() || Stack.back().first.size() == 1)
411 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
413 /// \brief Marks current region as nowait (it has a 'nowait' clause).
414 void setNowaitRegion(bool IsNowait = true) {
415 assert(!isStackEmpty());
416 Stack.back().first.back().NowaitRegion = IsNowait;
418 /// \brief Returns true, if parent region is nowait (has associated
419 /// 'nowait' clause), false - otherwise.
420 bool isParentNowaitRegion() const {
421 if (isStackEmpty() || Stack.back().first.size() == 1)
423 return std::next(Stack.back().first.rbegin())->NowaitRegion;
425 /// \brief Marks parent region as cancel region.
426 void setParentCancelRegion(bool Cancel = true) {
427 if (!isStackEmpty() && Stack.back().first.size() > 1) {
428 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
429 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
432 /// \brief Return true if current region has inner cancel construct.
433 bool isCancelRegion() const {
434 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
437 /// \brief Set collapse value for the region.
438 void setAssociatedLoops(unsigned Val) {
439 assert(!isStackEmpty());
440 Stack.back().first.back().AssociatedLoops = Val;
442 /// \brief Return collapse value for region.
443 unsigned getAssociatedLoops() const {
444 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
447 /// \brief Marks current target region as one with closely nested teams
449 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
450 if (!isStackEmpty() && Stack.back().first.size() > 1) {
451 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
455 /// \brief Returns true, if current region has closely nested teams region.
456 bool hasInnerTeamsRegion() const {
457 return getInnerTeamsRegionLoc().isValid();
459 /// \brief Returns location of the nested teams region (if any).
460 SourceLocation getInnerTeamsRegionLoc() const {
461 return isStackEmpty() ? SourceLocation()
462 : Stack.back().first.back().InnerTeamsRegionLoc;
465 Scope *getCurScope() const {
466 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
468 Scope *getCurScope() {
469 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
471 SourceLocation getConstructLoc() {
472 return isStackEmpty() ? SourceLocation()
473 : Stack.back().first.back().ConstructLoc;
476 /// Do the check specified in \a Check to all component lists and return true
477 /// if any issue is found.
478 bool checkMappableExprComponentListsForDecl(
479 ValueDecl *VD, bool CurrentRegionOnly,
480 const llvm::function_ref<
481 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
482 OpenMPClauseKind)> &Check) {
485 auto SI = Stack.back().first.rbegin();
486 auto SE = Stack.back().first.rend();
491 if (CurrentRegionOnly) {
497 for (; SI != SE; ++SI) {
498 auto MI = SI->MappedExprComponents.find(VD);
499 if (MI != SI->MappedExprComponents.end())
500 for (auto &L : MI->second.Components)
501 if (Check(L, MI->second.Kind))
507 /// Do the check specified in \a Check to all component lists at a given level
508 /// and return true if any issue is found.
509 bool checkMappableExprComponentListsForDeclAtLevel(
510 ValueDecl *VD, unsigned Level,
511 const llvm::function_ref<
512 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
513 OpenMPClauseKind)> &Check) {
517 auto StartI = Stack.back().first.begin();
518 auto EndI = Stack.back().first.end();
519 if (std::distance(StartI, EndI) <= (int)Level)
521 std::advance(StartI, Level);
523 auto MI = StartI->MappedExprComponents.find(VD);
524 if (MI != StartI->MappedExprComponents.end())
525 for (auto &L : MI->second.Components)
526 if (Check(L, MI->second.Kind))
531 /// Create a new mappable expression component list associated with a given
532 /// declaration and initialize it with the provided list of components.
533 void addMappableExpressionComponents(
535 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
536 OpenMPClauseKind WhereFoundClauseKind) {
537 assert(!isStackEmpty() &&
538 "Not expecting to retrieve components from a empty stack!");
539 auto &MEC = Stack.back().first.back().MappedExprComponents[VD];
540 // Create new entry and append the new components there.
541 MEC.Components.resize(MEC.Components.size() + 1);
542 MEC.Components.back().append(Components.begin(), Components.end());
543 MEC.Kind = WhereFoundClauseKind;
546 unsigned getNestingLevel() const {
547 assert(!isStackEmpty());
548 return Stack.back().first.size() - 1;
550 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
551 assert(!isStackEmpty() && Stack.back().first.size() > 1);
552 auto &StackElem = *std::next(Stack.back().first.rbegin());
553 assert(isOpenMPWorksharingDirective(StackElem.Directive));
554 StackElem.DoacrossDepends.insert({C, OpsOffs});
556 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
557 getDoacrossDependClauses() const {
558 assert(!isStackEmpty());
559 auto &StackElem = Stack.back().first.back();
560 if (isOpenMPWorksharingDirective(StackElem.Directive)) {
561 auto &Ref = StackElem.DoacrossDepends;
562 return llvm::make_range(Ref.begin(), Ref.end());
564 return llvm::make_range(StackElem.DoacrossDepends.end(),
565 StackElem.DoacrossDepends.end());
568 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
569 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
570 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
574 static Expr *getExprAsWritten(Expr *E) {
575 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
576 E = ExprTemp->getSubExpr();
578 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
579 E = MTE->GetTemporaryExpr();
581 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
582 E = Binder->getSubExpr();
584 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
585 E = ICE->getSubExprAsWritten();
586 return E->IgnoreParens();
589 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
590 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
591 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
592 D = ME->getMemberDecl();
593 auto *VD = dyn_cast<VarDecl>(D);
594 auto *FD = dyn_cast<FieldDecl>(D);
596 VD = VD->getCanonicalDecl();
600 FD = FD->getCanonicalDecl();
606 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
608 D = getCanonicalDecl(D);
609 auto *VD = dyn_cast<VarDecl>(D);
610 auto *FD = dyn_cast<FieldDecl>(D);
612 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
613 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
614 // in a region but not in construct]
615 // File-scope or namespace-scope variables referenced in called routines
616 // in the region are shared unless they appear in a threadprivate
618 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
619 DVar.CKind = OMPC_shared;
621 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
622 // in a region but not in construct]
623 // Variables with static storage duration that are declared in called
624 // routines in the region are shared.
625 if (VD && VD->hasGlobalStorage())
626 DVar.CKind = OMPC_shared;
628 // Non-static data members are shared by default.
630 DVar.CKind = OMPC_shared;
635 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
636 // in a Construct, C/C++, predetermined, p.1]
637 // Variables with automatic storage duration that are declared in a scope
638 // inside the construct are private.
639 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
640 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
641 DVar.CKind = OMPC_private;
645 DVar.DKind = Iter->Directive;
646 // Explicitly specified attributes and local variables with predetermined
648 if (Iter->SharingMap.count(D)) {
649 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
650 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
651 DVar.CKind = Iter->SharingMap[D].Attributes;
652 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
656 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
657 // in a Construct, C/C++, implicitly determined, p.1]
658 // In a parallel or task construct, the data-sharing attributes of these
659 // variables are determined by the default clause, if present.
660 switch (Iter->DefaultAttr) {
662 DVar.CKind = OMPC_shared;
663 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
667 case DSA_unspecified:
668 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
669 // in a Construct, implicitly determined, p.2]
670 // In a parallel construct, if no default clause is present, these
671 // variables are shared.
672 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
673 if (isOpenMPParallelDirective(DVar.DKind) ||
674 isOpenMPTeamsDirective(DVar.DKind)) {
675 DVar.CKind = OMPC_shared;
679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
680 // in a Construct, implicitly determined, p.4]
681 // In a task construct, if no default clause is present, a variable that in
682 // the enclosing context is determined to be shared by all implicit tasks
683 // bound to the current team is shared.
684 if (isOpenMPTaskingDirective(DVar.DKind)) {
686 auto I = Iter, E = Stack.back().first.rend();
689 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
690 // Referenced in a Construct, implicitly determined, p.6]
691 // In a task construct, if no default clause is present, a variable
692 // whose data-sharing attribute is not determined by the rules above is
694 DVarTemp = getDSA(I, D);
695 if (DVarTemp.CKind != OMPC_shared) {
696 DVar.RefExpr = nullptr;
697 DVar.CKind = OMPC_firstprivate;
700 } while (I != E && !isParallelOrTaskRegion(I->Directive));
702 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
706 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707 // in a Construct, implicitly determined, p.3]
708 // For constructs other than task, if no default clause is present, these
709 // variables inherit their data-sharing attributes from the enclosing
711 return getDSA(++Iter, D);
714 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {
715 assert(!isStackEmpty() && "Data sharing attributes stack is empty");
716 D = getCanonicalDecl(D);
717 auto &StackElem = Stack.back().first.back();
718 auto It = StackElem.AlignedMap.find(D);
719 if (It == StackElem.AlignedMap.end()) {
720 assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
721 StackElem.AlignedMap[D] = NewDE;
724 assert(It->second && "Unexpected nullptr expr in the aligned map");
730 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {
731 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
732 D = getCanonicalDecl(D);
733 auto &StackElem = Stack.back().first.back();
734 StackElem.LCVMap.insert(
735 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
738 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {
739 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
740 D = getCanonicalDecl(D);
741 auto &StackElem = Stack.back().first.back();
742 auto It = StackElem.LCVMap.find(D);
743 if (It != StackElem.LCVMap.end())
748 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {
749 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
750 "Data-sharing attributes stack is empty");
751 D = getCanonicalDecl(D);
752 auto &StackElem = *std::next(Stack.back().first.rbegin());
753 auto It = StackElem.LCVMap.find(D);
754 if (It != StackElem.LCVMap.end())
759 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
760 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
761 "Data-sharing attributes stack is empty");
762 auto &StackElem = *std::next(Stack.back().first.rbegin());
763 if (StackElem.LCVMap.size() < I)
765 for (auto &Pair : StackElem.LCVMap)
766 if (Pair.second.first == I)
771 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
772 DeclRefExpr *PrivateCopy) {
773 D = getCanonicalDecl(D);
774 if (A == OMPC_threadprivate) {
775 auto &Data = Threadprivates[D];
777 Data.RefExpr.setPointer(E);
778 Data.PrivateCopy = nullptr;
780 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
781 auto &Data = Stack.back().first.back().SharingMap[D];
782 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
783 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
784 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
785 (isLoopControlVariable(D).first && A == OMPC_private));
786 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
787 Data.RefExpr.setInt(/*IntVal=*/true);
790 const bool IsLastprivate =
791 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
793 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
794 Data.PrivateCopy = PrivateCopy;
796 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
798 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
799 Data.PrivateCopy = nullptr;
804 /// \brief Build a variable declaration for OpenMP loop iteration variable.
805 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
806 StringRef Name, const AttrVec *Attrs = nullptr) {
807 DeclContext *DC = SemaRef.CurContext;
808 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
809 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
811 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
813 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
821 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
823 bool RefersToCapture = false) {
825 D->markUsed(S.Context);
826 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
827 SourceLocation(), D, RefersToCapture, Loc, Ty,
831 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
832 BinaryOperatorKind BOK) {
833 D = getCanonicalDecl(D);
834 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
836 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
837 "Additional reduction info may be specified only for reduction items.");
838 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
839 assert(ReductionData.ReductionRange.isInvalid() &&
840 Stack.back().first.back().Directive == OMPD_taskgroup &&
841 "Additional reduction info may be specified only once for reduction "
843 ReductionData.set(BOK, SR);
844 Expr *&TaskgroupReductionRef =
845 Stack.back().first.back().TaskgroupReductionRef;
846 if (!TaskgroupReductionRef) {
847 auto *VD = buildVarDecl(SemaRef, SR.getBegin(),
848 SemaRef.Context.VoidPtrTy, ".task_red.");
849 TaskgroupReductionRef =
850 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
854 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
855 const Expr *ReductionRef) {
856 D = getCanonicalDecl(D);
857 assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
859 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
860 "Additional reduction info may be specified only for reduction items.");
861 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
862 assert(ReductionData.ReductionRange.isInvalid() &&
863 Stack.back().first.back().Directive == OMPD_taskgroup &&
864 "Additional reduction info may be specified only once for reduction "
866 ReductionData.set(ReductionRef, SR);
867 Expr *&TaskgroupReductionRef =
868 Stack.back().first.back().TaskgroupReductionRef;
869 if (!TaskgroupReductionRef) {
870 auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy,
872 TaskgroupReductionRef =
873 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
877 DSAStackTy::DSAVarData
878 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
879 BinaryOperatorKind &BOK,
880 Expr *&TaskgroupDescriptor) {
881 D = getCanonicalDecl(D);
882 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
883 if (Stack.back().first.empty())
885 for (auto I = std::next(Stack.back().first.rbegin(), 1),
886 E = Stack.back().first.rend();
887 I != E; std::advance(I, 1)) {
888 auto &Data = I->SharingMap[D];
889 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
891 auto &ReductionData = I->ReductionMap[D];
892 if (!ReductionData.ReductionOp ||
893 ReductionData.ReductionOp.is<const Expr *>())
895 SR = ReductionData.ReductionRange;
896 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
897 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
898 "expression for the descriptor is not "
900 TaskgroupDescriptor = I->TaskgroupReductionRef;
901 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
902 Data.PrivateCopy, I->DefaultAttrLoc);
907 DSAStackTy::DSAVarData
908 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
909 const Expr *&ReductionRef,
910 Expr *&TaskgroupDescriptor) {
911 D = getCanonicalDecl(D);
912 assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
913 if (Stack.back().first.empty())
915 for (auto I = std::next(Stack.back().first.rbegin(), 1),
916 E = Stack.back().first.rend();
917 I != E; std::advance(I, 1)) {
918 auto &Data = I->SharingMap[D];
919 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
921 auto &ReductionData = I->ReductionMap[D];
922 if (!ReductionData.ReductionOp ||
923 !ReductionData.ReductionOp.is<const Expr *>())
925 SR = ReductionData.ReductionRange;
926 ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
927 assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
928 "expression for the descriptor is not "
930 TaskgroupDescriptor = I->TaskgroupReductionRef;
931 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
932 Data.PrivateCopy, I->DefaultAttrLoc);
937 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
938 D = D->getCanonicalDecl();
939 if (!isStackEmpty() && Stack.back().first.size() > 1) {
940 reverse_iterator I = Iter, E = Stack.back().first.rend();
941 Scope *TopScope = nullptr;
942 while (I != E && !isParallelOrTaskRegion(I->Directive))
946 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
947 Scope *CurScope = getCurScope();
948 while (CurScope != TopScope && !CurScope->isDeclScope(D))
949 CurScope = CurScope->getParent();
950 return CurScope != TopScope;
955 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
956 D = getCanonicalDecl(D);
959 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
960 // in a Construct, C/C++, predetermined, p.1]
961 // Variables appearing in threadprivate directives are threadprivate.
962 auto *VD = dyn_cast<VarDecl>(D);
963 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
964 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
965 SemaRef.getLangOpts().OpenMPUseTLS &&
966 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
967 (VD && VD->getStorageClass() == SC_Register &&
968 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
969 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
973 auto TI = Threadprivates.find(D);
974 if (TI != Threadprivates.end()) {
975 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
976 DVar.CKind = OMPC_threadprivate;
978 } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
979 DVar.RefExpr = buildDeclRefExpr(
980 SemaRef, VD, D->getType().getNonReferenceType(),
981 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
982 DVar.CKind = OMPC_threadprivate;
983 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
987 // Not in OpenMP execution region and top scope was already checked.
990 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
991 // in a Construct, C/C++, predetermined, p.4]
992 // Static data members are shared.
993 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
994 // in a Construct, C/C++, predetermined, p.7]
995 // Variables with static storage duration that are declared in a scope
996 // inside the construct are shared.
997 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; };
998 if (VD && VD->isStaticDataMember()) {
999 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1000 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1003 DVar.CKind = OMPC_shared;
1007 QualType Type = D->getType().getNonReferenceType().getCanonicalType();
1008 bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1009 Type = SemaRef.getASTContext().getBaseElementType(Type);
1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1011 // in a Construct, C/C++, predetermined, p.6]
1012 // Variables with const qualified type having no mutable member are
1015 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1016 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1017 if (auto *CTD = CTSD->getSpecializedTemplate())
1018 RD = CTD->getTemplatedDecl();
1020 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1021 RD->hasMutableFields())) {
1022 // Variables with const-qualified type having no mutable member may be
1023 // listed in a firstprivate clause, even if they are static data members.
1024 DSAVarData DVarTemp = hasDSA(
1025 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; },
1026 MatchesAlways, FromParent);
1027 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1030 DVar.CKind = OMPC_shared;
1034 // Explicitly specified attributes and local variables with predetermined
1036 auto I = Stack.back().first.rbegin();
1037 auto EndI = Stack.back().first.rend();
1038 if (FromParent && I != EndI)
1040 if (I->SharingMap.count(D)) {
1041 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
1042 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
1043 DVar.CKind = I->SharingMap[D].Attributes;
1044 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1045 DVar.DKind = I->Directive;
1051 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1053 if (isStackEmpty()) {
1054 StackTy::reverse_iterator I;
1055 return getDSA(I, D);
1057 D = getCanonicalDecl(D);
1058 auto StartI = Stack.back().first.rbegin();
1059 auto EndI = Stack.back().first.rend();
1060 if (FromParent && StartI != EndI)
1061 std::advance(StartI, 1);
1062 return getDSA(StartI, D);
1065 DSAStackTy::DSAVarData
1066 DSAStackTy::hasDSA(ValueDecl *D,
1067 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1068 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1072 D = getCanonicalDecl(D);
1073 auto I = Stack.back().first.rbegin();
1074 auto EndI = Stack.back().first.rend();
1075 if (FromParent && I != EndI)
1077 for (; I != EndI; std::advance(I, 1)) {
1078 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1081 DSAVarData DVar = getDSA(NewI, D);
1082 if (I == NewI && CPred(DVar.CKind))
1088 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1089 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1090 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1094 D = getCanonicalDecl(D);
1095 auto StartI = Stack.back().first.rbegin();
1096 auto EndI = Stack.back().first.rend();
1097 if (FromParent && StartI != EndI)
1098 std::advance(StartI, 1);
1099 if (StartI == EndI || !DPred(StartI->Directive))
1102 DSAVarData DVar = getDSA(NewI, D);
1103 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1106 bool DSAStackTy::hasExplicitDSA(
1107 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1108 unsigned Level, bool NotLastprivate) {
1111 D = getCanonicalDecl(D);
1112 auto StartI = Stack.back().first.begin();
1113 auto EndI = Stack.back().first.end();
1114 if (std::distance(StartI, EndI) <= (int)Level)
1116 std::advance(StartI, Level);
1117 return (StartI->SharingMap.count(D) > 0) &&
1118 StartI->SharingMap[D].RefExpr.getPointer() &&
1119 CPred(StartI->SharingMap[D].Attributes) &&
1120 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
1123 bool DSAStackTy::hasExplicitDirective(
1124 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1128 auto StartI = Stack.back().first.begin();
1129 auto EndI = Stack.back().first.end();
1130 if (std::distance(StartI, EndI) <= (int)Level)
1132 std::advance(StartI, Level);
1133 return DPred(StartI->Directive);
1136 bool DSAStackTy::hasDirective(
1137 const llvm::function_ref<bool(OpenMPDirectiveKind,
1138 const DeclarationNameInfo &, SourceLocation)>
1141 // We look only in the enclosing region.
1144 auto StartI = std::next(Stack.back().first.rbegin());
1145 auto EndI = Stack.back().first.rend();
1146 if (FromParent && StartI != EndI)
1147 StartI = std::next(StartI);
1148 for (auto I = StartI, EE = EndI; I != EE; ++I) {
1149 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1155 void Sema::InitDataSharingAttributesStack() {
1156 VarDataSharingAttributesStack = new DSAStackTy(*this);
1159 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1161 void Sema::pushOpenMPFunctionRegion() {
1162 DSAStack->pushFunction();
1165 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1166 DSAStack->popFunction(OldFSI);
1169 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) {
1170 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1172 auto &Ctx = getASTContext();
1173 bool IsByRef = true;
1175 // Find the directive that is associated with the provided scope.
1176 D = cast<ValueDecl>(D->getCanonicalDecl());
1177 auto Ty = D->getType();
1179 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1180 // This table summarizes how a given variable should be passed to the device
1181 // given its type and the clauses where it appears. This table is based on
1182 // the description in OpenMP 4.5 [2.10.4, target Construct] and
1183 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1185 // =========================================================================
1186 // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1187 // | |(tofrom:scalar)| | pvt | | | |
1188 // =========================================================================
1189 // | scl | | | | - | | bycopy|
1190 // | scl | | - | x | - | - | bycopy|
1191 // | scl | | x | - | - | - | null |
1192 // | scl | x | | | - | | byref |
1193 // | scl | x | - | x | - | - | bycopy|
1194 // | scl | x | x | - | - | - | null |
1195 // | scl | | - | - | - | x | byref |
1196 // | scl | x | - | - | - | x | byref |
1198 // | agg | n.a. | | | - | | byref |
1199 // | agg | n.a. | - | x | - | - | byref |
1200 // | agg | n.a. | x | - | - | - | null |
1201 // | agg | n.a. | - | - | - | x | byref |
1202 // | agg | n.a. | - | - | - | x[] | byref |
1204 // | ptr | n.a. | | | - | | bycopy|
1205 // | ptr | n.a. | - | x | - | - | bycopy|
1206 // | ptr | n.a. | x | - | - | - | null |
1207 // | ptr | n.a. | - | - | - | x | byref |
1208 // | ptr | n.a. | - | - | - | x[] | bycopy|
1209 // | ptr | n.a. | - | - | x | | bycopy|
1210 // | ptr | n.a. | - | - | x | x | bycopy|
1211 // | ptr | n.a. | - | - | x | x[] | bycopy|
1212 // =========================================================================
1218 // - - invalid in this combination
1219 // [] - mapped with an array section
1220 // byref - should be mapped by reference
1221 // byval - should be mapped by value
1222 // null - initialize a local variable to null on the device
1225 // - All scalar declarations that show up in a map clause have to be passed
1226 // by reference, because they may have been mapped in the enclosing data
1228 // - If the scalar value does not fit the size of uintptr, it has to be
1229 // passed by reference, regardless the result in the table above.
1230 // - For pointers mapped by value that have either an implicit map or an
1231 // array section, the runtime library may pass the NULL value to the
1232 // device instead of the value passed to it by the compiler.
1234 if (Ty->isReferenceType())
1235 Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1237 // Locate map clauses and see if the variable being captured is referred to
1238 // in any of those clauses. Here we only care about variables, not fields,
1239 // because fields are part of aggregates.
1240 bool IsVariableUsedInMapClause = false;
1241 bool IsVariableAssociatedWithSection = false;
1243 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1244 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
1246 OpenMPClauseKind WhereFoundClauseKind) {
1247 // Only the map clause information influences how a variable is
1248 // captured. E.g. is_device_ptr does not require changing the default
1250 if (WhereFoundClauseKind != OMPC_map)
1253 auto EI = MapExprComponents.rbegin();
1254 auto EE = MapExprComponents.rend();
1256 assert(EI != EE && "Invalid map expression!");
1258 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1259 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1265 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1266 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1267 isa<MemberExpr>(EI->getAssociatedExpression())) {
1268 IsVariableAssociatedWithSection = true;
1269 // There is nothing more we need to know about this variable.
1273 // Keep looking for more map info.
1277 if (IsVariableUsedInMapClause) {
1278 // If variable is identified in a map clause it is always captured by
1279 // reference except if it is a pointer that is dereferenced somehow.
1280 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1282 // By default, all the data that has a scalar type is mapped by copy
1283 // (except for reduction variables).
1285 !Ty->isScalarType() ||
1286 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1287 DSAStack->hasExplicitDSA(
1288 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1292 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1294 !DSAStack->hasExplicitDSA(
1296 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1297 Level, /*NotLastprivate=*/true) &&
1298 // If the variable is artificial and must be captured by value - try to
1299 // capture by value.
1300 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1301 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1304 // When passing data by copy, we need to make sure it fits the uintptr size
1305 // and alignment, because the runtime library only deals with uintptr types.
1306 // If it does not fit the uintptr size, we need to pass the data by reference
1309 (Ctx.getTypeSizeInChars(Ty) >
1310 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1311 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1318 unsigned Sema::getOpenMPNestingLevel() const {
1319 assert(getLangOpts().OpenMP);
1320 return DSAStack->getNestingLevel();
1323 bool Sema::isInOpenMPTargetExecutionDirective() const {
1324 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1325 !DSAStack->isClauseParsingMode()) ||
1326 DSAStack->hasDirective(
1327 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1328 SourceLocation) -> bool {
1329 return isOpenMPTargetExecutionDirective(K);
1334 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) {
1335 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1336 D = getCanonicalDecl(D);
1338 // If we are attempting to capture a global variable in a directive with
1339 // 'target' we return true so that this global is also mapped to the device.
1341 // FIXME: If the declaration is enclosed in a 'declare target' directive,
1342 // then it should not be captured. Therefore, an extra check has to be
1343 // inserted here once support for 'declare target' is added.
1345 auto *VD = dyn_cast<VarDecl>(D);
1346 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1349 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1350 (!DSAStack->isClauseParsingMode() ||
1351 DSAStack->getParentDirective() != OMPD_unknown)) {
1352 auto &&Info = DSAStack->isLoopControlVariable(D);
1354 (VD && VD->hasLocalStorage() &&
1355 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1356 (VD && DSAStack->isForceVarCapturing()))
1357 return VD ? VD : Info.second;
1358 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1359 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1360 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1361 DVarPrivate = DSAStack->hasDSA(
1362 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1363 DSAStack->isClauseParsingMode());
1364 if (DVarPrivate.CKind != OMPC_unknown)
1365 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1370 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1371 unsigned Level) const {
1372 SmallVector<OpenMPDirectiveKind, 4> Regions;
1373 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1374 FunctionScopesIndex -= Regions.size();
1377 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) {
1378 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1379 return DSAStack->hasExplicitDSA(
1380 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1382 (DSAStack->isClauseParsingMode() &&
1383 DSAStack->getClauseParsingMode() == OMPC_private) ||
1384 // Consider taskgroup reduction descriptor variable a private to avoid
1385 // possible capture in the region.
1386 (DSAStack->hasExplicitDirective(
1387 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1389 DSAStack->isTaskgroupReductionRef(D, Level));
1392 void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) {
1393 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1394 D = getCanonicalDecl(D);
1395 OpenMPClauseKind OMPC = OMPC_unknown;
1396 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1397 const unsigned NewLevel = I - 1;
1398 if (DSAStack->hasExplicitDSA(D,
1399 [&OMPC](const OpenMPClauseKind K) {
1400 if (isOpenMPPrivate(K)) {
1408 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1410 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1411 OpenMPClauseKind) { return true; })) {
1415 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1417 OMPC = OMPC_firstprivate;
1421 if (OMPC != OMPC_unknown)
1422 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1425 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) {
1426 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1427 // Return true if the current level is no longer enclosed in a target region.
1429 auto *VD = dyn_cast<VarDecl>(D);
1430 return VD && !VD->hasLocalStorage() &&
1431 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1435 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1437 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1438 const DeclarationNameInfo &DirName,
1439 Scope *CurScope, SourceLocation Loc) {
1440 DSAStack->push(DKind, DirName, CurScope, Loc);
1441 PushExpressionEvaluationContext(
1442 ExpressionEvaluationContext::PotentiallyEvaluated);
1445 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1446 DSAStack->setClauseParsingMode(K);
1449 void Sema::EndOpenMPClause() {
1450 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1453 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1454 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1455 // A variable of class type (or array thereof) that appears in a lastprivate
1456 // clause requires an accessible, unambiguous default constructor for the
1457 // class type, unless the list item is also specified in a firstprivate
1459 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1460 for (auto *C : D->clauses()) {
1461 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1462 SmallVector<Expr *, 8> PrivateCopies;
1463 for (auto *DE : Clause->varlists()) {
1464 if (DE->isValueDependent() || DE->isTypeDependent()) {
1465 PrivateCopies.push_back(nullptr);
1468 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1469 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1470 QualType Type = VD->getType().getNonReferenceType();
1471 auto DVar = DSAStack->getTopDSA(VD, false);
1472 if (DVar.CKind == OMPC_lastprivate) {
1473 // Generate helper private variable and initialize it with the
1474 // default value. The address of the original variable is replaced
1475 // by the address of the new private variable in CodeGen. This new
1476 // variable is not added to IdResolver, so the code in the OpenMP
1477 // region uses original variable for proper diagnostics.
1478 auto *VDPrivate = buildVarDecl(
1479 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1480 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1481 ActOnUninitializedDecl(VDPrivate);
1482 if (VDPrivate->isInvalidDecl())
1484 PrivateCopies.push_back(buildDeclRefExpr(
1485 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1487 // The variable is also a firstprivate, so initialization sequence
1488 // for private copy is generated already.
1489 PrivateCopies.push_back(nullptr);
1492 // Set initializers to private copies if no errors were found.
1493 if (PrivateCopies.size() == Clause->varlist_size())
1494 Clause->setPrivateCopies(PrivateCopies);
1500 DiscardCleanupsInEvaluationContext();
1501 PopExpressionEvaluationContext();
1504 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1505 Expr *NumIterations, Sema &SemaRef,
1506 Scope *S, DSAStackTy *Stack);
1510 class VarDeclFilterCCC : public CorrectionCandidateCallback {
1515 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1516 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1517 NamedDecl *ND = Candidate.getCorrectionDecl();
1518 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1519 return VD->hasGlobalStorage() &&
1520 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1521 SemaRef.getCurScope());
1527 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1532 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1533 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1534 NamedDecl *ND = Candidate.getCorrectionDecl();
1535 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1536 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1537 SemaRef.getCurScope());
1545 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1546 CXXScopeSpec &ScopeSpec,
1547 const DeclarationNameInfo &Id) {
1548 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1549 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1551 if (Lookup.isAmbiguous())
1555 if (!Lookup.isSingleResult()) {
1556 if (TypoCorrection Corrected = CorrectTypo(
1557 Id, LookupOrdinaryName, CurScope, nullptr,
1558 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1559 diagnoseTypo(Corrected,
1560 PDiag(Lookup.empty()
1561 ? diag::err_undeclared_var_use_suggest
1562 : diag::err_omp_expected_var_arg_suggest)
1564 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1566 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1567 : diag::err_omp_expected_var_arg)
1572 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1573 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1574 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1578 Lookup.suppressDiagnostics();
1580 // OpenMP [2.9.2, Syntax, C/C++]
1581 // Variables must be file-scope, namespace-scope, or static block-scope.
1582 if (!VD->hasGlobalStorage()) {
1583 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1584 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1586 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1587 Diag(VD->getLocation(),
1588 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1593 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1594 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1595 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1596 // A threadprivate directive for file-scope variables must appear outside
1597 // any definition or declaration.
1598 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1599 !getCurLexicalContext()->isTranslationUnit()) {
1600 Diag(Id.getLoc(), diag::err_omp_var_scope)
1601 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1603 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1604 Diag(VD->getLocation(),
1605 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1609 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1610 // A threadprivate directive for static class member variables must appear
1611 // in the class definition, in the same scope in which the member
1612 // variables are declared.
1613 if (CanonicalVD->isStaticDataMember() &&
1614 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1615 Diag(Id.getLoc(), diag::err_omp_var_scope)
1616 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1618 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1619 Diag(VD->getLocation(),
1620 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1624 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1625 // A threadprivate directive for namespace-scope variables must appear
1626 // outside any definition or declaration other than the namespace
1627 // definition itself.
1628 if (CanonicalVD->getDeclContext()->isNamespace() &&
1629 (!getCurLexicalContext()->isFileContext() ||
1630 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1631 Diag(Id.getLoc(), diag::err_omp_var_scope)
1632 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1634 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1635 Diag(VD->getLocation(),
1636 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1640 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1641 // A threadprivate directive for static block-scope variables must appear
1642 // in the scope of the variable and not in a nested scope.
1643 if (CanonicalVD->isStaticLocal() && CurScope &&
1644 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1645 Diag(Id.getLoc(), diag::err_omp_var_scope)
1646 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1648 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1649 Diag(VD->getLocation(),
1650 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1655 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1656 // A threadprivate directive must lexically precede all references to any
1657 // of the variables in its list.
1658 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1659 Diag(Id.getLoc(), diag::err_omp_var_used)
1660 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1664 QualType ExprType = VD->getType().getNonReferenceType();
1665 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1666 SourceLocation(), VD,
1667 /*RefersToEnclosingVariableOrCapture=*/false,
1668 Id.getLoc(), ExprType, VK_LValue);
1671 Sema::DeclGroupPtrTy
1672 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1673 ArrayRef<Expr *> VarList) {
1674 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1675 CurContext->addDecl(D);
1676 return DeclGroupPtrTy::make(DeclGroupRef(D));
1682 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1686 bool VisitDeclRefExpr(const DeclRefExpr *E) {
1687 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1688 if (VD->hasLocalStorage()) {
1689 SemaRef.Diag(E->getLocStart(),
1690 diag::err_omp_local_var_in_threadprivate_init)
1691 << E->getSourceRange();
1692 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1693 << VD << VD->getSourceRange();
1699 bool VisitStmt(const Stmt *S) {
1700 for (auto Child : S->children()) {
1701 if (Child && Visit(Child))
1706 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1710 OMPThreadPrivateDecl *
1711 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1712 SmallVector<Expr *, 8> Vars;
1713 for (auto &RefExpr : VarList) {
1714 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1715 VarDecl *VD = cast<VarDecl>(DE->getDecl());
1716 SourceLocation ILoc = DE->getExprLoc();
1718 // Mark variable as used.
1719 VD->setReferenced();
1720 VD->markUsed(Context);
1722 QualType QType = VD->getType();
1723 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1724 // It will be analyzed later.
1729 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1730 // A threadprivate variable must not have an incomplete type.
1731 if (RequireCompleteType(ILoc, VD->getType(),
1732 diag::err_omp_threadprivate_incomplete_type)) {
1736 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1737 // A threadprivate variable must not have a reference type.
1738 if (VD->getType()->isReferenceType()) {
1739 Diag(ILoc, diag::err_omp_ref_type_arg)
1740 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1743 Diag(VD->getLocation(),
1744 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1749 // Check if this is a TLS variable. If TLS is not being supported, produce
1750 // the corresponding diagnostic.
1751 if ((VD->getTLSKind() != VarDecl::TLS_None &&
1752 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1753 getLangOpts().OpenMPUseTLS &&
1754 getASTContext().getTargetInfo().isTLSSupported())) ||
1755 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1756 !VD->isLocalVarDecl())) {
1757 Diag(ILoc, diag::err_omp_var_thread_local)
1758 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1760 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1761 Diag(VD->getLocation(),
1762 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1767 // Check if initial value of threadprivate variable reference variable with
1768 // local storage (it is not supported by runtime).
1769 if (auto Init = VD->getAnyInitializer()) {
1770 LocalVarRefChecker Checker(*this);
1771 if (Checker.Visit(Init))
1775 Vars.push_back(RefExpr);
1776 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1777 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1778 Context, SourceRange(Loc, Loc)));
1779 if (auto *ML = Context.getASTMutationListener())
1780 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1782 OMPThreadPrivateDecl *D = nullptr;
1783 if (!Vars.empty()) {
1784 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1786 D->setAccess(AS_public);
1791 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1792 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1793 bool IsLoopIterVar = false) {
1795 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1796 << getOpenMPClauseName(DVar.CKind);
1800 PDSA_StaticMemberShared,
1801 PDSA_StaticLocalVarShared,
1802 PDSA_LoopIterVarPrivate,
1803 PDSA_LoopIterVarLinear,
1804 PDSA_LoopIterVarLastprivate,
1805 PDSA_ConstVarShared,
1806 PDSA_GlobalVarShared,
1807 PDSA_TaskVarFirstprivate,
1808 PDSA_LocalVarPrivate,
1810 } Reason = PDSA_Implicit;
1811 bool ReportHint = false;
1812 auto ReportLoc = D->getLocation();
1813 auto *VD = dyn_cast<VarDecl>(D);
1814 if (IsLoopIterVar) {
1815 if (DVar.CKind == OMPC_private)
1816 Reason = PDSA_LoopIterVarPrivate;
1817 else if (DVar.CKind == OMPC_lastprivate)
1818 Reason = PDSA_LoopIterVarLastprivate;
1820 Reason = PDSA_LoopIterVarLinear;
1821 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1822 DVar.CKind == OMPC_firstprivate) {
1823 Reason = PDSA_TaskVarFirstprivate;
1824 ReportLoc = DVar.ImplicitDSALoc;
1825 } else if (VD && VD->isStaticLocal())
1826 Reason = PDSA_StaticLocalVarShared;
1827 else if (VD && VD->isStaticDataMember())
1828 Reason = PDSA_StaticMemberShared;
1829 else if (VD && VD->isFileVarDecl())
1830 Reason = PDSA_GlobalVarShared;
1831 else if (D->getType().isConstant(SemaRef.getASTContext()))
1832 Reason = PDSA_ConstVarShared;
1833 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1835 Reason = PDSA_LocalVarPrivate;
1837 if (Reason != PDSA_Implicit) {
1838 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1839 << Reason << ReportHint
1840 << getOpenMPDirectiveName(Stack->getCurrentDirective());
1841 } else if (DVar.ImplicitDSALoc.isValid()) {
1842 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1843 << getOpenMPClauseName(DVar.CKind);
1848 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1853 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1854 llvm::SmallVector<Expr *, 8> ImplicitMap;
1855 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1856 llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1859 void VisitDeclRefExpr(DeclRefExpr *E) {
1860 if (E->isTypeDependent() || E->isValueDependent() ||
1861 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1863 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1864 VD = VD->getCanonicalDecl();
1865 // Skip internally declared variables.
1866 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1869 auto DVar = Stack->getTopDSA(VD, false);
1870 // Check if the variable has explicit DSA set and stop analysis if it so.
1871 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1874 // Skip internally declared static variables.
1875 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1878 auto ELoc = E->getExprLoc();
1879 auto DKind = Stack->getCurrentDirective();
1880 // The default(none) clause requires that each variable that is referenced
1881 // in the construct, and does not have a predetermined data-sharing
1882 // attribute, must have its data-sharing attribute explicitly determined
1883 // by being listed in a data-sharing attribute clause.
1884 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1885 isParallelOrTaskRegion(DKind) &&
1886 VarsWithInheritedDSA.count(VD) == 0) {
1887 VarsWithInheritedDSA[VD] = E;
1891 if (isOpenMPTargetExecutionDirective(DKind) &&
1892 !Stack->isLoopControlVariable(VD).first) {
1893 if (!Stack->checkMappableExprComponentListsForDecl(
1894 VD, /*CurrentRegionOnly=*/true,
1895 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1898 // Variable is used if it has been marked as an array, array
1899 // section or the variable iself.
1900 return StackComponents.size() == 1 ||
1902 std::next(StackComponents.rbegin()),
1903 StackComponents.rend(),
1904 [](const OMPClauseMappableExprCommon::
1905 MappableComponent &MC) {
1906 return MC.getAssociatedDeclaration() ==
1908 (isa<OMPArraySectionExpr>(
1909 MC.getAssociatedExpression()) ||
1910 isa<ArraySubscriptExpr>(
1911 MC.getAssociatedExpression()));
1914 bool IsFirstprivate = false;
1915 // By default lambdas are captured as firstprivates.
1916 if (const auto *RD =
1917 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1918 IsFirstprivate = RD->isLambda();
1921 (VD->getType().getNonReferenceType()->isScalarType() &&
1922 Stack->getDefaultDMA() != DMA_tofrom_scalar);
1924 ImplicitFirstprivate.emplace_back(E);
1926 ImplicitMap.emplace_back(E);
1931 // OpenMP [2.9.3.6, Restrictions, p.2]
1932 // A list item that appears in a reduction clause of the innermost
1933 // enclosing worksharing or parallel construct may not be accessed in an
1935 DVar = Stack->hasInnermostDSA(
1936 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1937 [](OpenMPDirectiveKind K) -> bool {
1938 return isOpenMPParallelDirective(K) ||
1939 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1941 /*FromParent=*/true);
1942 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1944 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1945 ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1949 // Define implicit data-sharing attributes for task.
1950 DVar = Stack->getImplicitDSA(VD, false);
1951 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1952 !Stack->isLoopControlVariable(VD).first)
1953 ImplicitFirstprivate.push_back(E);
1956 void VisitMemberExpr(MemberExpr *E) {
1957 if (E->isTypeDependent() || E->isValueDependent() ||
1958 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1960 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1961 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1962 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1965 auto DVar = Stack->getTopDSA(FD, false);
1966 // Check if the variable has explicit DSA set and stop analysis if it
1968 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1971 if (isOpenMPTargetExecutionDirective(DKind) &&
1972 !Stack->isLoopControlVariable(FD).first &&
1973 !Stack->checkMappableExprComponentListsForDecl(
1974 FD, /*CurrentRegionOnly=*/true,
1975 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1978 return isa<CXXThisExpr>(
1980 StackComponents.back().getAssociatedExpression())
1984 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1985 // A bit-field cannot appear in a map clause.
1987 if (FD->isBitField())
1989 ImplicitMap.emplace_back(E);
1993 auto ELoc = E->getExprLoc();
1994 // OpenMP [2.9.3.6, Restrictions, p.2]
1995 // A list item that appears in a reduction clause of the innermost
1996 // enclosing worksharing or parallel construct may not be accessed in
1997 // an explicit task.
1998 DVar = Stack->hasInnermostDSA(
1999 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
2000 [](OpenMPDirectiveKind K) -> bool {
2001 return isOpenMPParallelDirective(K) ||
2002 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
2004 /*FromParent=*/true);
2005 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2007 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2008 ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2012 // Define implicit data-sharing attributes for task.
2013 DVar = Stack->getImplicitDSA(FD, false);
2014 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2015 !Stack->isLoopControlVariable(FD).first)
2016 ImplicitFirstprivate.push_back(E);
2019 if (isOpenMPTargetExecutionDirective(DKind)) {
2020 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2021 if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2022 /*NoDiagnose=*/true))
2024 auto *VD = cast<ValueDecl>(
2025 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2026 if (!Stack->checkMappableExprComponentListsForDecl(
2027 VD, /*CurrentRegionOnly=*/true,
2029 OMPClauseMappableExprCommon::MappableExprComponentListRef
2032 auto CCI = CurComponents.rbegin();
2033 auto CCE = CurComponents.rend();
2034 for (const auto &SC : llvm::reverse(StackComponents)) {
2035 // Do both expressions have the same kind?
2036 if (CCI->getAssociatedExpression()->getStmtClass() !=
2037 SC.getAssociatedExpression()->getStmtClass())
2038 if (!(isa<OMPArraySectionExpr>(
2039 SC.getAssociatedExpression()) &&
2040 isa<ArraySubscriptExpr>(
2041 CCI->getAssociatedExpression())))
2044 Decl *CCD = CCI->getAssociatedDeclaration();
2045 Decl *SCD = SC.getAssociatedDeclaration();
2046 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2047 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2050 std::advance(CCI, 1);
2056 Visit(E->getBase());
2059 Visit(E->getBase());
2061 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2062 for (auto *C : S->clauses()) {
2063 // Skip analysis of arguments of implicitly defined firstprivate clause
2064 // for task|target directives.
2065 // Skip analysis of arguments of implicitly defined map clause for target
2067 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2069 for (auto *CC : C->children()) {
2076 void VisitStmt(Stmt *S) {
2077 for (auto *C : S->children()) {
2078 if (C && !isa<OMPExecutableDirective>(C))
2083 bool isErrorFound() { return ErrorFound; }
2084 ArrayRef<Expr *> getImplicitFirstprivate() const {
2085 return ImplicitFirstprivate;
2087 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2088 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2089 return VarsWithInheritedDSA;
2092 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2093 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2097 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2100 case OMPD_parallel_for:
2101 case OMPD_parallel_for_simd:
2102 case OMPD_parallel_sections:
2104 case OMPD_teams_distribute:
2105 case OMPD_teams_distribute_simd: {
2106 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2107 QualType KmpInt32PtrTy =
2108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2109 Sema::CapturedParamNameType Params[] = {
2110 std::make_pair(".global_tid.", KmpInt32PtrTy),
2111 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2112 std::make_pair(StringRef(), QualType()) // __context with shared vars
2114 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2118 case OMPD_target_teams:
2119 case OMPD_target_parallel:
2120 case OMPD_target_parallel_for:
2121 case OMPD_target_parallel_for_simd:
2122 case OMPD_target_teams_distribute:
2123 case OMPD_target_teams_distribute_simd: {
2124 Sema::CapturedParamNameType ParamsTarget[] = {
2125 std::make_pair(StringRef(), QualType()) // __context with shared vars
2127 // Start a captured region for 'target' with no implicit parameters.
2128 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2130 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2131 QualType KmpInt32PtrTy =
2132 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2133 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2134 std::make_pair(".global_tid.", KmpInt32PtrTy),
2135 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2136 std::make_pair(StringRef(), QualType()) // __context with shared vars
2138 // Start a captured region for 'teams' or 'parallel'. Both regions have
2139 // the same implicit parameters.
2140 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2141 ParamsTeamsOrParallel);
2152 case OMPD_taskgroup:
2153 case OMPD_distribute:
2154 case OMPD_distribute_simd:
2157 case OMPD_target_data:
2159 case OMPD_target_simd: {
2160 Sema::CapturedParamNameType Params[] = {
2161 std::make_pair(StringRef(), QualType()) // __context with shared vars
2163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2168 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2169 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2170 FunctionProtoType::ExtProtoInfo EPI;
2171 EPI.Variadic = true;
2172 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2173 Sema::CapturedParamNameType Params[] = {
2174 std::make_pair(".global_tid.", KmpInt32Ty),
2175 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2176 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2177 std::make_pair(".copy_fn.",
2178 Context.getPointerType(CopyFnType).withConst()),
2179 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2180 std::make_pair(StringRef(), QualType()) // __context with shared vars
2182 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2184 // Mark this captured region as inlined, because we don't use outlined
2185 // function directly.
2186 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2187 AlwaysInlineAttr::CreateImplicit(
2188 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2192 case OMPD_taskloop_simd: {
2193 QualType KmpInt32Ty =
2194 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2195 QualType KmpUInt64Ty =
2196 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2197 QualType KmpInt64Ty =
2198 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2199 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2200 FunctionProtoType::ExtProtoInfo EPI;
2201 EPI.Variadic = true;
2202 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2203 Sema::CapturedParamNameType Params[] = {
2204 std::make_pair(".global_tid.", KmpInt32Ty),
2205 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2206 std::make_pair(".privates.",
2207 Context.VoidPtrTy.withConst().withRestrict()),
2210 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2211 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2212 std::make_pair(".lb.", KmpUInt64Ty),
2213 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2214 std::make_pair(".liter.", KmpInt32Ty),
2215 std::make_pair(".reductions.",
2216 Context.VoidPtrTy.withConst().withRestrict()),
2217 std::make_pair(StringRef(), QualType()) // __context with shared vars
2219 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2221 // Mark this captured region as inlined, because we don't use outlined
2222 // function directly.
2223 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2224 AlwaysInlineAttr::CreateImplicit(
2225 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2228 case OMPD_distribute_parallel_for_simd:
2229 case OMPD_distribute_parallel_for:
2230 case OMPD_target_teams_distribute_parallel_for:
2231 case OMPD_target_teams_distribute_parallel_for_simd: {
2232 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2233 QualType KmpInt32PtrTy =
2234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2235 Sema::CapturedParamNameType Params[] = {
2236 std::make_pair(".global_tid.", KmpInt32PtrTy),
2237 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2238 std::make_pair(".previous.lb.", Context.getSizeType()),
2239 std::make_pair(".previous.ub.", Context.getSizeType()),
2240 std::make_pair(StringRef(), QualType()) // __context with shared vars
2242 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2246 case OMPD_teams_distribute_parallel_for:
2247 case OMPD_teams_distribute_parallel_for_simd: {
2248 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2249 QualType KmpInt32PtrTy =
2250 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2252 Sema::CapturedParamNameType ParamsTeams[] = {
2253 std::make_pair(".global_tid.", KmpInt32PtrTy),
2254 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2255 std::make_pair(StringRef(), QualType()) // __context with shared vars
2257 // Start a captured region for 'target' with no implicit parameters.
2258 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2261 Sema::CapturedParamNameType ParamsParallel[] = {
2262 std::make_pair(".global_tid.", KmpInt32PtrTy),
2263 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2264 std::make_pair(".previous.lb.", Context.getSizeType()),
2265 std::make_pair(".previous.ub.", Context.getSizeType()),
2266 std::make_pair(StringRef(), QualType()) // __context with shared vars
2268 // Start a captured region for 'teams' or 'parallel'. Both regions have
2269 // the same implicit parameters.
2270 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2274 case OMPD_target_update:
2275 case OMPD_target_enter_data:
2276 case OMPD_target_exit_data: {
2277 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2278 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2279 FunctionProtoType::ExtProtoInfo EPI;
2280 EPI.Variadic = true;
2281 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2282 Sema::CapturedParamNameType Params[] = {
2283 std::make_pair(".global_tid.", KmpInt32Ty),
2284 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2285 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2286 std::make_pair(".copy_fn.",
2287 Context.getPointerType(CopyFnType).withConst()),
2288 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2289 std::make_pair(StringRef(), QualType()) // __context with shared vars
2291 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2293 // Mark this captured region as inlined, because we don't use outlined
2294 // function directly.
2295 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2296 AlwaysInlineAttr::CreateImplicit(
2297 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2300 case OMPD_threadprivate:
2301 case OMPD_taskyield:
2304 case OMPD_cancellation_point:
2307 case OMPD_declare_reduction:
2308 case OMPD_declare_simd:
2309 case OMPD_declare_target:
2310 case OMPD_end_declare_target:
2311 llvm_unreachable("OpenMP Directive is not allowed");
2313 llvm_unreachable("Unknown OpenMP directive");
2317 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2318 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2319 getOpenMPCaptureRegions(CaptureRegions, DKind);
2320 return CaptureRegions.size();
2323 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2324 Expr *CaptureExpr, bool WithInit,
2325 bool AsExpression) {
2326 assert(CaptureExpr);
2327 ASTContext &C = S.getASTContext();
2328 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2329 QualType Ty = Init->getType();
2330 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2331 if (S.getLangOpts().CPlusPlus) {
2332 Ty = C.getLValueReferenceType(Ty);
2334 Ty = C.getPointerType(Ty);
2336 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2337 if (!Res.isUsable())
2343 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2344 CaptureExpr->getLocStart());
2346 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2347 S.CurContext->addHiddenDecl(CED);
2348 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2352 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2354 OMPCapturedExprDecl *CD;
2355 if (auto *VD = S.IsOpenMPCapturedDecl(D)) {
2356 CD = cast<OMPCapturedExprDecl>(VD);
2358 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2359 /*AsExpression=*/false);
2361 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2362 CaptureExpr->getExprLoc());
2365 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2366 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2368 OMPCapturedExprDecl *CD = buildCaptureDecl(
2369 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2370 /*WithInit=*/true, /*AsExpression=*/true);
2371 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2372 CaptureExpr->getExprLoc());
2374 ExprResult Res = Ref;
2375 if (!S.getLangOpts().CPlusPlus &&
2376 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2377 Ref->getType()->isPointerType()) {
2378 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2379 if (!Res.isUsable())
2382 return S.DefaultLvalueConversion(Res.get());
2386 // OpenMP directives parsed in this section are represented as a
2387 // CapturedStatement with an associated statement. If a syntax error
2388 // is detected during the parsing of the associated statement, the
2389 // compiler must abort processing and close the CapturedStatement.
2391 // Combined directives such as 'target parallel' have more than one
2392 // nested CapturedStatements. This RAII ensures that we unwind out
2393 // of all the nested CapturedStatements when an error is found.
2394 class CaptureRegionUnwinderRAII {
2398 OpenMPDirectiveKind DKind;
2401 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2402 OpenMPDirectiveKind DKind)
2403 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2404 ~CaptureRegionUnwinderRAII() {
2406 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2407 while (--ThisCaptureLevel >= 0)
2408 S.ActOnCapturedRegionError();
2414 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2415 ArrayRef<OMPClause *> Clauses) {
2416 bool ErrorFound = false;
2417 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2418 *this, ErrorFound, DSAStack->getCurrentDirective());
2419 if (!S.isUsable()) {
2424 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2425 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2426 OMPOrderedClause *OC = nullptr;
2427 OMPScheduleClause *SC = nullptr;
2428 SmallVector<OMPLinearClause *, 4> LCs;
2429 SmallVector<OMPClauseWithPreInit *, 8> PICs;
2430 // This is required for proper codegen.
2431 for (auto *Clause : Clauses) {
2432 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2433 Clause->getClauseKind() == OMPC_in_reduction) {
2434 // Capture taskgroup task_reduction descriptors inside the tasking regions
2435 // with the corresponding in_reduction items.
2436 auto *IRC = cast<OMPInReductionClause>(Clause);
2437 for (auto *E : IRC->taskgroup_descriptors())
2439 MarkDeclarationsReferencedInExpr(E);
2441 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2442 Clause->getClauseKind() == OMPC_copyprivate ||
2443 (getLangOpts().OpenMPUseTLS &&
2444 getASTContext().getTargetInfo().isTLSSupported() &&
2445 Clause->getClauseKind() == OMPC_copyin)) {
2446 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2447 // Mark all variables in private list clauses as used in inner region.
2448 for (auto *VarRef : Clause->children()) {
2449 if (auto *E = cast_or_null<Expr>(VarRef)) {
2450 MarkDeclarationsReferencedInExpr(E);
2453 DSAStack->setForceVarCapturing(/*V=*/false);
2454 } else if (CaptureRegions.size() > 1 ||
2455 CaptureRegions.back() != OMPD_unknown) {
2456 if (auto *C = OMPClauseWithPreInit::get(Clause))
2458 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2459 if (auto *E = C->getPostUpdateExpr())
2460 MarkDeclarationsReferencedInExpr(E);
2463 if (Clause->getClauseKind() == OMPC_schedule)
2464 SC = cast<OMPScheduleClause>(Clause);
2465 else if (Clause->getClauseKind() == OMPC_ordered)
2466 OC = cast<OMPOrderedClause>(Clause);
2467 else if (Clause->getClauseKind() == OMPC_linear)
2468 LCs.push_back(cast<OMPLinearClause>(Clause));
2470 // OpenMP, 2.7.1 Loop Construct, Restrictions
2471 // The nonmonotonic modifier cannot be specified if an ordered clause is
2474 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2475 SC->getSecondScheduleModifier() ==
2476 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2478 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2479 ? SC->getFirstScheduleModifierLoc()
2480 : SC->getSecondScheduleModifierLoc(),
2481 diag::err_omp_schedule_nonmonotonic_ordered)
2482 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2485 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2486 for (auto *C : LCs) {
2487 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2488 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2492 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2493 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2494 OC->getNumForLoops()) {
2495 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2496 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2503 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2504 // Mark all variables in private list clauses as used in inner region.
2505 // Required for proper codegen of combined directives.
2506 // TODO: add processing for other clauses.
2507 if (ThisCaptureRegion != OMPD_unknown) {
2508 for (auto *C : PICs) {
2509 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2510 // Find the particular capture region for the clause if the
2511 // directive is a combined one with multiple capture regions.
2512 // If the directive is not a combined one, the capture region
2513 // associated with the clause is OMPD_unknown and is generated
2515 if (CaptureRegion == ThisCaptureRegion ||
2516 CaptureRegion == OMPD_unknown) {
2517 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2518 for (auto *D : DS->decls())
2519 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2524 SR = ActOnCapturedRegionEnd(SR.get());
2529 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2530 OpenMPDirectiveKind CancelRegion,
2531 SourceLocation StartLoc) {
2532 // CancelRegion is only needed for cancel and cancellation_point.
2533 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2536 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2537 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2540 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2541 << getOpenMPDirectiveName(CancelRegion);
2545 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2546 OpenMPDirectiveKind CurrentRegion,
2547 const DeclarationNameInfo &CurrentName,
2548 OpenMPDirectiveKind CancelRegion,
2549 SourceLocation StartLoc) {
2550 if (Stack->getCurScope()) {
2551 auto ParentRegion = Stack->getParentDirective();
2552 auto OffendingRegion = ParentRegion;
2553 bool NestingProhibited = false;
2554 bool CloseNesting = true;
2555 bool OrphanSeen = false;
2558 ShouldBeInParallelRegion,
2559 ShouldBeInOrderedRegion,
2560 ShouldBeInTargetRegion,
2561 ShouldBeInTeamsRegion
2562 } Recommend = NoRecommend;
2563 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2564 // OpenMP [2.16, Nesting of Regions]
2565 // OpenMP constructs may not be nested inside a simd region.
2566 // OpenMP [2.8.1,simd Construct, Restrictions]
2567 // An ordered construct with the simd clause is the only OpenMP
2568 // construct that can appear in the simd region.
2569 // Allowing a SIMD construct nested in another SIMD construct is an
2570 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2572 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2573 ? diag::err_omp_prohibited_region_simd
2574 : diag::warn_omp_nesting_simd);
2575 return CurrentRegion != OMPD_simd;
2577 if (ParentRegion == OMPD_atomic) {
2578 // OpenMP [2.16, Nesting of Regions]
2579 // OpenMP constructs may not be nested inside an atomic region.
2580 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2583 if (CurrentRegion == OMPD_section) {
2584 // OpenMP [2.7.2, sections Construct, Restrictions]
2585 // Orphaned section directives are prohibited. That is, the section
2586 // directives must appear within the sections construct and must not be
2587 // encountered elsewhere in the sections region.
2588 if (ParentRegion != OMPD_sections &&
2589 ParentRegion != OMPD_parallel_sections) {
2590 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2591 << (ParentRegion != OMPD_unknown)
2592 << getOpenMPDirectiveName(ParentRegion);
2597 // Allow some constructs (except teams) to be orphaned (they could be
2598 // used in functions, called from OpenMP regions with the required
2600 if (ParentRegion == OMPD_unknown &&
2601 !isOpenMPNestingTeamsDirective(CurrentRegion))
2603 if (CurrentRegion == OMPD_cancellation_point ||
2604 CurrentRegion == OMPD_cancel) {
2605 // OpenMP [2.16, Nesting of Regions]
2606 // A cancellation point construct for which construct-type-clause is
2607 // taskgroup must be nested inside a task construct. A cancellation
2608 // point construct for which construct-type-clause is not taskgroup must
2609 // be closely nested inside an OpenMP construct that matches the type
2610 // specified in construct-type-clause.
2611 // A cancel construct for which construct-type-clause is taskgroup must be
2612 // nested inside a task construct. A cancel construct for which
2613 // construct-type-clause is not taskgroup must be closely nested inside an
2614 // OpenMP construct that matches the type specified in
2615 // construct-type-clause.
2617 !((CancelRegion == OMPD_parallel &&
2618 (ParentRegion == OMPD_parallel ||
2619 ParentRegion == OMPD_target_parallel)) ||
2620 (CancelRegion == OMPD_for &&
2621 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2622 ParentRegion == OMPD_target_parallel_for ||
2623 ParentRegion == OMPD_distribute_parallel_for ||
2624 ParentRegion == OMPD_teams_distribute_parallel_for ||
2625 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2626 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2627 (CancelRegion == OMPD_sections &&
2628 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2629 ParentRegion == OMPD_parallel_sections)));
2630 } else if (CurrentRegion == OMPD_master) {
2631 // OpenMP [2.16, Nesting of Regions]
2632 // A master region may not be closely nested inside a worksharing,
2633 // atomic, or explicit task region.
2634 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2635 isOpenMPTaskingDirective(ParentRegion);
2636 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2637 // OpenMP [2.16, Nesting of Regions]
2638 // A critical region may not be nested (closely or otherwise) inside a
2639 // critical region with the same name. Note that this restriction is not
2640 // sufficient to prevent deadlock.
2641 SourceLocation PreviousCriticalLoc;
2642 bool DeadLock = Stack->hasDirective(
2643 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2644 const DeclarationNameInfo &DNI,
2645 SourceLocation Loc) -> bool {
2646 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2647 PreviousCriticalLoc = Loc;
2652 false /* skip top directive */);
2654 SemaRef.Diag(StartLoc,
2655 diag::err_omp_prohibited_region_critical_same_name)
2656 << CurrentName.getName();
2657 if (PreviousCriticalLoc.isValid())
2658 SemaRef.Diag(PreviousCriticalLoc,
2659 diag::note_omp_previous_critical_region);
2662 } else if (CurrentRegion == OMPD_barrier) {
2663 // OpenMP [2.16, Nesting of Regions]
2664 // A barrier region may not be closely nested inside a worksharing,
2665 // explicit task, critical, ordered, atomic, or master region.
2666 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2667 isOpenMPTaskingDirective(ParentRegion) ||
2668 ParentRegion == OMPD_master ||
2669 ParentRegion == OMPD_critical ||
2670 ParentRegion == OMPD_ordered;
2671 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2672 !isOpenMPParallelDirective(CurrentRegion) &&
2673 !isOpenMPTeamsDirective(CurrentRegion)) {
2674 // OpenMP [2.16, Nesting of Regions]
2675 // A worksharing region may not be closely nested inside a worksharing,
2676 // explicit task, critical, ordered, atomic, or master region.
2677 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2678 isOpenMPTaskingDirective(ParentRegion) ||
2679 ParentRegion == OMPD_master ||
2680 ParentRegion == OMPD_critical ||
2681 ParentRegion == OMPD_ordered;
2682 Recommend = ShouldBeInParallelRegion;
2683 } else if (CurrentRegion == OMPD_ordered) {
2684 // OpenMP [2.16, Nesting of Regions]
2685 // An ordered region may not be closely nested inside a critical,
2686 // atomic, or explicit task region.
2687 // An ordered region must be closely nested inside a loop region (or
2688 // parallel loop region) with an ordered clause.
2689 // OpenMP [2.8.1,simd Construct, Restrictions]
2690 // An ordered construct with the simd clause is the only OpenMP construct
2691 // that can appear in the simd region.
2692 NestingProhibited = ParentRegion == OMPD_critical ||
2693 isOpenMPTaskingDirective(ParentRegion) ||
2694 !(isOpenMPSimdDirective(ParentRegion) ||
2695 Stack->isParentOrderedRegion());
2696 Recommend = ShouldBeInOrderedRegion;
2697 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2698 // OpenMP [2.16, Nesting of Regions]
2699 // If specified, a teams construct must be contained within a target
2701 NestingProhibited = ParentRegion != OMPD_target;
2702 OrphanSeen = ParentRegion == OMPD_unknown;
2703 Recommend = ShouldBeInTargetRegion;
2705 if (!NestingProhibited &&
2706 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2707 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2708 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2709 // OpenMP [2.16, Nesting of Regions]
2710 // distribute, parallel, parallel sections, parallel workshare, and the
2711 // parallel loop and parallel loop SIMD constructs are the only OpenMP
2712 // constructs that can be closely nested in the teams region.
2713 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2714 !isOpenMPDistributeDirective(CurrentRegion);
2715 Recommend = ShouldBeInParallelRegion;
2717 if (!NestingProhibited &&
2718 isOpenMPNestingDistributeDirective(CurrentRegion)) {
2719 // OpenMP 4.5 [2.17 Nesting of Regions]
2720 // The region associated with the distribute construct must be strictly
2721 // nested inside a teams region
2723 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2724 Recommend = ShouldBeInTeamsRegion;
2726 if (!NestingProhibited &&
2727 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2728 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2729 // OpenMP 4.5 [2.17 Nesting of Regions]
2730 // If a target, target update, target data, target enter data, or
2731 // target exit data construct is encountered during execution of a
2732 // target region, the behavior is unspecified.
2733 NestingProhibited = Stack->hasDirective(
2734 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2735 SourceLocation) -> bool {
2736 if (isOpenMPTargetExecutionDirective(K)) {
2737 OffendingRegion = K;
2742 false /* don't skip top directive */);
2743 CloseNesting = false;
2745 if (NestingProhibited) {
2747 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2748 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2750 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2751 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2752 << Recommend << getOpenMPDirectiveName(CurrentRegion);
2760 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2761 ArrayRef<OMPClause *> Clauses,
2762 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2763 bool ErrorFound = false;
2764 unsigned NamedModifiersNumber = 0;
2765 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2767 SmallVector<SourceLocation, 4> NameModifierLoc;
2768 for (const auto *C : Clauses) {
2769 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2770 // At most one if clause without a directive-name-modifier can appear on
2772 OpenMPDirectiveKind CurNM = IC->getNameModifier();
2773 if (FoundNameModifiers[CurNM]) {
2774 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2775 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2776 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2778 } else if (CurNM != OMPD_unknown) {
2779 NameModifierLoc.push_back(IC->getNameModifierLoc());
2780 ++NamedModifiersNumber;
2782 FoundNameModifiers[CurNM] = IC;
2783 if (CurNM == OMPD_unknown)
2785 // Check if the specified name modifier is allowed for the current
2787 // At most one if clause with the particular directive-name-modifier can
2788 // appear on the directive.
2789 bool MatchFound = false;
2790 for (auto NM : AllowedNameModifiers) {
2797 S.Diag(IC->getNameModifierLoc(),
2798 diag::err_omp_wrong_if_directive_name_modifier)
2799 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
2804 // If any if clause on the directive includes a directive-name-modifier then
2805 // all if clauses on the directive must include a directive-name-modifier.
2806 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2807 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2808 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2809 diag::err_omp_no_more_if_clause);
2812 std::string Sep(", ");
2813 unsigned AllowedCnt = 0;
2814 unsigned TotalAllowedNum =
2815 AllowedNameModifiers.size() - NamedModifiersNumber;
2816 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2818 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2819 if (!FoundNameModifiers[NM]) {
2821 Values += getOpenMPDirectiveName(NM);
2823 if (AllowedCnt + 2 == TotalAllowedNum)
2825 else if (AllowedCnt + 1 != TotalAllowedNum)
2830 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2831 diag::err_omp_unnamed_if_clause)
2832 << (TotalAllowedNum > 1) << Values;
2834 for (auto Loc : NameModifierLoc) {
2835 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2842 StmtResult Sema::ActOnOpenMPExecutableDirective(
2843 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2844 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2845 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2846 StmtResult Res = StmtError();
2847 // First check CancelRegion which is then used in checkNestingOfRegions.
2848 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2849 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2853 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2854 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2855 bool ErrorFound = false;
2856 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2857 if (AStmt && !CurContext->isDependentContext()) {
2858 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2860 // Check default data sharing attributes for referenced variables.
2861 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2862 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2864 while (--ThisCaptureLevel >= 0)
2865 S = cast<CapturedStmt>(S)->getCapturedStmt();
2866 DSAChecker.Visit(S);
2867 if (DSAChecker.isErrorFound())
2869 // Generate list of implicitly defined firstprivate variables.
2870 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2872 SmallVector<Expr *, 4> ImplicitFirstprivates(
2873 DSAChecker.getImplicitFirstprivate().begin(),
2874 DSAChecker.getImplicitFirstprivate().end());
2875 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2876 DSAChecker.getImplicitMap().end());
2877 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2878 for (auto *C : Clauses) {
2879 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2880 for (auto *E : IRC->taskgroup_descriptors())
2882 ImplicitFirstprivates.emplace_back(E);
2885 if (!ImplicitFirstprivates.empty()) {
2886 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2887 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2888 SourceLocation())) {
2889 ClausesWithImplicit.push_back(Implicit);
2890 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2891 ImplicitFirstprivates.size();
2895 if (!ImplicitMaps.empty()) {
2896 if (OMPClause *Implicit = ActOnOpenMPMapClause(
2897 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2898 SourceLocation(), SourceLocation(), ImplicitMaps,
2899 SourceLocation(), SourceLocation(), SourceLocation())) {
2900 ClausesWithImplicit.emplace_back(Implicit);
2902 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2908 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2911 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2913 AllowedNameModifiers.push_back(OMPD_parallel);
2916 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2917 VarsWithInheritedDSA);
2920 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2921 VarsWithInheritedDSA);
2924 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2925 EndLoc, VarsWithInheritedDSA);
2928 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2932 assert(ClausesWithImplicit.empty() &&
2933 "No clauses are allowed for 'omp section' directive");
2934 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2937 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2941 assert(ClausesWithImplicit.empty() &&
2942 "No clauses are allowed for 'omp master' directive");
2943 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2946 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2949 case OMPD_parallel_for:
2950 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2951 EndLoc, VarsWithInheritedDSA);
2952 AllowedNameModifiers.push_back(OMPD_parallel);
2954 case OMPD_parallel_for_simd:
2955 Res = ActOnOpenMPParallelForSimdDirective(
2956 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2957 AllowedNameModifiers.push_back(OMPD_parallel);
2959 case OMPD_parallel_sections:
2960 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2962 AllowedNameModifiers.push_back(OMPD_parallel);
2966 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2967 AllowedNameModifiers.push_back(OMPD_task);
2969 case OMPD_taskyield:
2970 assert(ClausesWithImplicit.empty() &&
2971 "No clauses are allowed for 'omp taskyield' directive");
2972 assert(AStmt == nullptr &&
2973 "No associated statement allowed for 'omp taskyield' directive");
2974 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2977 assert(ClausesWithImplicit.empty() &&
2978 "No clauses are allowed for 'omp barrier' directive");
2979 assert(AStmt == nullptr &&
2980 "No associated statement allowed for 'omp barrier' directive");
2981 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2984 assert(ClausesWithImplicit.empty() &&
2985 "No clauses are allowed for 'omp taskwait' directive");
2986 assert(AStmt == nullptr &&
2987 "No associated statement allowed for 'omp taskwait' directive");
2988 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2990 case OMPD_taskgroup:
2991 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2995 assert(AStmt == nullptr &&
2996 "No associated statement allowed for 'omp flush' directive");
2997 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3000 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3004 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3009 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3012 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3014 AllowedNameModifiers.push_back(OMPD_target);
3016 case OMPD_target_parallel:
3017 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3019 AllowedNameModifiers.push_back(OMPD_target);
3020 AllowedNameModifiers.push_back(OMPD_parallel);
3022 case OMPD_target_parallel_for:
3023 Res = ActOnOpenMPTargetParallelForDirective(
3024 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3025 AllowedNameModifiers.push_back(OMPD_target);
3026 AllowedNameModifiers.push_back(OMPD_parallel);
3028 case OMPD_cancellation_point:
3029 assert(ClausesWithImplicit.empty() &&
3030 "No clauses are allowed for 'omp cancellation point' directive");
3031 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3032 "cancellation point' directive");
3033 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3036 assert(AStmt == nullptr &&
3037 "No associated statement allowed for 'omp cancel' directive");
3038 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3040 AllowedNameModifiers.push_back(OMPD_cancel);
3042 case OMPD_target_data:
3043 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3045 AllowedNameModifiers.push_back(OMPD_target_data);
3047 case OMPD_target_enter_data:
3048 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3050 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3052 case OMPD_target_exit_data:
3053 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3055 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3058 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3059 EndLoc, VarsWithInheritedDSA);
3060 AllowedNameModifiers.push_back(OMPD_taskloop);
3062 case OMPD_taskloop_simd:
3063 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3064 EndLoc, VarsWithInheritedDSA);
3065 AllowedNameModifiers.push_back(OMPD_taskloop);
3067 case OMPD_distribute:
3068 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3069 EndLoc, VarsWithInheritedDSA);
3071 case OMPD_target_update:
3072 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3074 AllowedNameModifiers.push_back(OMPD_target_update);
3076 case OMPD_distribute_parallel_for:
3077 Res = ActOnOpenMPDistributeParallelForDirective(
3078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3079 AllowedNameModifiers.push_back(OMPD_parallel);
3081 case OMPD_distribute_parallel_for_simd:
3082 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084 AllowedNameModifiers.push_back(OMPD_parallel);
3086 case OMPD_distribute_simd:
3087 Res = ActOnOpenMPDistributeSimdDirective(
3088 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3090 case OMPD_target_parallel_for_simd:
3091 Res = ActOnOpenMPTargetParallelForSimdDirective(
3092 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3093 AllowedNameModifiers.push_back(OMPD_target);
3094 AllowedNameModifiers.push_back(OMPD_parallel);
3096 case OMPD_target_simd:
3097 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3098 EndLoc, VarsWithInheritedDSA);
3099 AllowedNameModifiers.push_back(OMPD_target);
3101 case OMPD_teams_distribute:
3102 Res = ActOnOpenMPTeamsDistributeDirective(
3103 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3105 case OMPD_teams_distribute_simd:
3106 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3107 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3109 case OMPD_teams_distribute_parallel_for_simd:
3110 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3112 AllowedNameModifiers.push_back(OMPD_parallel);
3114 case OMPD_teams_distribute_parallel_for:
3115 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3116 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3117 AllowedNameModifiers.push_back(OMPD_parallel);
3119 case OMPD_target_teams:
3120 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3122 AllowedNameModifiers.push_back(OMPD_target);
3124 case OMPD_target_teams_distribute:
3125 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3126 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3127 AllowedNameModifiers.push_back(OMPD_target);
3129 case OMPD_target_teams_distribute_parallel_for:
3130 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3131 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3132 AllowedNameModifiers.push_back(OMPD_target);
3133 AllowedNameModifiers.push_back(OMPD_parallel);
3135 case OMPD_target_teams_distribute_parallel_for_simd:
3136 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3137 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3138 AllowedNameModifiers.push_back(OMPD_target);
3139 AllowedNameModifiers.push_back(OMPD_parallel);
3141 case OMPD_target_teams_distribute_simd:
3142 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3143 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3144 AllowedNameModifiers.push_back(OMPD_target);
3146 case OMPD_declare_target:
3147 case OMPD_end_declare_target:
3148 case OMPD_threadprivate:
3149 case OMPD_declare_reduction:
3150 case OMPD_declare_simd:
3151 llvm_unreachable("OpenMP Directive is not allowed");
3153 llvm_unreachable("Unknown OpenMP directive");
3156 for (auto P : VarsWithInheritedDSA) {
3157 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3158 << P.first << P.second->getSourceRange();
3160 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3162 if (!AllowedNameModifiers.empty())
3163 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3171 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3172 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3173 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3174 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3175 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3176 assert(Aligneds.size() == Alignments.size());
3177 assert(Linears.size() == LinModifiers.size());
3178 assert(Linears.size() == Steps.size());
3179 if (!DG || DG.get().isNull())
3180 return DeclGroupPtrTy();
3182 if (!DG.get().isSingleDecl()) {
3183 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3186 auto *ADecl = DG.get().getSingleDecl();
3187 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3188 ADecl = FTD->getTemplatedDecl();
3190 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3192 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3193 return DeclGroupPtrTy();
3196 // OpenMP [2.8.2, declare simd construct, Description]
3197 // The parameter of the simdlen clause must be a constant positive integer
3201 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3202 // OpenMP [2.8.2, declare simd construct, Description]
3203 // The special this pointer can be used as if was one of the arguments to the
3204 // function in any of the linear, aligned, or uniform clauses.
3205 // The uniform clause declares one or more arguments to have an invariant
3206 // value for all concurrent invocations of the function in the execution of a
3207 // single SIMD loop.
3208 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3209 Expr *UniformedLinearThis = nullptr;
3210 for (auto *E : Uniforms) {
3211 E = E->IgnoreParenImpCasts();
3212 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3213 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3214 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3215 FD->getParamDecl(PVD->getFunctionScopeIndex())
3216 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3217 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3220 if (isa<CXXThisExpr>(E)) {
3221 UniformedLinearThis = E;
3224 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3225 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3227 // OpenMP [2.8.2, declare simd construct, Description]
3228 // The aligned clause declares that the object to which each list item points
3229 // is aligned to the number of bytes expressed in the optional parameter of
3230 // the aligned clause.
3231 // The special this pointer can be used as if was one of the arguments to the
3232 // function in any of the linear, aligned, or uniform clauses.
3233 // The type of list items appearing in the aligned clause must be array,
3234 // pointer, reference to array, or reference to pointer.
3235 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3236 Expr *AlignedThis = nullptr;
3237 for (auto *E : Aligneds) {
3238 E = E->IgnoreParenImpCasts();
3239 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3240 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3241 auto *CanonPVD = PVD->getCanonicalDecl();
3242 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3243 FD->getParamDecl(PVD->getFunctionScopeIndex())
3244 ->getCanonicalDecl() == CanonPVD) {
3245 // OpenMP [2.8.1, simd construct, Restrictions]
3246 // A list-item cannot appear in more than one aligned clause.
3247 if (AlignedArgs.count(CanonPVD) > 0) {
3248 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3249 << 1 << E->getSourceRange();
3250 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3251 diag::note_omp_explicit_dsa)
3252 << getOpenMPClauseName(OMPC_aligned);
3255 AlignedArgs[CanonPVD] = E;
3256 QualType QTy = PVD->getType()
3257 .getNonReferenceType()
3258 .getUnqualifiedType()
3259 .getCanonicalType();
3260 const Type *Ty = QTy.getTypePtrOrNull();
3261 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3262 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3263 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3264 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3269 if (isa<CXXThisExpr>(E)) {
3271 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3272 << 2 << E->getSourceRange();
3273 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3274 << getOpenMPClauseName(OMPC_aligned);
3279 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3280 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3282 // The optional parameter of the aligned clause, alignment, must be a constant
3283 // positive integer expression. If no optional parameter is specified,
3284 // implementation-defined default alignments for SIMD instructions on the
3285 // target platforms are assumed.
3286 SmallVector<Expr *, 4> NewAligns;
3287 for (auto *E : Alignments) {
3290 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3291 NewAligns.push_back(Align.get());
3293 // OpenMP [2.8.2, declare simd construct, Description]
3294 // The linear clause declares one or more list items to be private to a SIMD
3295 // lane and to have a linear relationship with respect to the iteration space
3297 // The special this pointer can be used as if was one of the arguments to the
3298 // function in any of the linear, aligned, or uniform clauses.
3299 // When a linear-step expression is specified in a linear clause it must be
3300 // either a constant integer expression or an integer-typed parameter that is
3301 // specified in a uniform clause on the directive.
3302 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3303 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3304 auto MI = LinModifiers.begin();
3305 for (auto *E : Linears) {
3306 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3308 E = E->IgnoreParenImpCasts();
3309 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3310 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3311 auto *CanonPVD = PVD->getCanonicalDecl();
3312 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3313 FD->getParamDecl(PVD->getFunctionScopeIndex())
3314 ->getCanonicalDecl() == CanonPVD) {
3315 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3316 // A list-item cannot appear in more than one linear clause.
3317 if (LinearArgs.count(CanonPVD) > 0) {
3318 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3319 << getOpenMPClauseName(OMPC_linear)
3320 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3321 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3322 diag::note_omp_explicit_dsa)
3323 << getOpenMPClauseName(OMPC_linear);
3326 // Each argument can appear in at most one uniform or linear clause.
3327 if (UniformedArgs.count(CanonPVD) > 0) {
3328 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3329 << getOpenMPClauseName(OMPC_linear)
3330 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3331 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3332 diag::note_omp_explicit_dsa)
3333 << getOpenMPClauseName(OMPC_uniform);
3336 LinearArgs[CanonPVD] = E;
3337 if (E->isValueDependent() || E->isTypeDependent() ||
3338 E->isInstantiationDependent() ||
3339 E->containsUnexpandedParameterPack())
3341 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3342 PVD->getOriginalType());
3346 if (isa<CXXThisExpr>(E)) {
3347 if (UniformedLinearThis) {
3348 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3349 << getOpenMPClauseName(OMPC_linear)
3350 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3351 << E->getSourceRange();
3352 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3353 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3357 UniformedLinearThis = E;
3358 if (E->isValueDependent() || E->isTypeDependent() ||
3359 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3361 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3365 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3366 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3368 Expr *Step = nullptr;
3369 Expr *NewStep = nullptr;
3370 SmallVector<Expr *, 4> NewSteps;
3371 for (auto *E : Steps) {
3372 // Skip the same step expression, it was checked already.
3373 if (Step == E || !E) {
3374 NewSteps.push_back(E ? NewStep : nullptr);
3378 if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3379 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3380 auto *CanonPVD = PVD->getCanonicalDecl();
3381 if (UniformedArgs.count(CanonPVD) == 0) {
3382 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3383 << Step->getSourceRange();
3384 } else if (E->isValueDependent() || E->isTypeDependent() ||
3385 E->isInstantiationDependent() ||
3386 E->containsUnexpandedParameterPack() ||
3387 CanonPVD->getType()->hasIntegerRepresentation())
3388 NewSteps.push_back(Step);
3390 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3391 << Step->getSourceRange();
3396 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3397 !Step->isInstantiationDependent() &&
3398 !Step->containsUnexpandedParameterPack()) {
3399 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3402 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3404 NewSteps.push_back(NewStep);
3406 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3407 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3408 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3409 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3410 const_cast<Expr **>(Linears.data()), Linears.size(),
3411 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3412 NewSteps.data(), NewSteps.size(), SR);
3413 ADecl->addAttr(NewAttr);
3414 return ConvertDeclToDeclGroup(ADecl);
3417 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3419 SourceLocation StartLoc,
3420 SourceLocation EndLoc) {
3424 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3425 // 1.2.2 OpenMP Language Terminology
3426 // Structured block - An executable statement with a single entry at the
3427 // top and a single exit at the bottom.
3428 // The point of exit cannot be a branch out of the structured block.
3429 // longjmp() and throw() must not violate the entry/exit criteria.
3430 CS->getCapturedDecl()->setNothrow();
3432 getCurFunction()->setHasBranchProtectedScope();
3434 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3435 DSAStack->isCancelRegion());
3439 /// \brief Helper class for checking canonical form of the OpenMP loops and
3440 /// extracting iteration space of each loop in the loop nest, that will be used
3441 /// for IR generation.
3442 class OpenMPIterationSpaceChecker {
3443 /// \brief Reference to Sema.
3445 /// \brief A location for diagnostics (when there is no some better location).
3446 SourceLocation DefaultLoc;
3447 /// \brief A location for diagnostics (when increment is not compatible).
3448 SourceLocation ConditionLoc;
3449 /// \brief A source location for referring to loop init later.
3450 SourceRange InitSrcRange;
3451 /// \brief A source location for referring to condition later.
3452 SourceRange ConditionSrcRange;
3453 /// \brief A source location for referring to increment later.
3454 SourceRange IncrementSrcRange;
3455 /// \brief Loop variable.
3456 ValueDecl *LCDecl = nullptr;
3457 /// \brief Reference to loop variable.
3458 Expr *LCRef = nullptr;
3459 /// \brief Lower bound (initializer for the var).
3461 /// \brief Upper bound.
3463 /// \brief Loop step (increment).
3464 Expr *Step = nullptr;
3465 /// \brief This flag is true when condition is one of:
3470 bool TestIsLessOp = false;
3471 /// \brief This flag is true when condition is strict ( < or > ).
3472 bool TestIsStrictOp = false;
3473 /// \brief This flag is true when step is subtracted on each iteration.
3474 bool SubtractStep = false;
3477 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3478 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3479 /// \brief Check init-expr for canonical loop form and save loop counter
3480 /// variable - #Var and its initialization value - #LB.
3481 bool CheckInit(Stmt *S, bool EmitDiags = true);
3482 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3483 /// for less/greater and for strict/non-strict comparison.
3484 bool CheckCond(Expr *S);
3485 /// \brief Check incr-expr for canonical loop form and return true if it
3486 /// does not conform, otherwise save loop step (#Step).
3487 bool CheckInc(Expr *S);
3488 /// \brief Return the loop counter variable.
3489 ValueDecl *GetLoopDecl() const { return LCDecl; }
3490 /// \brief Return the reference expression to loop counter variable.
3491 Expr *GetLoopDeclRefExpr() const { return LCRef; }
3492 /// \brief Source range of the loop init.
3493 SourceRange GetInitSrcRange() const { return InitSrcRange; }
3494 /// \brief Source range of the loop condition.
3495 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3496 /// \brief Source range of the loop increment.
3497 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3498 /// \brief True if the step should be subtracted.
3499 bool ShouldSubtractStep() const { return SubtractStep; }
3500 /// \brief Build the expression to calculate the number of iterations.
3502 BuildNumIterations(Scope *S, const bool LimitedType,
3503 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3504 /// \brief Build the precondition expression for the loops.
3505 Expr *BuildPreCond(Scope *S, Expr *Cond,
3506 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3507 /// \brief Build reference expression to the counter be used for codegen.
3508 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3509 DSAStackTy &DSA) const;
3510 /// \brief Build reference expression to the private counter be used for
3512 Expr *BuildPrivateCounterVar() const;
3513 /// \brief Build initialization of the counter be used for codegen.
3514 Expr *BuildCounterInit() const;
3515 /// \brief Build step of the counter be used for codegen.
3516 Expr *BuildCounterStep() const;
3517 /// \brief Return true if any expression is dependent.
3518 bool Dependent() const;
3521 /// \brief Check the right-hand side of an assignment in the increment
3523 bool CheckIncRHS(Expr *RHS);
3524 /// \brief Helper to set loop counter variable and its initializer.
3525 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3526 /// \brief Helper to set upper bound.
3527 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3529 /// \brief Helper to set loop increment.
3530 bool SetStep(Expr *NewStep, bool Subtract);
3533 bool OpenMPIterationSpaceChecker::Dependent() const {
3535 assert(!LB && !UB && !Step);
3538 return LCDecl->getType()->isDependentType() ||
3539 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3540 (Step && Step->isValueDependent());
3543 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3546 // State consistency checking to ensure correct usage.
3547 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3548 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3549 if (!NewLCDecl || !NewLB)
3551 LCDecl = getCanonicalDecl(NewLCDecl);
3552 LCRef = NewLCRefExpr;
3553 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3554 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3555 if ((Ctor->isCopyOrMoveConstructor() ||
3556 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3557 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3558 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3563 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3564 SourceRange SR, SourceLocation SL) {
3565 // State consistency checking to ensure correct usage.
3566 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3567 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3571 TestIsLessOp = LessOp;
3572 TestIsStrictOp = StrictOp;
3573 ConditionSrcRange = SR;
3578 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3579 // State consistency checking to ensure correct usage.
3580 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3583 if (!NewStep->isValueDependent()) {
3584 // Check that the step is integer expression.
3585 SourceLocation StepLoc = NewStep->getLocStart();
3586 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3587 StepLoc, getExprAsWritten(NewStep));
3588 if (Val.isInvalid())
3590 NewStep = Val.get();
3592 // OpenMP [2.6, Canonical Loop Form, Restrictions]
3593 // If test-expr is of form var relational-op b and relational-op is < or
3594 // <= then incr-expr must cause var to increase on each iteration of the
3595 // loop. If test-expr is of form var relational-op b and relational-op is
3596 // > or >= then incr-expr must cause var to decrease on each iteration of
3598 // If test-expr is of form b relational-op var and relational-op is < or
3599 // <= then incr-expr must cause var to decrease on each iteration of the
3600 // loop. If test-expr is of form b relational-op var and relational-op is
3601 // > or >= then incr-expr must cause var to increase on each iteration of
3603 llvm::APSInt Result;
3604 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3605 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3607 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3609 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3610 bool IsConstZero = IsConstant && !Result.getBoolValue();
3611 if (UB && (IsConstZero ||
3612 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3613 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3614 SemaRef.Diag(NewStep->getExprLoc(),
3615 diag::err_omp_loop_incr_not_compatible)
3616 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3617 SemaRef.Diag(ConditionLoc,
3618 diag::note_omp_loop_cond_requres_compatible_incr)
3619 << TestIsLessOp << ConditionSrcRange;
3622 if (TestIsLessOp == Subtract) {
3624 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3626 Subtract = !Subtract;
3631 SubtractStep = Subtract;
3635 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3636 // Check init-expr for canonical loop form and save loop counter
3637 // variable - #Var and its initialization value - #LB.
3638 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3640 // integer-type var = lb
3641 // random-access-iterator-type var = lb
3642 // pointer-type var = lb
3646 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3650 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3651 if (!ExprTemp->cleanupsHaveSideEffects())
3652 S = ExprTemp->getSubExpr();
3654 InitSrcRange = S->getSourceRange();
3655 if (Expr *E = dyn_cast<Expr>(S))
3656 S = E->IgnoreParens();
3657 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3658 if (BO->getOpcode() == BO_Assign) {
3659 auto *LHS = BO->getLHS()->IgnoreParens();
3660 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3661 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3662 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3663 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3664 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3666 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3667 if (ME->isArrow() &&
3668 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3669 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3672 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3673 if (DS->isSingleDecl()) {
3674 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3675 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3676 // Accept non-canonical init form here but emit ext. warning.
3677 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3678 SemaRef.Diag(S->getLocStart(),
3679 diag::ext_omp_loop_not_canonical_init)
3680 << S->getSourceRange();
3681 return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3685 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3686 if (CE->getOperator() == OO_Equal) {
3687 auto *LHS = CE->getArg(0);
3688 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3689 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3690 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3691 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3692 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3695 if (ME->isArrow() &&
3696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3697 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3702 if (Dependent() || SemaRef.CurContext->isDependentContext())
3705 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3706 << S->getSourceRange();
3711 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3712 /// variable (which may be the loop variable) if possible.
3713 static const ValueDecl *GetInitLCDecl(Expr *E) {
3716 E = getExprAsWritten(E);
3717 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3718 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3719 if ((Ctor->isCopyOrMoveConstructor() ||
3720 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3721 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3722 E = CE->getArg(0)->IgnoreParenImpCasts();
3723 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3724 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3725 return getCanonicalDecl(VD);
3727 if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3728 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3729 return getCanonicalDecl(ME->getMemberDecl());
3733 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3734 // Check test-expr for canonical form, save upper-bound UB, flags for
3735 // less/greater and for strict/non-strict comparison.
3736 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3737 // var relational-op b
3738 // b relational-op var
3741 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3744 S = getExprAsWritten(S);
3745 SourceLocation CondLoc = S->getLocStart();
3746 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3747 if (BO->isRelationalOp()) {
3748 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3749 return SetUB(BO->getRHS(),
3750 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3751 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3752 BO->getSourceRange(), BO->getOperatorLoc());
3753 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3754 return SetUB(BO->getLHS(),
3755 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3756 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3757 BO->getSourceRange(), BO->getOperatorLoc());
3759 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3760 if (CE->getNumArgs() == 2) {
3761 auto Op = CE->getOperator();
3764 case OO_GreaterEqual:
3767 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3768 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3769 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3770 CE->getOperatorLoc());
3771 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3772 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3773 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3774 CE->getOperatorLoc());
3781 if (Dependent() || SemaRef.CurContext->isDependentContext())
3783 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3784 << S->getSourceRange() << LCDecl;
3788 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3789 // RHS of canonical loop form increment can be:
3794 RHS = RHS->IgnoreParenImpCasts();
3795 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3796 if (BO->isAdditiveOp()) {
3797 bool IsAdd = BO->getOpcode() == BO_Add;
3798 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3799 return SetStep(BO->getRHS(), !IsAdd);
3800 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3801 return SetStep(BO->getLHS(), false);
3803 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3804 bool IsAdd = CE->getOperator() == OO_Plus;
3805 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3806 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3807 return SetStep(CE->getArg(1), !IsAdd);
3808 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3809 return SetStep(CE->getArg(0), false);
3812 if (Dependent() || SemaRef.CurContext->isDependentContext())
3814 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3815 << RHS->getSourceRange() << LCDecl;
3819 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3820 // Check incr-expr for canonical loop form and return true if it
3821 // does not conform.
3822 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3834 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3837 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3838 if (!ExprTemp->cleanupsHaveSideEffects())
3839 S = ExprTemp->getSubExpr();
3841 IncrementSrcRange = S->getSourceRange();
3842 S = S->IgnoreParens();
3843 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3844 if (UO->isIncrementDecrementOp() &&
3845 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3846 return SetStep(SemaRef
3847 .ActOnIntegerConstant(UO->getLocStart(),
3848 (UO->isDecrementOp() ? -1 : 1))
3851 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3852 switch (BO->getOpcode()) {
3855 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3856 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3859 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3860 return CheckIncRHS(BO->getRHS());
3865 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3866 switch (CE->getOperator()) {
3869 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3870 return SetStep(SemaRef
3871 .ActOnIntegerConstant(
3873 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3879 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3880 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3883 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3884 return CheckIncRHS(CE->getArg(1));
3890 if (Dependent() || SemaRef.CurContext->isDependentContext())
3892 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3893 << S->getSourceRange() << LCDecl;
3898 tryBuildCapture(Sema &SemaRef, Expr *Capture,
3899 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3900 if (SemaRef.CurContext->isDependentContext())
3901 return ExprResult(Capture);
3902 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
3903 return SemaRef.PerformImplicitConversion(
3904 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
3905 /*AllowExplicit=*/true);
3906 auto I = Captures.find(Capture);
3907 if (I != Captures.end())
3908 return buildCapture(SemaRef, Capture, I->second);
3909 DeclRefExpr *Ref = nullptr;
3910 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
3911 Captures[Capture] = Ref;
3915 /// \brief Build the expression to calculate the number of iterations.
3916 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3917 Scope *S, const bool LimitedType,
3918 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
3920 auto VarType = LCDecl->getType().getNonReferenceType();
3921 if (VarType->isIntegerType() || VarType->isPointerType() ||
3922 SemaRef.getLangOpts().CPlusPlus) {
3924 auto *UBExpr = TestIsLessOp ? UB : LB;
3925 auto *LBExpr = TestIsLessOp ? LB : UB;
3926 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3927 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3928 if (!Upper || !Lower)
3931 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3933 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3934 // BuildBinOp already emitted error, this one is to point user to upper
3935 // and lower bound, and to tell what is passed to 'operator-'.
3936 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3937 << Upper->getSourceRange() << Lower->getSourceRange();
3942 if (!Diff.isUsable())
3945 // Upper - Lower [- 1]
3947 Diff = SemaRef.BuildBinOp(
3948 S, DefaultLoc, BO_Sub, Diff.get(),
3949 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3950 if (!Diff.isUsable())
3953 // Upper - Lower [- 1] + Step
3954 auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
3955 if (!NewStep.isUsable())
3957 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3958 if (!Diff.isUsable())
3961 // Parentheses (for dumping/debugging purposes only).
3962 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3963 if (!Diff.isUsable())
3966 // (Upper - Lower [- 1] + Step) / Step
3967 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3968 if (!Diff.isUsable())
3971 // OpenMP runtime requires 32-bit or 64-bit loop variables.
3972 QualType Type = Diff.get()->getType();
3973 auto &C = SemaRef.Context;
3974 bool UseVarType = VarType->hasIntegerRepresentation() &&
3975 C.getTypeSize(Type) > C.getTypeSize(VarType);
3976 if (!Type->isIntegerType() || UseVarType) {
3978 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3979 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3980 : Type->hasSignedIntegerRepresentation();
3981 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3982 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3983 Diff = SemaRef.PerformImplicitConversion(
3984 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3985 if (!Diff.isUsable())
3990 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3991 if (NewSize != C.getTypeSize(Type)) {
3992 if (NewSize < C.getTypeSize(Type)) {
3993 assert(NewSize == 64 && "incorrect loop var size");
3994 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3995 << InitSrcRange << ConditionSrcRange;
3997 QualType NewType = C.getIntTypeForBitwidth(
3998 NewSize, Type->hasSignedIntegerRepresentation() ||
3999 C.getTypeSize(Type) < NewSize);
4000 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4001 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4002 Sema::AA_Converting, true);
4003 if (!Diff.isUsable())
4012 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4013 Scope *S, Expr *Cond,
4014 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4015 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4016 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4017 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4019 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4020 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4021 if (!NewLB.isUsable() || !NewUB.isUsable())
4024 auto CondExpr = SemaRef.BuildBinOp(
4025 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4026 : (TestIsStrictOp ? BO_GT : BO_GE),
4027 NewLB.get(), NewUB.get());
4028 if (CondExpr.isUsable()) {
4029 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4030 SemaRef.Context.BoolTy))
4031 CondExpr = SemaRef.PerformImplicitConversion(
4032 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4033 /*AllowExplicit=*/true);
4035 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4036 // Otherwise use original loop conditon and evaluate it in runtime.
4037 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4040 /// \brief Build reference expression to the counter be used for codegen.
4041 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4042 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4043 auto *VD = dyn_cast<VarDecl>(LCDecl);
4045 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4046 auto *Ref = buildDeclRefExpr(
4047 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4048 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4049 // If the loop control decl is explicitly marked as private, do not mark it
4050 // as captured again.
4051 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4052 Captures.insert(std::make_pair(LCRef, Ref));
4055 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4059 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4060 if (LCDecl && !LCDecl->isInvalidDecl()) {
4061 auto Type = LCDecl->getType().getNonReferenceType();
4063 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4064 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4065 if (PrivateVar->isInvalidDecl())
4067 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4072 /// \brief Build initialization of the counter to be used for codegen.
4073 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
4075 /// \brief Build step of the counter be used for codegen.
4076 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4078 /// \brief Iteration space of a single for loop.
4079 struct LoopIterationSpace final {
4080 /// \brief Condition of the loop.
4081 Expr *PreCond = nullptr;
4082 /// \brief This expression calculates the number of iterations in the loop.
4083 /// It is always possible to calculate it before starting the loop.
4084 Expr *NumIterations = nullptr;
4085 /// \brief The loop counter variable.
4086 Expr *CounterVar = nullptr;
4087 /// \brief Private loop counter variable.
4088 Expr *PrivateCounterVar = nullptr;
4089 /// \brief This is initializer for the initial value of #CounterVar.
4090 Expr *CounterInit = nullptr;
4091 /// \brief This is step for the #CounterVar used to generate its update:
4092 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4093 Expr *CounterStep = nullptr;
4094 /// \brief Should step be subtracted?
4095 bool Subtract = false;
4096 /// \brief Source range of the loop init.
4097 SourceRange InitSrcRange;
4098 /// \brief Source range of the loop condition.
4099 SourceRange CondSrcRange;
4100 /// \brief Source range of the loop increment.
4101 SourceRange IncSrcRange;
4106 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4107 assert(getLangOpts().OpenMP && "OpenMP is not active.");
4108 assert(Init && "Expected loop in canonical form.");
4109 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4110 if (AssociatedLoops > 0 &&
4111 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4112 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4113 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4114 if (auto *D = ISC.GetLoopDecl()) {
4115 auto *VD = dyn_cast<VarDecl>(D);
4117 if (auto *Private = IsOpenMPCapturedDecl(D))
4120 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4121 /*WithInit=*/false);
4122 VD = cast<VarDecl>(Ref->getDecl());
4125 DSAStack->addLoopControlVariable(D, VD);
4128 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4132 /// \brief Called on a for stmt to check and extract its iteration space
4133 /// for further processing (such as collapsing).
4134 static bool CheckOpenMPIterationSpace(
4135 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4136 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4137 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4138 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4139 LoopIterationSpace &ResultIterSpace,
4140 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4141 // OpenMP [2.6, Canonical Loop Form]
4142 // for (init-expr; test-expr; incr-expr) structured-block
4143 auto *For = dyn_cast_or_null<ForStmt>(S);
4145 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4146 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4147 << getOpenMPDirectiveName(DKind) << NestedLoopCount
4148 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4149 if (NestedLoopCount > 1) {
4150 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4151 SemaRef.Diag(DSA.getConstructLoc(),
4152 diag::note_omp_collapse_ordered_expr)
4153 << 2 << CollapseLoopCountExpr->getSourceRange()
4154 << OrderedLoopCountExpr->getSourceRange();
4155 else if (CollapseLoopCountExpr)
4156 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4157 diag::note_omp_collapse_ordered_expr)
4158 << 0 << CollapseLoopCountExpr->getSourceRange();
4160 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4161 diag::note_omp_collapse_ordered_expr)
4162 << 1 << OrderedLoopCountExpr->getSourceRange();
4166 assert(For->getBody());
4168 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4171 auto Init = For->getInit();
4172 if (ISC.CheckInit(Init))
4175 bool HasErrors = false;
4177 // Check loop variable's type.
4178 if (auto *LCDecl = ISC.GetLoopDecl()) {
4179 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4181 // OpenMP [2.6, Canonical Loop Form]
4182 // Var is one of the following:
4183 // A variable of signed or unsigned integer type.
4184 // For C++, a variable of a random access iterator type.
4185 // For C, a variable of a pointer type.
4186 auto VarType = LCDecl->getType().getNonReferenceType();
4187 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4188 !VarType->isPointerType() &&
4189 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4190 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4191 << SemaRef.getLangOpts().CPlusPlus;
4195 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4197 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4198 // parallel for construct is (are) private.
4199 // The loop iteration variable in the associated for-loop of a simd
4200 // construct with just one associated for-loop is linear with a
4201 // constant-linear-step that is the increment of the associated for-loop.
4202 // Exclude loop var from the list of variables with implicitly defined data
4203 // sharing attributes.
4204 VarsWithImplicitDSA.erase(LCDecl);
4206 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4207 // in a Construct, C/C++].
4208 // The loop iteration variable in the associated for-loop of a simd
4209 // construct with just one associated for-loop may be listed in a linear
4210 // clause with a constant-linear-step that is the increment of the
4211 // associated for-loop.
4212 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4213 // parallel for construct may be listed in a private or lastprivate clause.
4214 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4215 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4216 // declared in the loop and it is predetermined as a private.
4217 auto PredeterminedCKind =
4218 isOpenMPSimdDirective(DKind)
4219 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4221 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4222 DVar.CKind != PredeterminedCKind) ||
4223 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4224 isOpenMPDistributeDirective(DKind)) &&
4225 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4226 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4227 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4228 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4229 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4230 << getOpenMPClauseName(PredeterminedCKind);
4231 if (DVar.RefExpr == nullptr)
4232 DVar.CKind = PredeterminedCKind;
4233 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4235 } else if (LoopDeclRefExpr != nullptr) {
4236 // Make the loop iteration variable private (for worksharing constructs),
4237 // linear (for simd directives with the only one associated loop) or
4238 // lastprivate (for simd directives with several collapsed or ordered
4240 if (DVar.CKind == OMPC_unknown)
4241 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4242 [](OpenMPDirectiveKind) -> bool { return true; },
4243 /*FromParent=*/false);
4244 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4247 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4250 HasErrors |= ISC.CheckCond(For->getCond());
4253 HasErrors |= ISC.CheckInc(For->getInc());
4256 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4259 // Build the loop's iteration space representation.
4260 ResultIterSpace.PreCond =
4261 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4262 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4264 (isOpenMPWorksharingDirective(DKind) ||
4265 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4267 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4268 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4269 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4270 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4271 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4272 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4273 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4274 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4276 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4277 ResultIterSpace.NumIterations == nullptr ||
4278 ResultIterSpace.CounterVar == nullptr ||
4279 ResultIterSpace.PrivateCounterVar == nullptr ||
4280 ResultIterSpace.CounterInit == nullptr ||
4281 ResultIterSpace.CounterStep == nullptr);
4286 /// \brief Build 'VarRef = Start.
4288 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4290 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4291 // Build 'VarRef = Start.
4292 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4293 if (!NewStart.isUsable())
4295 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4296 VarRef.get()->getType())) {
4297 NewStart = SemaRef.PerformImplicitConversion(
4298 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4299 /*AllowExplicit=*/true);
4300 if (!NewStart.isUsable())
4305 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4309 /// \brief Build 'VarRef = Start + Iter * Step'.
4311 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc,
4312 ExprResult VarRef, ExprResult Start, ExprResult Iter,
4313 ExprResult Step, bool Subtract,
4314 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4315 // Add parentheses (for debugging purposes only).
4316 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4317 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4321 ExprResult NewStep = Step;
4323 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4324 if (NewStep.isInvalid())
4327 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4328 if (!Update.isUsable())
4331 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4332 // 'VarRef = Start (+|-) Iter * Step'.
4333 ExprResult NewStart = Start;
4335 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4336 if (NewStart.isInvalid())
4339 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4340 ExprResult SavedUpdate = Update;
4341 ExprResult UpdateVal;
4342 if (VarRef.get()->getType()->isOverloadableType() ||
4343 NewStart.get()->getType()->isOverloadableType() ||
4344 Update.get()->getType()->isOverloadableType()) {
4345 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4346 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4348 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4349 if (Update.isUsable()) {
4351 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4352 VarRef.get(), SavedUpdate.get());
4353 if (UpdateVal.isUsable()) {
4354 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4358 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4361 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4362 if (!Update.isUsable() || !UpdateVal.isUsable()) {
4363 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4364 NewStart.get(), SavedUpdate.get());
4365 if (!Update.isUsable())
4368 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4369 VarRef.get()->getType())) {
4370 Update = SemaRef.PerformImplicitConversion(
4371 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4372 if (!Update.isUsable())
4376 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4381 /// \brief Convert integer expression \a E to make it have at least \a Bits
4383 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4386 auto &C = SemaRef.Context;
4387 QualType OldType = E->getType();
4388 unsigned HasBits = C.getTypeSize(OldType);
4389 if (HasBits >= Bits)
4390 return ExprResult(E);
4391 // OK to convert to signed, because new type has more bits than old.
4392 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4393 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4397 /// \brief Check if the given expression \a E is a constant integer that fits
4398 /// into \a Bits bits.
4399 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4402 llvm::APSInt Result;
4403 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4404 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4408 /// Build preinits statement for the given declarations.
4409 static Stmt *buildPreInits(ASTContext &Context,
4410 MutableArrayRef<Decl *> PreInits) {
4411 if (!PreInits.empty()) {
4412 return new (Context) DeclStmt(
4413 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4414 SourceLocation(), SourceLocation());
4419 /// Build preinits statement for the given declarations.
4421 buildPreInits(ASTContext &Context,
4422 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4423 if (!Captures.empty()) {
4424 SmallVector<Decl *, 16> PreInits;
4425 for (auto &Pair : Captures)
4426 PreInits.push_back(Pair.second->getDecl());
4427 return buildPreInits(Context, PreInits);
4432 /// Build postupdate expression for the given list of postupdates expressions.
4433 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4434 Expr *PostUpdate = nullptr;
4435 if (!PostUpdates.empty()) {
4436 for (auto *E : PostUpdates) {
4437 Expr *ConvE = S.BuildCStyleCastExpr(
4439 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4442 PostUpdate = PostUpdate
4443 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4452 /// \brief Called on a for stmt to check itself and nested loops (if any).
4453 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4454 /// number of collapsed loops otherwise.
4456 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4457 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4459 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4460 OMPLoopDirective::HelperExprs &Built) {
4461 unsigned NestedLoopCount = 1;
4462 if (CollapseLoopCountExpr) {
4463 // Found 'collapse' clause - calculate collapse number.
4464 llvm::APSInt Result;
4465 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4466 NestedLoopCount = Result.getLimitedValue();
4468 if (OrderedLoopCountExpr) {
4469 // Found 'ordered' clause - calculate collapse number.
4470 llvm::APSInt Result;
4471 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4472 if (Result.getLimitedValue() < NestedLoopCount) {
4473 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4474 diag::err_omp_wrong_ordered_loop_count)
4475 << OrderedLoopCountExpr->getSourceRange();
4476 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4477 diag::note_collapse_loop_count)
4478 << CollapseLoopCountExpr->getSourceRange();
4480 NestedLoopCount = Result.getLimitedValue();
4483 // This is helper routine for loop directives (e.g., 'for', 'simd',
4484 // 'for simd', etc.).
4485 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4486 SmallVector<LoopIterationSpace, 4> IterSpaces;
4487 IterSpaces.resize(NestedLoopCount);
4488 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4489 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4490 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4491 NestedLoopCount, CollapseLoopCountExpr,
4492 OrderedLoopCountExpr, VarsWithImplicitDSA,
4493 IterSpaces[Cnt], Captures))
4495 // Move on to the next nested for loop, or to the loop body.
4496 // OpenMP [2.8.1, simd construct, Restrictions]
4497 // All loops associated with the construct must be perfectly nested; that
4498 // is, there must be no intervening code nor any OpenMP directive between
4500 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4503 Built.clear(/* size */ NestedLoopCount);
4505 if (SemaRef.CurContext->isDependentContext())
4506 return NestedLoopCount;
4508 // An example of what is generated for the following code:
4510 // #pragma omp simd collapse(2) ordered(2)
4511 // for (i = 0; i < NI; ++i)
4512 // for (k = 0; k < NK; ++k)
4513 // for (j = J0; j < NJ; j+=2) {
4517 // We generate the code below.
4518 // Note: the loop body may be outlined in CodeGen.
4519 // Note: some counters may be C++ classes, operator- is used to find number of
4520 // iterations and operator+= to calculate counter value.
4521 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4522 // or i64 is currently supported).
4524 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4525 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4526 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4527 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4528 // // similar updates for vars in clauses (e.g. 'linear')
4529 // <loop body (using local i and j)>
4531 // i = NI; // assign final values of counters
4535 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4536 // the iteration counts of the collapsed for loops.
4537 // Precondition tests if there is at least one iteration (all conditions are
4539 auto PreCond = ExprResult(IterSpaces[0].PreCond);
4540 auto N0 = IterSpaces[0].NumIterations;
4541 ExprResult LastIteration32 = WidenIterationCount(
4542 32 /* Bits */, SemaRef
4543 .PerformImplicitConversion(
4544 N0->IgnoreImpCasts(), N0->getType(),
4545 Sema::AA_Converting, /*AllowExplicit=*/true)
4548 ExprResult LastIteration64 = WidenIterationCount(
4549 64 /* Bits */, SemaRef
4550 .PerformImplicitConversion(
4551 N0->IgnoreImpCasts(), N0->getType(),
4552 Sema::AA_Converting, /*AllowExplicit=*/true)
4556 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4557 return NestedLoopCount;
4559 auto &C = SemaRef.Context;
4560 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4562 Scope *CurScope = DSA.getCurScope();
4563 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4564 if (PreCond.isUsable()) {
4566 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4567 PreCond.get(), IterSpaces[Cnt].PreCond);
4569 auto N = IterSpaces[Cnt].NumIterations;
4570 SourceLocation Loc = N->getExprLoc();
4571 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4572 if (LastIteration32.isUsable())
4573 LastIteration32 = SemaRef.BuildBinOp(
4574 CurScope, Loc, BO_Mul, LastIteration32.get(),
4576 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4577 Sema::AA_Converting,
4578 /*AllowExplicit=*/true)
4580 if (LastIteration64.isUsable())
4581 LastIteration64 = SemaRef.BuildBinOp(
4582 CurScope, Loc, BO_Mul, LastIteration64.get(),
4584 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4585 Sema::AA_Converting,
4586 /*AllowExplicit=*/true)
4590 // Choose either the 32-bit or 64-bit version.
4591 ExprResult LastIteration = LastIteration64;
4592 if (LastIteration32.isUsable() &&
4593 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4594 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4597 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4598 LastIteration64.get(), SemaRef)))
4599 LastIteration = LastIteration32;
4600 QualType VType = LastIteration.get()->getType();
4601 QualType RealVType = VType;
4602 QualType StrideVType = VType;
4603 if (isOpenMPTaskLoopDirective(DKind)) {
4605 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4607 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4610 if (!LastIteration.isUsable())
4613 // Save the number of iterations.
4614 ExprResult NumIterations = LastIteration;
4616 LastIteration = SemaRef.BuildBinOp(
4617 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4618 LastIteration.get(),
4619 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4620 if (!LastIteration.isUsable())
4624 // Calculate the last iteration number beforehand instead of doing this on
4625 // each iteration. Do not do this if the number of iterations may be kfold-ed.
4626 llvm::APSInt Result;
4628 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4629 ExprResult CalcLastIteration;
4631 ExprResult SaveRef =
4632 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4633 LastIteration = SaveRef;
4635 // Prepare SaveRef + 1.
4636 NumIterations = SemaRef.BuildBinOp(
4637 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4638 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4639 if (!NumIterations.isUsable())
4643 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4645 // Build variables passed into runtime, necessary for worksharing directives.
4646 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4647 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4648 isOpenMPDistributeDirective(DKind)) {
4649 // Lower bound variable, initialized with zero.
4650 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4651 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4652 SemaRef.AddInitializerToDecl(LBDecl,
4653 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4654 /*DirectInit*/ false);
4656 // Upper bound variable, initialized with last iteration number.
4657 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4658 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4659 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4660 /*DirectInit*/ false);
4662 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4663 // This will be used to implement clause 'lastprivate'.
4664 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4665 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4666 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4667 SemaRef.AddInitializerToDecl(ILDecl,
4668 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4669 /*DirectInit*/ false);
4671 // Stride variable returned by runtime (we initialize it to 1 by default).
4673 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4674 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4675 SemaRef.AddInitializerToDecl(STDecl,
4676 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4677 /*DirectInit*/ false);
4679 // Build expression: UB = min(UB, LastIteration)
4680 // It is necessary for CodeGen of directives with static scheduling.
4681 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4682 UB.get(), LastIteration.get());
4683 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4684 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4685 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4687 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4689 // If we have a combined directive that combines 'distribute', 'for' or
4690 // 'simd' we need to be able to access the bounds of the schedule of the
4691 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4692 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4693 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4695 // Lower bound variable, initialized with zero.
4696 VarDecl *CombLBDecl =
4697 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4698 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4699 SemaRef.AddInitializerToDecl(
4700 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4701 /*DirectInit*/ false);
4703 // Upper bound variable, initialized with last iteration number.
4704 VarDecl *CombUBDecl =
4705 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4706 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4707 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4708 /*DirectInit*/ false);
4710 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4711 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4712 ExprResult CombCondOp =
4713 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4714 LastIteration.get(), CombUB.get());
4715 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4717 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4719 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4720 // We expect to have at least 2 more parameters than the 'parallel'
4721 // directive does - the lower and upper bounds of the previous schedule.
4722 assert(CD->getNumParams() >= 4 &&
4723 "Unexpected number of parameters in loop combined directive");
4725 // Set the proper type for the bounds given what we learned from the
4727 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4728 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4730 // Previous lower and upper bounds are obtained from the region
4733 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4735 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4739 // Build the iteration variable and its initialization before loop.
4741 ExprResult Init, CombInit;
4743 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4744 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4746 (isOpenMPWorksharingDirective(DKind) ||
4747 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4749 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4750 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4751 Init = SemaRef.ActOnFinishFullExpr(Init.get());
4753 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4755 (isOpenMPWorksharingDirective(DKind) ||
4756 isOpenMPTaskLoopDirective(DKind) ||
4757 isOpenMPDistributeDirective(DKind))
4759 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4761 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4762 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4766 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4767 SourceLocation CondLoc;
4769 (isOpenMPWorksharingDirective(DKind) ||
4770 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4771 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4772 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4773 NumIterations.get());
4774 ExprResult CombCond;
4775 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4777 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4779 // Loop increment (IV = IV + 1)
4780 SourceLocation IncLoc;
4782 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4783 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4784 if (!Inc.isUsable())
4786 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4787 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4788 if (!Inc.isUsable())
4791 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4792 // Used for directives with static scheduling.
4793 // In combined construct, add combined version that use CombLB and CombUB
4794 // base variables for the update
4795 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4796 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4797 isOpenMPDistributeDirective(DKind)) {
4799 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4800 if (!NextLB.isUsable())
4804 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4805 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4806 if (!NextLB.isUsable())
4809 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4810 if (!NextUB.isUsable())
4814 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4815 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4816 if (!NextUB.isUsable())
4818 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4820 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4821 if (!NextLB.isUsable())
4824 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4826 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4827 if (!CombNextLB.isUsable())
4831 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4832 if (!CombNextUB.isUsable())
4835 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4837 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4838 if (!CombNextUB.isUsable())
4843 // Create increment expression for distribute loop when combined in a same
4844 // directive with for as IV = IV + ST; ensure upper bound expression based
4845 // on PrevUB instead of NumIterations - used to implement 'for' when found
4846 // in combination with 'distribute', like in 'distribute parallel for'
4847 SourceLocation DistIncLoc;
4848 ExprResult DistCond, DistInc, PrevEUB;
4849 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4850 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4851 assert(DistCond.isUsable() && "distribute cond expr was not built");
4854 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4855 assert(DistInc.isUsable() && "distribute inc expr was not built");
4856 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4858 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4859 assert(DistInc.isUsable() && "distribute inc expr was not built");
4861 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4863 SourceLocation DistEUBLoc;
4864 ExprResult IsUBGreater =
4865 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4866 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4867 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4868 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4870 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4873 // Build updates and final values of the loop counters.
4874 bool HasErrors = false;
4875 Built.Counters.resize(NestedLoopCount);
4876 Built.Inits.resize(NestedLoopCount);
4877 Built.Updates.resize(NestedLoopCount);
4878 Built.Finals.resize(NestedLoopCount);
4879 SmallVector<Expr *, 4> LoopMultipliers;
4882 // Go from inner nested loop to outer.
4883 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4884 LoopIterationSpace &IS = IterSpaces[Cnt];
4885 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4886 // Build: Iter = (IV / Div) % IS.NumIters
4887 // where Div is product of previous iterations' IS.NumIters.
4889 if (Div.isUsable()) {
4891 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4894 assert((Cnt == (int)NestedLoopCount - 1) &&
4895 "unusable div expected on first iteration only");
4898 if (Cnt != 0 && Iter.isUsable())
4899 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4901 if (!Iter.isUsable()) {
4906 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4907 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4908 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
4909 IS.CounterVar->getExprLoc(),
4910 /*RefersToCapture=*/true);
4911 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4912 IS.CounterInit, Captures);
4913 if (!Init.isUsable()) {
4917 ExprResult Update = BuildCounterUpdate(
4918 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4919 IS.CounterStep, IS.Subtract, &Captures);
4920 if (!Update.isUsable()) {
4925 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4926 ExprResult Final = BuildCounterUpdate(
4927 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4928 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4929 if (!Final.isUsable()) {
4934 // Build Div for the next iteration: Div <- Div * IS.NumIters
4937 Div = IS.NumIterations;
4939 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4942 // Add parentheses (for debugging purposes only).
4944 Div = tryBuildCapture(SemaRef, Div.get(), Captures);
4945 if (!Div.isUsable()) {
4949 LoopMultipliers.push_back(Div.get());
4951 if (!Update.isUsable() || !Final.isUsable()) {
4956 Built.Counters[Cnt] = IS.CounterVar;
4957 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4958 Built.Inits[Cnt] = Init.get();
4959 Built.Updates[Cnt] = Update.get();
4960 Built.Finals[Cnt] = Final.get();
4968 Built.IterationVarRef = IV.get();
4969 Built.LastIteration = LastIteration.get();
4970 Built.NumIterations = NumIterations.get();
4971 Built.CalcLastIteration =
4972 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4973 Built.PreCond = PreCond.get();
4974 Built.PreInits = buildPreInits(C, Captures);
4975 Built.Cond = Cond.get();
4976 Built.Init = Init.get();
4977 Built.Inc = Inc.get();
4978 Built.LB = LB.get();
4979 Built.UB = UB.get();
4980 Built.IL = IL.get();
4981 Built.ST = ST.get();
4982 Built.EUB = EUB.get();
4983 Built.NLB = NextLB.get();
4984 Built.NUB = NextUB.get();
4985 Built.PrevLB = PrevLB.get();
4986 Built.PrevUB = PrevUB.get();
4987 Built.DistInc = DistInc.get();
4988 Built.PrevEUB = PrevEUB.get();
4989 Built.DistCombinedFields.LB = CombLB.get();
4990 Built.DistCombinedFields.UB = CombUB.get();
4991 Built.DistCombinedFields.EUB = CombEUB.get();
4992 Built.DistCombinedFields.Init = CombInit.get();
4993 Built.DistCombinedFields.Cond = CombCond.get();
4994 Built.DistCombinedFields.NLB = CombNextLB.get();
4995 Built.DistCombinedFields.NUB = CombNextUB.get();
4997 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
4998 // Fill data for doacross depend clauses.
4999 for (auto Pair : DSA.getDoacrossDependClauses()) {
5000 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5001 Pair.first->setCounterValue(CounterVal);
5003 if (NestedLoopCount != Pair.second.size() ||
5004 NestedLoopCount != LoopMultipliers.size() + 1) {
5005 // Erroneous case - clause has some problems.
5006 Pair.first->setCounterValue(CounterVal);
5009 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5010 auto I = Pair.second.rbegin();
5011 auto IS = IterSpaces.rbegin();
5012 auto ILM = LoopMultipliers.rbegin();
5013 Expr *UpCounterVal = CounterVal;
5014 Expr *Multiplier = nullptr;
5015 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5017 assert(IS->CounterStep);
5018 Expr *NormalizedOffset =
5020 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5021 I->first, IS->CounterStep)
5026 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5027 NormalizedOffset, Multiplier)
5030 assert(I->second == OO_Plus || I->second == OO_Minus);
5031 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5032 UpCounterVal = SemaRef
5033 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5034 UpCounterVal, NormalizedOffset)
5042 Pair.first->setCounterValue(UpCounterVal);
5046 return NestedLoopCount;
5049 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5050 auto CollapseClauses =
5051 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5052 if (CollapseClauses.begin() != CollapseClauses.end())
5053 return (*CollapseClauses.begin())->getNumForLoops();
5057 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5058 auto OrderedClauses =
5059 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5060 if (OrderedClauses.begin() != OrderedClauses.end())
5061 return (*OrderedClauses.begin())->getNumForLoops();
5065 static bool checkSimdlenSafelenSpecified(Sema &S,
5066 const ArrayRef<OMPClause *> Clauses) {
5067 OMPSafelenClause *Safelen = nullptr;
5068 OMPSimdlenClause *Simdlen = nullptr;
5070 for (auto *Clause : Clauses) {
5071 if (Clause->getClauseKind() == OMPC_safelen)
5072 Safelen = cast<OMPSafelenClause>(Clause);
5073 else if (Clause->getClauseKind() == OMPC_simdlen)
5074 Simdlen = cast<OMPSimdlenClause>(Clause);
5075 if (Safelen && Simdlen)
5079 if (Simdlen && Safelen) {
5080 llvm::APSInt SimdlenRes, SafelenRes;
5081 auto SimdlenLength = Simdlen->getSimdlen();
5082 auto SafelenLength = Safelen->getSafelen();
5083 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5084 SimdlenLength->isInstantiationDependent() ||
5085 SimdlenLength->containsUnexpandedParameterPack())
5087 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5088 SafelenLength->isInstantiationDependent() ||
5089 SafelenLength->containsUnexpandedParameterPack())
5091 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5092 SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5093 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5094 // If both simdlen and safelen clauses are specified, the value of the
5095 // simdlen parameter must be less than or equal to the value of the safelen
5097 if (SimdlenRes > SafelenRes) {
5098 S.Diag(SimdlenLength->getExprLoc(),
5099 diag::err_omp_wrong_simdlen_safelen_values)
5100 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5107 StmtResult Sema::ActOnOpenMPSimdDirective(
5108 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5109 SourceLocation EndLoc,
5110 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5114 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5115 OMPLoopDirective::HelperExprs B;
5116 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5117 // define the nested loops number.
5118 unsigned NestedLoopCount = CheckOpenMPLoop(
5119 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5120 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5121 if (NestedLoopCount == 0)
5124 assert((CurContext->isDependentContext() || B.builtAll()) &&
5125 "omp simd loop exprs were not built");
5127 if (!CurContext->isDependentContext()) {
5128 // Finalize the clauses that need pre-built expressions for CodeGen.
5129 for (auto C : Clauses) {
5130 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5131 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5132 B.NumIterations, *this, CurScope,
5138 if (checkSimdlenSafelenSpecified(*this, Clauses))
5141 getCurFunction()->setHasBranchProtectedScope();
5142 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5146 StmtResult Sema::ActOnOpenMPForDirective(
5147 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5148 SourceLocation EndLoc,
5149 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5153 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5154 OMPLoopDirective::HelperExprs B;
5155 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5156 // define the nested loops number.
5157 unsigned NestedLoopCount = CheckOpenMPLoop(
5158 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5159 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5160 if (NestedLoopCount == 0)
5163 assert((CurContext->isDependentContext() || B.builtAll()) &&
5164 "omp for loop exprs were not built");
5166 if (!CurContext->isDependentContext()) {
5167 // Finalize the clauses that need pre-built expressions for CodeGen.
5168 for (auto C : Clauses) {
5169 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5170 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5171 B.NumIterations, *this, CurScope,
5177 getCurFunction()->setHasBranchProtectedScope();
5178 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5179 Clauses, AStmt, B, DSAStack->isCancelRegion());
5182 StmtResult Sema::ActOnOpenMPForSimdDirective(
5183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5184 SourceLocation EndLoc,
5185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5189 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5190 OMPLoopDirective::HelperExprs B;
5191 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5192 // define the nested loops number.
5193 unsigned NestedLoopCount =
5194 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5195 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5196 VarsWithImplicitDSA, B);
5197 if (NestedLoopCount == 0)
5200 assert((CurContext->isDependentContext() || B.builtAll()) &&
5201 "omp for simd loop exprs were not built");
5203 if (!CurContext->isDependentContext()) {
5204 // Finalize the clauses that need pre-built expressions for CodeGen.
5205 for (auto C : Clauses) {
5206 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5207 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5208 B.NumIterations, *this, CurScope,
5214 if (checkSimdlenSafelenSpecified(*this, Clauses))
5217 getCurFunction()->setHasBranchProtectedScope();
5218 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5222 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5224 SourceLocation StartLoc,
5225 SourceLocation EndLoc) {
5229 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5230 auto BaseStmt = AStmt;
5231 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5232 BaseStmt = CS->getCapturedStmt();
5233 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5234 auto S = C->children();
5235 if (S.begin() == S.end())
5237 // All associated statements must be '#pragma omp section' except for
5239 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5240 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5242 Diag(SectionStmt->getLocStart(),
5243 diag::err_omp_sections_substmt_not_section);
5246 cast<OMPSectionDirective>(SectionStmt)
5247 ->setHasCancel(DSAStack->isCancelRegion());
5250 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5254 getCurFunction()->setHasBranchProtectedScope();
5256 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5257 DSAStack->isCancelRegion());
5260 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5261 SourceLocation StartLoc,
5262 SourceLocation EndLoc) {
5266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5268 getCurFunction()->setHasBranchProtectedScope();
5269 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5271 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5272 DSAStack->isCancelRegion());
5275 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5277 SourceLocation StartLoc,
5278 SourceLocation EndLoc) {
5282 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5284 getCurFunction()->setHasBranchProtectedScope();
5286 // OpenMP [2.7.3, single Construct, Restrictions]
5287 // The copyprivate clause must not be used with the nowait clause.
5288 OMPClause *Nowait = nullptr;
5289 OMPClause *Copyprivate = nullptr;
5290 for (auto *Clause : Clauses) {
5291 if (Clause->getClauseKind() == OMPC_nowait)
5293 else if (Clause->getClauseKind() == OMPC_copyprivate)
5294 Copyprivate = Clause;
5295 if (Copyprivate && Nowait) {
5296 Diag(Copyprivate->getLocStart(),
5297 diag::err_omp_single_copyprivate_with_nowait);
5298 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5303 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5306 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5307 SourceLocation StartLoc,
5308 SourceLocation EndLoc) {
5312 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5314 getCurFunction()->setHasBranchProtectedScope();
5316 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5319 StmtResult Sema::ActOnOpenMPCriticalDirective(
5320 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5321 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5325 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5327 bool ErrorFound = false;
5329 SourceLocation HintLoc;
5330 bool DependentHint = false;
5331 for (auto *C : Clauses) {
5332 if (C->getClauseKind() == OMPC_hint) {
5333 if (!DirName.getName()) {
5334 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5337 Expr *E = cast<OMPHintClause>(C)->getHint();
5338 if (E->isTypeDependent() || E->isValueDependent() ||
5339 E->isInstantiationDependent())
5340 DependentHint = true;
5342 Hint = E->EvaluateKnownConstInt(Context);
5343 HintLoc = C->getLocStart();
5349 auto Pair = DSAStack->getCriticalWithHint(DirName);
5350 if (Pair.first && DirName.getName() && !DependentHint) {
5351 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5352 Diag(StartLoc, diag::err_omp_critical_with_hint);
5353 if (HintLoc.isValid()) {
5354 Diag(HintLoc, diag::note_omp_critical_hint_here)
5355 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5357 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5358 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5359 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5361 << C->getHint()->EvaluateKnownConstInt(Context).toString(
5362 /*Radix=*/10, /*Signed=*/false);
5364 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5368 getCurFunction()->setHasBranchProtectedScope();
5370 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5372 if (!Pair.first && DirName.getName() && !DependentHint)
5373 DSAStack->addCriticalWithHint(Dir, Hint);
5377 StmtResult Sema::ActOnOpenMPParallelForDirective(
5378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5379 SourceLocation EndLoc,
5380 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5384 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5385 // 1.2.2 OpenMP Language Terminology
5386 // Structured block - An executable statement with a single entry at the
5387 // top and a single exit at the bottom.
5388 // The point of exit cannot be a branch out of the structured block.
5389 // longjmp() and throw() must not violate the entry/exit criteria.
5390 CS->getCapturedDecl()->setNothrow();
5392 OMPLoopDirective::HelperExprs B;
5393 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5394 // define the nested loops number.
5395 unsigned NestedLoopCount =
5396 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5397 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5398 VarsWithImplicitDSA, B);
5399 if (NestedLoopCount == 0)
5402 assert((CurContext->isDependentContext() || B.builtAll()) &&
5403 "omp parallel for loop exprs were not built");
5405 if (!CurContext->isDependentContext()) {
5406 // Finalize the clauses that need pre-built expressions for CodeGen.
5407 for (auto C : Clauses) {
5408 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5410 B.NumIterations, *this, CurScope,
5416 getCurFunction()->setHasBranchProtectedScope();
5417 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5418 NestedLoopCount, Clauses, AStmt, B,
5419 DSAStack->isCancelRegion());
5422 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
5423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5424 SourceLocation EndLoc,
5425 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5429 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5430 // 1.2.2 OpenMP Language Terminology
5431 // Structured block - An executable statement with a single entry at the
5432 // top and a single exit at the bottom.
5433 // The point of exit cannot be a branch out of the structured block.
5434 // longjmp() and throw() must not violate the entry/exit criteria.
5435 CS->getCapturedDecl()->setNothrow();
5437 OMPLoopDirective::HelperExprs B;
5438 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5439 // define the nested loops number.
5440 unsigned NestedLoopCount =
5441 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5442 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5443 VarsWithImplicitDSA, B);
5444 if (NestedLoopCount == 0)
5447 if (!CurContext->isDependentContext()) {
5448 // Finalize the clauses that need pre-built expressions for CodeGen.
5449 for (auto C : Clauses) {
5450 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5451 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5452 B.NumIterations, *this, CurScope,
5458 if (checkSimdlenSafelenSpecified(*this, Clauses))
5461 getCurFunction()->setHasBranchProtectedScope();
5462 return OMPParallelForSimdDirective::Create(
5463 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5467 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
5468 Stmt *AStmt, SourceLocation StartLoc,
5469 SourceLocation EndLoc) {
5473 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5474 auto BaseStmt = AStmt;
5475 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5476 BaseStmt = CS->getCapturedStmt();
5477 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5478 auto S = C->children();
5479 if (S.begin() == S.end())
5481 // All associated statements must be '#pragma omp section' except for
5483 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5484 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5486 Diag(SectionStmt->getLocStart(),
5487 diag::err_omp_parallel_sections_substmt_not_section);
5490 cast<OMPSectionDirective>(SectionStmt)
5491 ->setHasCancel(DSAStack->isCancelRegion());
5494 Diag(AStmt->getLocStart(),
5495 diag::err_omp_parallel_sections_not_compound_stmt);
5499 getCurFunction()->setHasBranchProtectedScope();
5501 return OMPParallelSectionsDirective::Create(
5502 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5505 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
5506 Stmt *AStmt, SourceLocation StartLoc,
5507 SourceLocation EndLoc) {
5511 auto *CS = cast<CapturedStmt>(AStmt);
5512 // 1.2.2 OpenMP Language Terminology
5513 // Structured block - An executable statement with a single entry at the
5514 // top and a single exit at the bottom.
5515 // The point of exit cannot be a branch out of the structured block.
5516 // longjmp() and throw() must not violate the entry/exit criteria.
5517 CS->getCapturedDecl()->setNothrow();
5519 getCurFunction()->setHasBranchProtectedScope();
5521 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5522 DSAStack->isCancelRegion());
5525 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
5526 SourceLocation EndLoc) {
5527 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5530 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
5531 SourceLocation EndLoc) {
5532 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5535 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
5536 SourceLocation EndLoc) {
5537 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5540 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
5542 SourceLocation StartLoc,
5543 SourceLocation EndLoc) {
5547 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5549 getCurFunction()->setHasBranchProtectedScope();
5551 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5553 DSAStack->getTaskgroupReductionRef());
5556 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
5557 SourceLocation StartLoc,
5558 SourceLocation EndLoc) {
5559 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5560 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5563 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
5565 SourceLocation StartLoc,
5566 SourceLocation EndLoc) {
5567 OMPClause *DependFound = nullptr;
5568 OMPClause *DependSourceClause = nullptr;
5569 OMPClause *DependSinkClause = nullptr;
5570 bool ErrorFound = false;
5571 OMPThreadsClause *TC = nullptr;
5572 OMPSIMDClause *SC = nullptr;
5573 for (auto *C : Clauses) {
5574 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5576 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5577 if (DependSourceClause) {
5578 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5579 << getOpenMPDirectiveName(OMPD_ordered)
5580 << getOpenMPClauseName(OMPC_depend) << 2;
5583 DependSourceClause = C;
5584 if (DependSinkClause) {
5585 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5589 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5590 if (DependSourceClause) {
5591 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5595 DependSinkClause = C;
5597 } else if (C->getClauseKind() == OMPC_threads)
5598 TC = cast<OMPThreadsClause>(C);
5599 else if (C->getClauseKind() == OMPC_simd)
5600 SC = cast<OMPSIMDClause>(C);
5602 if (!ErrorFound && !SC &&
5603 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5604 // OpenMP [2.8.1,simd Construct, Restrictions]
5605 // An ordered construct with the simd clause is the only OpenMP construct
5606 // that can appear in the simd region.
5607 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5609 } else if (DependFound && (TC || SC)) {
5610 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5611 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5613 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
5614 Diag(DependFound->getLocStart(),
5615 diag::err_omp_ordered_directive_without_param);
5617 } else if (TC || Clauses.empty()) {
5618 if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
5619 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5620 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5622 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5626 if ((!AStmt && !DependFound) || ErrorFound)
5630 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5632 getCurFunction()->setHasBranchProtectedScope();
5635 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5639 /// \brief Helper class for checking expression in 'omp atomic [update]'
5641 class OpenMPAtomicUpdateChecker {
5642 /// \brief Error results for atomic update expressions.
5643 enum ExprAnalysisErrorCode {
5644 /// \brief A statement is not an expression statement.
5646 /// \brief Expression is not builtin binary or unary operation.
5647 NotABinaryOrUnaryExpression,
5648 /// \brief Unary operation is not post-/pre- increment/decrement operation.
5649 NotAnUnaryIncDecExpression,
5650 /// \brief An expression is not of scalar type.
5652 /// \brief A binary operation is not an assignment operation.
5654 /// \brief RHS part of the binary operation is not a binary expression.
5655 NotABinaryExpression,
5656 /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5659 /// \brief RHS binary operation does not have reference to the updated LHS
5661 NotAnUpdateExpression,
5662 /// \brief No errors is found.
5665 /// \brief Reference to Sema.
5667 /// \brief A location for note diagnostics (when error is found).
5668 SourceLocation NoteLoc;
5669 /// \brief 'x' lvalue part of the source atomic expression.
5671 /// \brief 'expr' rvalue part of the source atomic expression.
5673 /// \brief Helper expression of the form
5674 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5675 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5677 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5678 /// important for non-associative operations.
5679 bool IsXLHSInRHSPart;
5680 BinaryOperatorKind Op;
5681 SourceLocation OpLoc;
5682 /// \brief true if the source expression is a postfix unary operation, false
5683 /// if it is a prefix unary operation.
5684 bool IsPostfixUpdate;
5687 OpenMPAtomicUpdateChecker(Sema &SemaRef)
5688 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5689 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5690 /// \brief Check specified statement that it is suitable for 'atomic update'
5691 /// constructs and extract 'x', 'expr' and Operation from the original
5692 /// expression. If DiagId and NoteId == 0, then only check is performed
5693 /// without error notification.
5694 /// \param DiagId Diagnostic which should be emitted if error is found.
5695 /// \param NoteId Diagnostic note for the main error message.
5696 /// \return true if statement is not an update expression, false otherwise.
5697 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5698 /// \brief Return the 'x' lvalue part of the source atomic expression.
5699 Expr *getX() const { return X; }
5700 /// \brief Return the 'expr' rvalue part of the source atomic expression.
5701 Expr *getExpr() const { return E; }
5702 /// \brief Return the update expression used in calculation of the updated
5703 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5704 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5705 Expr *getUpdateExpr() const { return UpdateExpr; }
5706 /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5707 /// false otherwise.
5708 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5710 /// \brief true if the source expression is a postfix unary operation, false
5711 /// if it is a prefix unary operation.
5712 bool isPostfixUpdate() const { return IsPostfixUpdate; }
5715 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5716 unsigned NoteId = 0);
5720 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5721 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5722 ExprAnalysisErrorCode ErrorFound = NoError;
5723 SourceLocation ErrorLoc, NoteLoc;
5724 SourceRange ErrorRange, NoteRange;
5725 // Allowed constructs are:
5726 // x = x binop expr;
5727 // x = expr binop x;
5728 if (AtomicBinOp->getOpcode() == BO_Assign) {
5729 X = AtomicBinOp->getLHS();
5730 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5731 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5732 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5733 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5734 AtomicInnerBinOp->isBitwiseOp()) {
5735 Op = AtomicInnerBinOp->getOpcode();
5736 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5737 auto *LHS = AtomicInnerBinOp->getLHS();
5738 auto *RHS = AtomicInnerBinOp->getRHS();
5739 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5740 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5741 /*Canonical=*/true);
5742 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5743 /*Canonical=*/true);
5744 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
5745 /*Canonical=*/true);
5748 IsXLHSInRHSPart = true;
5749 } else if (XId == RHSId) {
5751 IsXLHSInRHSPart = false;
5753 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5754 ErrorRange = AtomicInnerBinOp->getSourceRange();
5755 NoteLoc = X->getExprLoc();
5756 NoteRange = X->getSourceRange();
5757 ErrorFound = NotAnUpdateExpression;
5760 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5761 ErrorRange = AtomicInnerBinOp->getSourceRange();
5762 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5763 NoteRange = SourceRange(NoteLoc, NoteLoc);
5764 ErrorFound = NotABinaryOperator;
5767 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
5768 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
5769 ErrorFound = NotABinaryExpression;
5772 ErrorLoc = AtomicBinOp->getExprLoc();
5773 ErrorRange = AtomicBinOp->getSourceRange();
5774 NoteLoc = AtomicBinOp->getOperatorLoc();
5775 NoteRange = SourceRange(NoteLoc, NoteLoc);
5776 ErrorFound = NotAnAssignmentOp;
5778 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5779 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5780 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5782 } else if (SemaRef.CurContext->isDependentContext())
5783 E = X = UpdateExpr = nullptr;
5784 return ErrorFound != NoError;
5787 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
5789 ExprAnalysisErrorCode ErrorFound = NoError;
5790 SourceLocation ErrorLoc, NoteLoc;
5791 SourceRange ErrorRange, NoteRange;
5792 // Allowed constructs are:
5798 // x = x binop expr;
5799 // x = expr binop x;
5800 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
5801 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5802 if (AtomicBody->getType()->isScalarType() ||
5803 AtomicBody->isInstantiationDependent()) {
5804 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5805 AtomicBody->IgnoreParenImpCasts())) {
5806 // Check for Compound Assignment Operation
5807 Op = BinaryOperator::getOpForCompoundAssignment(
5808 AtomicCompAssignOp->getOpcode());
5809 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5810 E = AtomicCompAssignOp->getRHS();
5811 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5812 IsXLHSInRHSPart = true;
5813 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5814 AtomicBody->IgnoreParenImpCasts())) {
5815 // Check for Binary Operation
5816 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5818 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5819 AtomicBody->IgnoreParenImpCasts())) {
5820 // Check for Unary Operation
5821 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5822 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5823 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5824 OpLoc = AtomicUnaryOp->getOperatorLoc();
5825 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5826 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
5827 IsXLHSInRHSPart = true;
5829 ErrorFound = NotAnUnaryIncDecExpression;
5830 ErrorLoc = AtomicUnaryOp->getExprLoc();
5831 ErrorRange = AtomicUnaryOp->getSourceRange();
5832 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5833 NoteRange = SourceRange(NoteLoc, NoteLoc);
5835 } else if (!AtomicBody->isInstantiationDependent()) {
5836 ErrorFound = NotABinaryOrUnaryExpression;
5837 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5838 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5841 ErrorFound = NotAScalarType;
5842 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5843 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5846 ErrorFound = NotAnExpression;
5847 NoteLoc = ErrorLoc = S->getLocStart();
5848 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5850 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5851 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5852 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5854 } else if (SemaRef.CurContext->isDependentContext())
5855 E = X = UpdateExpr = nullptr;
5856 if (ErrorFound == NoError && E && X) {
5857 // Build an update expression of form 'OpaqueValueExpr(x) binop
5858 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
5859 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
5860 auto *OVEX = new (SemaRef.getASTContext())
5861 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
5862 auto *OVEExpr = new (SemaRef.getASTContext())
5863 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
5865 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
5866 IsXLHSInRHSPart ? OVEExpr : OVEX);
5867 if (Update.isInvalid())
5869 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
5871 if (Update.isInvalid())
5873 UpdateExpr = Update.get();
5875 return ErrorFound != NoError;
5878 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
5880 SourceLocation StartLoc,
5881 SourceLocation EndLoc) {
5885 auto *CS = cast<CapturedStmt>(AStmt);
5886 // 1.2.2 OpenMP Language Terminology
5887 // Structured block - An executable statement with a single entry at the
5888 // top and a single exit at the bottom.
5889 // The point of exit cannot be a branch out of the structured block.
5890 // longjmp() and throw() must not violate the entry/exit criteria.
5891 OpenMPClauseKind AtomicKind = OMPC_unknown;
5892 SourceLocation AtomicKindLoc;
5893 for (auto *C : Clauses) {
5894 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5895 C->getClauseKind() == OMPC_update ||
5896 C->getClauseKind() == OMPC_capture) {
5897 if (AtomicKind != OMPC_unknown) {
5898 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5899 << SourceRange(C->getLocStart(), C->getLocEnd());
5900 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5901 << getOpenMPClauseName(AtomicKind);
5903 AtomicKind = C->getClauseKind();
5904 AtomicKindLoc = C->getLocStart();
5909 auto Body = CS->getCapturedStmt();
5910 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5911 Body = EWC->getSubExpr();
5917 bool IsXLHSInRHSPart = false;
5918 bool IsPostfixUpdate = false;
5919 // OpenMP [2.12.6, atomic Construct]
5920 // In the next expressions:
5921 // * x and v (as applicable) are both l-value expressions with scalar type.
5922 // * During the execution of an atomic region, multiple syntactic
5923 // occurrences of x must designate the same storage location.
5924 // * Neither of v and expr (as applicable) may access the storage location
5926 // * Neither of x and expr (as applicable) may access the storage location
5928 // * expr is an expression with scalar type.
5929 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5930 // * binop, binop=, ++, and -- are not overloaded operators.
5931 // * The expression x binop expr must be numerically equivalent to x binop
5932 // (expr). This requirement is satisfied if the operators in expr have
5933 // precedence greater than binop, or by using parentheses around expr or
5934 // subexpressions of expr.
5935 // * The expression expr binop x must be numerically equivalent to (expr)
5936 // binop x. This requirement is satisfied if the operators in expr have
5937 // precedence equal to or greater than binop, or by using parentheses around
5938 // expr or subexpressions of expr.
5939 // * For forms that allow multiple occurrences of x, the number of times
5940 // that x is evaluated is unspecified.
5941 if (AtomicKind == OMPC_read) {
5948 } ErrorFound = NoError;
5949 SourceLocation ErrorLoc, NoteLoc;
5950 SourceRange ErrorRange, NoteRange;
5951 // If clause is read:
5953 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5955 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5956 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5957 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5958 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5959 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5960 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5961 if (!X->isLValue() || !V->isLValue()) {
5962 auto NotLValueExpr = X->isLValue() ? V : X;
5963 ErrorFound = NotAnLValue;
5964 ErrorLoc = AtomicBinOp->getExprLoc();
5965 ErrorRange = AtomicBinOp->getSourceRange();
5966 NoteLoc = NotLValueExpr->getExprLoc();
5967 NoteRange = NotLValueExpr->getSourceRange();
5969 } else if (!X->isInstantiationDependent() ||
5970 !V->isInstantiationDependent()) {
5971 auto NotScalarExpr =
5972 (X->isInstantiationDependent() || X->getType()->isScalarType())
5975 ErrorFound = NotAScalarType;
5976 ErrorLoc = AtomicBinOp->getExprLoc();
5977 ErrorRange = AtomicBinOp->getSourceRange();
5978 NoteLoc = NotScalarExpr->getExprLoc();
5979 NoteRange = NotScalarExpr->getSourceRange();
5981 } else if (!AtomicBody->isInstantiationDependent()) {
5982 ErrorFound = NotAnAssignmentOp;
5983 ErrorLoc = AtomicBody->getExprLoc();
5984 ErrorRange = AtomicBody->getSourceRange();
5985 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5986 : AtomicBody->getExprLoc();
5987 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5988 : AtomicBody->getSourceRange();
5991 ErrorFound = NotAnExpression;
5992 NoteLoc = ErrorLoc = Body->getLocStart();
5993 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5995 if (ErrorFound != NoError) {
5996 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5998 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6001 } else if (CurContext->isDependentContext())
6003 } else if (AtomicKind == OMPC_write) {
6010 } ErrorFound = NoError;
6011 SourceLocation ErrorLoc, NoteLoc;
6012 SourceRange ErrorRange, NoteRange;
6013 // If clause is write:
6015 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6017 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6018 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6019 X = AtomicBinOp->getLHS();
6020 E = AtomicBinOp->getRHS();
6021 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6022 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6023 if (!X->isLValue()) {
6024 ErrorFound = NotAnLValue;
6025 ErrorLoc = AtomicBinOp->getExprLoc();
6026 ErrorRange = AtomicBinOp->getSourceRange();
6027 NoteLoc = X->getExprLoc();
6028 NoteRange = X->getSourceRange();
6030 } else if (!X->isInstantiationDependent() ||
6031 !E->isInstantiationDependent()) {
6032 auto NotScalarExpr =
6033 (X->isInstantiationDependent() || X->getType()->isScalarType())
6036 ErrorFound = NotAScalarType;
6037 ErrorLoc = AtomicBinOp->getExprLoc();
6038 ErrorRange = AtomicBinOp->getSourceRange();
6039 NoteLoc = NotScalarExpr->getExprLoc();
6040 NoteRange = NotScalarExpr->getSourceRange();
6042 } else if (!AtomicBody->isInstantiationDependent()) {
6043 ErrorFound = NotAnAssignmentOp;
6044 ErrorLoc = AtomicBody->getExprLoc();
6045 ErrorRange = AtomicBody->getSourceRange();
6046 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6047 : AtomicBody->getExprLoc();
6048 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6049 : AtomicBody->getSourceRange();
6052 ErrorFound = NotAnExpression;
6053 NoteLoc = ErrorLoc = Body->getLocStart();
6054 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6056 if (ErrorFound != NoError) {
6057 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6059 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6062 } else if (CurContext->isDependentContext())
6064 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6065 // If clause is update:
6071 // x = x binop expr;
6072 // x = expr binop x;
6073 OpenMPAtomicUpdateChecker Checker(*this);
6074 if (Checker.checkStatement(
6075 Body, (AtomicKind == OMPC_update)
6076 ? diag::err_omp_atomic_update_not_expression_statement
6077 : diag::err_omp_atomic_not_expression_statement,
6078 diag::note_omp_atomic_update))
6080 if (!CurContext->isDependentContext()) {
6081 E = Checker.getExpr();
6083 UE = Checker.getUpdateExpr();
6084 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6086 } else if (AtomicKind == OMPC_capture) {
6089 NotACompoundStatement,
6090 NotTwoSubstatements,
6091 NotASpecificExpression,
6093 } ErrorFound = NoError;
6094 SourceLocation ErrorLoc, NoteLoc;
6095 SourceRange ErrorRange, NoteRange;
6096 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6097 // If clause is a capture:
6102 // v = x binop= expr;
6103 // v = x = x binop expr;
6104 // v = x = expr binop x;
6106 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6107 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6108 V = AtomicBinOp->getLHS();
6109 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6110 OpenMPAtomicUpdateChecker Checker(*this);
6111 if (Checker.checkStatement(
6112 Body, diag::err_omp_atomic_capture_not_expression_statement,
6113 diag::note_omp_atomic_update))
6115 E = Checker.getExpr();
6117 UE = Checker.getUpdateExpr();
6118 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6119 IsPostfixUpdate = Checker.isPostfixUpdate();
6120 } else if (!AtomicBody->isInstantiationDependent()) {
6121 ErrorLoc = AtomicBody->getExprLoc();
6122 ErrorRange = AtomicBody->getSourceRange();
6123 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6124 : AtomicBody->getExprLoc();
6125 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6126 : AtomicBody->getSourceRange();
6127 ErrorFound = NotAnAssignmentOp;
6129 if (ErrorFound != NoError) {
6130 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6132 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6134 } else if (CurContext->isDependentContext()) {
6135 UE = V = E = X = nullptr;
6138 // If clause is a capture:
6139 // { v = x; x = expr; }
6144 // { v = x; x binop= expr; }
6145 // { v = x; x = x binop expr; }
6146 // { v = x; x = expr binop x; }
6151 // { x binop= expr; v = x; }
6152 // { x = x binop expr; v = x; }
6153 // { x = expr binop x; v = x; }
6154 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6155 // Check that this is { expr1; expr2; }
6156 if (CS->size() == 2) {
6157 auto *First = CS->body_front();
6158 auto *Second = CS->body_back();
6159 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6160 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6161 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6162 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6163 // Need to find what subexpression is 'v' and what is 'x'.
6164 OpenMPAtomicUpdateChecker Checker(*this);
6165 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6166 BinaryOperator *BinOp = nullptr;
6167 if (IsUpdateExprFound) {
6168 BinOp = dyn_cast<BinaryOperator>(First);
6169 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6171 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6176 // { v = x; x binop= expr; }
6177 // { v = x; x = x binop expr; }
6178 // { v = x; x = expr binop x; }
6179 // Check that the first expression has form v = x.
6180 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6181 llvm::FoldingSetNodeID XId, PossibleXId;
6182 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6183 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6184 IsUpdateExprFound = XId == PossibleXId;
6185 if (IsUpdateExprFound) {
6186 V = BinOp->getLHS();
6188 E = Checker.getExpr();
6189 UE = Checker.getUpdateExpr();
6190 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6191 IsPostfixUpdate = true;
6194 if (!IsUpdateExprFound) {
6195 IsUpdateExprFound = !Checker.checkStatement(First);
6197 if (IsUpdateExprFound) {
6198 BinOp = dyn_cast<BinaryOperator>(Second);
6199 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6201 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6206 // { x binop= expr; v = x; }
6207 // { x = x binop expr; v = x; }
6208 // { x = expr binop x; v = x; }
6209 // Check that the second expression has form v = x.
6210 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6211 llvm::FoldingSetNodeID XId, PossibleXId;
6212 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6213 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6214 IsUpdateExprFound = XId == PossibleXId;
6215 if (IsUpdateExprFound) {
6216 V = BinOp->getLHS();
6218 E = Checker.getExpr();
6219 UE = Checker.getUpdateExpr();
6220 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6221 IsPostfixUpdate = false;
6225 if (!IsUpdateExprFound) {
6226 // { v = x; x = expr; }
6227 auto *FirstExpr = dyn_cast<Expr>(First);
6228 auto *SecondExpr = dyn_cast<Expr>(Second);
6229 if (!FirstExpr || !SecondExpr ||
6230 !(FirstExpr->isInstantiationDependent() ||
6231 SecondExpr->isInstantiationDependent())) {
6232 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6233 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6234 ErrorFound = NotAnAssignmentOp;
6235 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6236 : First->getLocStart();
6237 NoteRange = ErrorRange = FirstBinOp
6238 ? FirstBinOp->getSourceRange()
6239 : SourceRange(ErrorLoc, ErrorLoc);
6241 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6242 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6243 ErrorFound = NotAnAssignmentOp;
6244 NoteLoc = ErrorLoc = SecondBinOp
6245 ? SecondBinOp->getOperatorLoc()
6246 : Second->getLocStart();
6247 NoteRange = ErrorRange =
6248 SecondBinOp ? SecondBinOp->getSourceRange()
6249 : SourceRange(ErrorLoc, ErrorLoc);
6251 auto *PossibleXRHSInFirst =
6252 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6253 auto *PossibleXLHSInSecond =
6254 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6255 llvm::FoldingSetNodeID X1Id, X2Id;
6256 PossibleXRHSInFirst->Profile(X1Id, Context,
6257 /*Canonical=*/true);
6258 PossibleXLHSInSecond->Profile(X2Id, Context,
6259 /*Canonical=*/true);
6260 IsUpdateExprFound = X1Id == X2Id;
6261 if (IsUpdateExprFound) {
6262 V = FirstBinOp->getLHS();
6263 X = SecondBinOp->getLHS();
6264 E = SecondBinOp->getRHS();
6266 IsXLHSInRHSPart = false;
6267 IsPostfixUpdate = true;
6269 ErrorFound = NotASpecificExpression;
6270 ErrorLoc = FirstBinOp->getExprLoc();
6271 ErrorRange = FirstBinOp->getSourceRange();
6272 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6273 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6280 NoteLoc = ErrorLoc = Body->getLocStart();
6281 NoteRange = ErrorRange =
6282 SourceRange(Body->getLocStart(), Body->getLocStart());
6283 ErrorFound = NotTwoSubstatements;
6286 NoteLoc = ErrorLoc = Body->getLocStart();
6287 NoteRange = ErrorRange =
6288 SourceRange(Body->getLocStart(), Body->getLocStart());
6289 ErrorFound = NotACompoundStatement;
6291 if (ErrorFound != NoError) {
6292 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6294 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6296 } else if (CurContext->isDependentContext()) {
6297 UE = V = E = X = nullptr;
6302 getCurFunction()->setHasBranchProtectedScope();
6304 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6305 X, V, E, UE, IsXLHSInRHSPart,
6309 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6311 SourceLocation StartLoc,
6312 SourceLocation EndLoc) {
6316 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6317 // 1.2.2 OpenMP Language Terminology
6318 // Structured block - An executable statement with a single entry at the
6319 // top and a single exit at the bottom.
6320 // The point of exit cannot be a branch out of the structured block.
6321 // longjmp() and throw() must not violate the entry/exit criteria.
6322 CS->getCapturedDecl()->setNothrow();
6324 // OpenMP [2.16, Nesting of Regions]
6325 // If specified, a teams construct must be contained within a target
6326 // construct. That target construct must contain no statements or directives
6327 // outside of the teams construct.
6328 if (DSAStack->hasInnerTeamsRegion()) {
6329 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
6330 bool OMPTeamsFound = true;
6331 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6332 auto I = CS->body_begin();
6333 while (I != CS->body_end()) {
6334 auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6335 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6336 OMPTeamsFound = false;
6341 assert(I != CS->body_end() && "Not found statement");
6344 auto *OED = dyn_cast<OMPExecutableDirective>(S);
6345 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6347 if (!OMPTeamsFound) {
6348 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6349 Diag(DSAStack->getInnerTeamsRegionLoc(),
6350 diag::note_omp_nested_teams_construct_here);
6351 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6352 << isa<OMPExecutableDirective>(S);
6357 getCurFunction()->setHasBranchProtectedScope();
6359 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6363 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
6364 Stmt *AStmt, SourceLocation StartLoc,
6365 SourceLocation EndLoc) {
6369 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6370 // 1.2.2 OpenMP Language Terminology
6371 // Structured block - An executable statement with a single entry at the
6372 // top and a single exit at the bottom.
6373 // The point of exit cannot be a branch out of the structured block.
6374 // longjmp() and throw() must not violate the entry/exit criteria.
6375 CS->getCapturedDecl()->setNothrow();
6377 getCurFunction()->setHasBranchProtectedScope();
6379 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6383 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
6384 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6385 SourceLocation EndLoc,
6386 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6390 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6391 // 1.2.2 OpenMP Language Terminology
6392 // Structured block - An executable statement with a single entry at the
6393 // top and a single exit at the bottom.
6394 // The point of exit cannot be a branch out of the structured block.
6395 // longjmp() and throw() must not violate the entry/exit criteria.
6396 CS->getCapturedDecl()->setNothrow();
6397 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6398 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6399 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6400 // 1.2.2 OpenMP Language Terminology
6401 // Structured block - An executable statement with a single entry at the
6402 // top and a single exit at the bottom.
6403 // The point of exit cannot be a branch out of the structured block.
6404 // longjmp() and throw() must not violate the entry/exit criteria.
6405 CS->getCapturedDecl()->setNothrow();
6408 OMPLoopDirective::HelperExprs B;
6409 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6410 // define the nested loops number.
6411 unsigned NestedLoopCount =
6412 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6413 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6414 VarsWithImplicitDSA, B);
6415 if (NestedLoopCount == 0)
6418 assert((CurContext->isDependentContext() || B.builtAll()) &&
6419 "omp target parallel for loop exprs were not built");
6421 if (!CurContext->isDependentContext()) {
6422 // Finalize the clauses that need pre-built expressions for CodeGen.
6423 for (auto C : Clauses) {
6424 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6425 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6426 B.NumIterations, *this, CurScope,
6432 getCurFunction()->setHasBranchProtectedScope();
6433 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6434 NestedLoopCount, Clauses, AStmt,
6435 B, DSAStack->isCancelRegion());
6438 /// Check for existence of a map clause in the list of clauses.
6439 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6440 const OpenMPClauseKind K) {
6441 return llvm::any_of(
6442 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6445 template <typename... Params>
6446 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
6447 const Params... ClauseTypes) {
6448 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6451 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
6453 SourceLocation StartLoc,
6454 SourceLocation EndLoc) {
6458 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6460 // OpenMP [2.10.1, Restrictions, p. 97]
6461 // At least one map clause must appear on the directive.
6462 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6463 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6464 << "'map' or 'use_device_ptr'"
6465 << getOpenMPDirectiveName(OMPD_target_data);
6469 getCurFunction()->setHasBranchProtectedScope();
6471 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6476 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
6477 SourceLocation StartLoc,
6478 SourceLocation EndLoc, Stmt *AStmt) {
6482 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6483 // 1.2.2 OpenMP Language Terminology
6484 // Structured block - An executable statement with a single entry at the
6485 // top and a single exit at the bottom.
6486 // The point of exit cannot be a branch out of the structured block.
6487 // longjmp() and throw() must not violate the entry/exit criteria.
6488 CS->getCapturedDecl()->setNothrow();
6489 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6490 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6491 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6492 // 1.2.2 OpenMP Language Terminology
6493 // Structured block - An executable statement with a single entry at the
6494 // top and a single exit at the bottom.
6495 // The point of exit cannot be a branch out of the structured block.
6496 // longjmp() and throw() must not violate the entry/exit criteria.
6497 CS->getCapturedDecl()->setNothrow();
6500 // OpenMP [2.10.2, Restrictions, p. 99]
6501 // At least one map clause must appear on the directive.
6502 if (!hasClauses(Clauses, OMPC_map)) {
6503 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6504 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6508 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6513 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
6514 SourceLocation StartLoc,
6515 SourceLocation EndLoc, Stmt *AStmt) {
6519 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6520 // 1.2.2 OpenMP Language Terminology
6521 // Structured block - An executable statement with a single entry at the
6522 // top and a single exit at the bottom.
6523 // The point of exit cannot be a branch out of the structured block.
6524 // longjmp() and throw() must not violate the entry/exit criteria.
6525 CS->getCapturedDecl()->setNothrow();
6526 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6527 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6528 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6529 // 1.2.2 OpenMP Language Terminology
6530 // Structured block - An executable statement with a single entry at the
6531 // top and a single exit at the bottom.
6532 // The point of exit cannot be a branch out of the structured block.
6533 // longjmp() and throw() must not violate the entry/exit criteria.
6534 CS->getCapturedDecl()->setNothrow();
6537 // OpenMP [2.10.3, Restrictions, p. 102]
6538 // At least one map clause must appear on the directive.
6539 if (!hasClauses(Clauses, OMPC_map)) {
6540 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6541 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6545 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6549 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
6550 SourceLocation StartLoc,
6551 SourceLocation EndLoc,
6556 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6557 // 1.2.2 OpenMP Language Terminology
6558 // Structured block - An executable statement with a single entry at the
6559 // top and a single exit at the bottom.
6560 // The point of exit cannot be a branch out of the structured block.
6561 // longjmp() and throw() must not violate the entry/exit criteria.
6562 CS->getCapturedDecl()->setNothrow();
6563 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6564 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6565 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6566 // 1.2.2 OpenMP Language Terminology
6567 // Structured block - An executable statement with a single entry at the
6568 // top and a single exit at the bottom.
6569 // The point of exit cannot be a branch out of the structured block.
6570 // longjmp() and throw() must not violate the entry/exit criteria.
6571 CS->getCapturedDecl()->setNothrow();
6574 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6575 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6578 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6582 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
6583 Stmt *AStmt, SourceLocation StartLoc,
6584 SourceLocation EndLoc) {
6588 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6589 // 1.2.2 OpenMP Language Terminology
6590 // Structured block - An executable statement with a single entry at the
6591 // top and a single exit at the bottom.
6592 // The point of exit cannot be a branch out of the structured block.
6593 // longjmp() and throw() must not violate the entry/exit criteria.
6594 CS->getCapturedDecl()->setNothrow();
6596 getCurFunction()->setHasBranchProtectedScope();
6598 DSAStack->setParentTeamsRegionLoc(StartLoc);
6600 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6604 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
6605 SourceLocation EndLoc,
6606 OpenMPDirectiveKind CancelRegion) {
6607 if (DSAStack->isParentNowaitRegion()) {
6608 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6611 if (DSAStack->isParentOrderedRegion()) {
6612 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6615 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6619 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
6620 SourceLocation StartLoc,
6621 SourceLocation EndLoc,
6622 OpenMPDirectiveKind CancelRegion) {
6623 if (DSAStack->isParentNowaitRegion()) {
6624 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6627 if (DSAStack->isParentOrderedRegion()) {
6628 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6631 DSAStack->setParentCancelRegion(/*Cancel=*/true);
6632 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6636 static bool checkGrainsizeNumTasksClauses(Sema &S,
6637 ArrayRef<OMPClause *> Clauses) {
6638 OMPClause *PrevClause = nullptr;
6639 bool ErrorFound = false;
6640 for (auto *C : Clauses) {
6641 if (C->getClauseKind() == OMPC_grainsize ||
6642 C->getClauseKind() == OMPC_num_tasks) {
6645 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6646 S.Diag(C->getLocStart(),
6647 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6648 << getOpenMPClauseName(C->getClauseKind())
6649 << getOpenMPClauseName(PrevClause->getClauseKind());
6650 S.Diag(PrevClause->getLocStart(),
6651 diag::note_omp_previous_grainsize_num_tasks)
6652 << getOpenMPClauseName(PrevClause->getClauseKind());
6660 static bool checkReductionClauseWithNogroup(Sema &S,
6661 ArrayRef<OMPClause *> Clauses) {
6662 OMPClause *ReductionClause = nullptr;
6663 OMPClause *NogroupClause = nullptr;
6664 for (auto *C : Clauses) {
6665 if (C->getClauseKind() == OMPC_reduction) {
6666 ReductionClause = C;
6671 if (C->getClauseKind() == OMPC_nogroup) {
6673 if (ReductionClause)
6678 if (ReductionClause && NogroupClause) {
6679 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
6680 << SourceRange(NogroupClause->getLocStart(),
6681 NogroupClause->getLocEnd());
6687 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
6688 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6689 SourceLocation EndLoc,
6690 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6694 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6695 OMPLoopDirective::HelperExprs B;
6696 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6697 // define the nested loops number.
6698 unsigned NestedLoopCount =
6699 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6700 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6701 VarsWithImplicitDSA, B);
6702 if (NestedLoopCount == 0)
6705 assert((CurContext->isDependentContext() || B.builtAll()) &&
6706 "omp for loop exprs were not built");
6708 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6709 // The grainsize clause and num_tasks clause are mutually exclusive and may
6710 // not appear on the same taskloop directive.
6711 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6713 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6714 // If a reduction clause is present on the taskloop directive, the nogroup
6715 // clause must not be specified.
6716 if (checkReductionClauseWithNogroup(*this, Clauses))
6719 getCurFunction()->setHasBranchProtectedScope();
6720 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6721 NestedLoopCount, Clauses, AStmt, B);
6724 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
6725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6726 SourceLocation EndLoc,
6727 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6731 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6732 OMPLoopDirective::HelperExprs B;
6733 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6734 // define the nested loops number.
6735 unsigned NestedLoopCount =
6736 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
6737 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6738 VarsWithImplicitDSA, B);
6739 if (NestedLoopCount == 0)
6742 assert((CurContext->isDependentContext() || B.builtAll()) &&
6743 "omp for loop exprs were not built");
6745 if (!CurContext->isDependentContext()) {
6746 // Finalize the clauses that need pre-built expressions for CodeGen.
6747 for (auto C : Clauses) {
6748 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6749 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6750 B.NumIterations, *this, CurScope,
6756 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6757 // The grainsize clause and num_tasks clause are mutually exclusive and may
6758 // not appear on the same taskloop directive.
6759 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6761 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6762 // If a reduction clause is present on the taskloop directive, the nogroup
6763 // clause must not be specified.
6764 if (checkReductionClauseWithNogroup(*this, Clauses))
6766 if (checkSimdlenSafelenSpecified(*this, Clauses))
6769 getCurFunction()->setHasBranchProtectedScope();
6770 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
6771 NestedLoopCount, Clauses, AStmt, B);
6774 StmtResult Sema::ActOnOpenMPDistributeDirective(
6775 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6776 SourceLocation EndLoc,
6777 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6781 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6782 OMPLoopDirective::HelperExprs B;
6783 // In presence of clause 'collapse' with number of loops, it will
6784 // define the nested loops number.
6785 unsigned NestedLoopCount =
6786 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
6787 nullptr /*ordered not a clause on distribute*/, AStmt,
6788 *this, *DSAStack, VarsWithImplicitDSA, B);
6789 if (NestedLoopCount == 0)
6792 assert((CurContext->isDependentContext() || B.builtAll()) &&
6793 "omp for loop exprs were not built");
6795 getCurFunction()->setHasBranchProtectedScope();
6796 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
6797 NestedLoopCount, Clauses, AStmt, B);
6800 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
6801 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6802 SourceLocation EndLoc,
6803 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6807 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6808 // 1.2.2 OpenMP Language Terminology
6809 // Structured block - An executable statement with a single entry at the
6810 // top and a single exit at the bottom.
6811 // The point of exit cannot be a branch out of the structured block.
6812 // longjmp() and throw() must not violate the entry/exit criteria.
6813 CS->getCapturedDecl()->setNothrow();
6814 for (int ThisCaptureLevel =
6815 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6816 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6817 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6818 // 1.2.2 OpenMP Language Terminology
6819 // Structured block - An executable statement with a single entry at the
6820 // top and a single exit at the bottom.
6821 // The point of exit cannot be a branch out of the structured block.
6822 // longjmp() and throw() must not violate the entry/exit criteria.
6823 CS->getCapturedDecl()->setNothrow();
6826 OMPLoopDirective::HelperExprs B;
6827 // In presence of clause 'collapse' with number of loops, it will
6828 // define the nested loops number.
6829 unsigned NestedLoopCount = CheckOpenMPLoop(
6830 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
6831 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6832 VarsWithImplicitDSA, B);
6833 if (NestedLoopCount == 0)
6836 assert((CurContext->isDependentContext() || B.builtAll()) &&
6837 "omp for loop exprs were not built");
6839 getCurFunction()->setHasBranchProtectedScope();
6840 return OMPDistributeParallelForDirective::Create(
6841 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6842 DSAStack->isCancelRegion());
6845 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
6846 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6847 SourceLocation EndLoc,
6848 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6852 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6853 // 1.2.2 OpenMP Language Terminology
6854 // Structured block - An executable statement with a single entry at the
6855 // top and a single exit at the bottom.
6856 // The point of exit cannot be a branch out of the structured block.
6857 // longjmp() and throw() must not violate the entry/exit criteria.
6858 CS->getCapturedDecl()->setNothrow();
6859 for (int ThisCaptureLevel =
6860 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6861 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6862 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6863 // 1.2.2 OpenMP Language Terminology
6864 // Structured block - An executable statement with a single entry at the
6865 // top and a single exit at the bottom.
6866 // The point of exit cannot be a branch out of the structured block.
6867 // longjmp() and throw() must not violate the entry/exit criteria.
6868 CS->getCapturedDecl()->setNothrow();
6871 OMPLoopDirective::HelperExprs B;
6872 // In presence of clause 'collapse' with number of loops, it will
6873 // define the nested loops number.
6874 unsigned NestedLoopCount = CheckOpenMPLoop(
6875 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
6876 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6877 VarsWithImplicitDSA, B);
6878 if (NestedLoopCount == 0)
6881 assert((CurContext->isDependentContext() || B.builtAll()) &&
6882 "omp for loop exprs were not built");
6884 if (!CurContext->isDependentContext()) {
6885 // Finalize the clauses that need pre-built expressions for CodeGen.
6886 for (auto C : Clauses) {
6887 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6888 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6889 B.NumIterations, *this, CurScope,
6895 if (checkSimdlenSafelenSpecified(*this, Clauses))
6898 getCurFunction()->setHasBranchProtectedScope();
6899 return OMPDistributeParallelForSimdDirective::Create(
6900 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6903 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
6904 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6905 SourceLocation EndLoc,
6906 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6910 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6911 // 1.2.2 OpenMP Language Terminology
6912 // Structured block - An executable statement with a single entry at the
6913 // top and a single exit at the bottom.
6914 // The point of exit cannot be a branch out of the structured block.
6915 // longjmp() and throw() must not violate the entry/exit criteria.
6916 CS->getCapturedDecl()->setNothrow();
6917 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
6918 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6919 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6920 // 1.2.2 OpenMP Language Terminology
6921 // Structured block - An executable statement with a single entry at the
6922 // top and a single exit at the bottom.
6923 // The point of exit cannot be a branch out of the structured block.
6924 // longjmp() and throw() must not violate the entry/exit criteria.
6925 CS->getCapturedDecl()->setNothrow();
6928 OMPLoopDirective::HelperExprs B;
6929 // In presence of clause 'collapse' with number of loops, it will
6930 // define the nested loops number.
6931 unsigned NestedLoopCount =
6932 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
6933 nullptr /*ordered not a clause on distribute*/, CS, *this,
6934 *DSAStack, VarsWithImplicitDSA, B);
6935 if (NestedLoopCount == 0)
6938 assert((CurContext->isDependentContext() || B.builtAll()) &&
6939 "omp for loop exprs were not built");
6941 if (!CurContext->isDependentContext()) {
6942 // Finalize the clauses that need pre-built expressions for CodeGen.
6943 for (auto C : Clauses) {
6944 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6946 B.NumIterations, *this, CurScope,
6952 if (checkSimdlenSafelenSpecified(*this, Clauses))
6955 getCurFunction()->setHasBranchProtectedScope();
6956 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
6957 NestedLoopCount, Clauses, AStmt, B);
6960 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
6961 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6962 SourceLocation EndLoc,
6963 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6967 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6968 // 1.2.2 OpenMP Language Terminology
6969 // Structured block - An executable statement with a single entry at the
6970 // top and a single exit at the bottom.
6971 // The point of exit cannot be a branch out of the structured block.
6972 // longjmp() and throw() must not violate the entry/exit criteria.
6973 CS->getCapturedDecl()->setNothrow();
6974 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6975 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6976 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6977 // 1.2.2 OpenMP Language Terminology
6978 // Structured block - An executable statement with a single entry at the
6979 // top and a single exit at the bottom.
6980 // The point of exit cannot be a branch out of the structured block.
6981 // longjmp() and throw() must not violate the entry/exit criteria.
6982 CS->getCapturedDecl()->setNothrow();
6985 OMPLoopDirective::HelperExprs B;
6986 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6987 // define the nested loops number.
6988 unsigned NestedLoopCount = CheckOpenMPLoop(
6989 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
6990 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6991 VarsWithImplicitDSA, B);
6992 if (NestedLoopCount == 0)
6995 assert((CurContext->isDependentContext() || B.builtAll()) &&
6996 "omp target parallel for simd loop exprs were not built");
6998 if (!CurContext->isDependentContext()) {
6999 // Finalize the clauses that need pre-built expressions for CodeGen.
7000 for (auto C : Clauses) {
7001 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7002 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7003 B.NumIterations, *this, CurScope,
7008 if (checkSimdlenSafelenSpecified(*this, Clauses))
7011 getCurFunction()->setHasBranchProtectedScope();
7012 return OMPTargetParallelForSimdDirective::Create(
7013 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7016 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7018 SourceLocation EndLoc,
7019 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7023 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7024 // 1.2.2 OpenMP Language Terminology
7025 // Structured block - An executable statement with a single entry at the
7026 // top and a single exit at the bottom.
7027 // The point of exit cannot be a branch out of the structured block.
7028 // longjmp() and throw() must not violate the entry/exit criteria.
7029 CS->getCapturedDecl()->setNothrow();
7030 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7031 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7032 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7033 // 1.2.2 OpenMP Language Terminology
7034 // Structured block - An executable statement with a single entry at the
7035 // top and a single exit at the bottom.
7036 // The point of exit cannot be a branch out of the structured block.
7037 // longjmp() and throw() must not violate the entry/exit criteria.
7038 CS->getCapturedDecl()->setNothrow();
7041 OMPLoopDirective::HelperExprs B;
7042 // In presence of clause 'collapse' with number of loops, it will define the
7043 // nested loops number.
7044 unsigned NestedLoopCount =
7045 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7046 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7047 VarsWithImplicitDSA, B);
7048 if (NestedLoopCount == 0)
7051 assert((CurContext->isDependentContext() || B.builtAll()) &&
7052 "omp target simd loop exprs were not built");
7054 if (!CurContext->isDependentContext()) {
7055 // Finalize the clauses that need pre-built expressions for CodeGen.
7056 for (auto C : Clauses) {
7057 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7058 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7059 B.NumIterations, *this, CurScope,
7065 if (checkSimdlenSafelenSpecified(*this, Clauses))
7068 getCurFunction()->setHasBranchProtectedScope();
7069 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7070 NestedLoopCount, Clauses, AStmt, B);
7073 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7074 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7075 SourceLocation EndLoc,
7076 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7080 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7081 // 1.2.2 OpenMP Language Terminology
7082 // Structured block - An executable statement with a single entry at the
7083 // top and a single exit at the bottom.
7084 // The point of exit cannot be a branch out of the structured block.
7085 // longjmp() and throw() must not violate the entry/exit criteria.
7086 CS->getCapturedDecl()->setNothrow();
7087 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7088 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7089 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7090 // 1.2.2 OpenMP Language Terminology
7091 // Structured block - An executable statement with a single entry at the
7092 // top and a single exit at the bottom.
7093 // The point of exit cannot be a branch out of the structured block.
7094 // longjmp() and throw() must not violate the entry/exit criteria.
7095 CS->getCapturedDecl()->setNothrow();
7098 OMPLoopDirective::HelperExprs B;
7099 // In presence of clause 'collapse' with number of loops, it will
7100 // define the nested loops number.
7101 unsigned NestedLoopCount =
7102 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7103 nullptr /*ordered not a clause on distribute*/, CS, *this,
7104 *DSAStack, VarsWithImplicitDSA, B);
7105 if (NestedLoopCount == 0)
7108 assert((CurContext->isDependentContext() || B.builtAll()) &&
7109 "omp teams distribute loop exprs were not built");
7111 getCurFunction()->setHasBranchProtectedScope();
7113 DSAStack->setParentTeamsRegionLoc(StartLoc);
7115 return OMPTeamsDistributeDirective::Create(
7116 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7119 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7120 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7121 SourceLocation EndLoc,
7122 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7126 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7127 // 1.2.2 OpenMP Language Terminology
7128 // Structured block - An executable statement with a single entry at the
7129 // top and a single exit at the bottom.
7130 // The point of exit cannot be a branch out of the structured block.
7131 // longjmp() and throw() must not violate the entry/exit criteria.
7132 CS->getCapturedDecl()->setNothrow();
7133 for (int ThisCaptureLevel =
7134 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7135 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7136 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7137 // 1.2.2 OpenMP Language Terminology
7138 // Structured block - An executable statement with a single entry at the
7139 // top and a single exit at the bottom.
7140 // The point of exit cannot be a branch out of the structured block.
7141 // longjmp() and throw() must not violate the entry/exit criteria.
7142 CS->getCapturedDecl()->setNothrow();
7146 OMPLoopDirective::HelperExprs B;
7147 // In presence of clause 'collapse' with number of loops, it will
7148 // define the nested loops number.
7149 unsigned NestedLoopCount = CheckOpenMPLoop(
7150 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7151 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7152 VarsWithImplicitDSA, B);
7154 if (NestedLoopCount == 0)
7157 assert((CurContext->isDependentContext() || B.builtAll()) &&
7158 "omp teams distribute simd loop exprs were not built");
7160 if (!CurContext->isDependentContext()) {
7161 // Finalize the clauses that need pre-built expressions for CodeGen.
7162 for (auto C : Clauses) {
7163 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7165 B.NumIterations, *this, CurScope,
7171 if (checkSimdlenSafelenSpecified(*this, Clauses))
7174 getCurFunction()->setHasBranchProtectedScope();
7176 DSAStack->setParentTeamsRegionLoc(StartLoc);
7178 return OMPTeamsDistributeSimdDirective::Create(
7179 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7182 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7184 SourceLocation EndLoc,
7185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7189 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7190 // 1.2.2 OpenMP Language Terminology
7191 // Structured block - An executable statement with a single entry at the
7192 // top and a single exit at the bottom.
7193 // The point of exit cannot be a branch out of the structured block.
7194 // longjmp() and throw() must not violate the entry/exit criteria.
7195 CS->getCapturedDecl()->setNothrow();
7197 for (int ThisCaptureLevel =
7198 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7199 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7200 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7201 // 1.2.2 OpenMP Language Terminology
7202 // Structured block - An executable statement with a single entry at the
7203 // top and a single exit at the bottom.
7204 // The point of exit cannot be a branch out of the structured block.
7205 // longjmp() and throw() must not violate the entry/exit criteria.
7206 CS->getCapturedDecl()->setNothrow();
7209 OMPLoopDirective::HelperExprs B;
7210 // In presence of clause 'collapse' with number of loops, it will
7211 // define the nested loops number.
7212 auto NestedLoopCount = CheckOpenMPLoop(
7213 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7214 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7215 VarsWithImplicitDSA, B);
7217 if (NestedLoopCount == 0)
7220 assert((CurContext->isDependentContext() || B.builtAll()) &&
7221 "omp for loop exprs were not built");
7223 if (!CurContext->isDependentContext()) {
7224 // Finalize the clauses that need pre-built expressions for CodeGen.
7225 for (auto C : Clauses) {
7226 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7227 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7228 B.NumIterations, *this, CurScope,
7234 if (checkSimdlenSafelenSpecified(*this, Clauses))
7237 getCurFunction()->setHasBranchProtectedScope();
7239 DSAStack->setParentTeamsRegionLoc(StartLoc);
7241 return OMPTeamsDistributeParallelForSimdDirective::Create(
7242 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7245 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7246 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7247 SourceLocation EndLoc,
7248 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7252 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7253 // 1.2.2 OpenMP Language Terminology
7254 // Structured block - An executable statement with a single entry at the
7255 // top and a single exit at the bottom.
7256 // The point of exit cannot be a branch out of the structured block.
7257 // longjmp() and throw() must not violate the entry/exit criteria.
7258 CS->getCapturedDecl()->setNothrow();
7260 for (int ThisCaptureLevel =
7261 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7262 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7263 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7264 // 1.2.2 OpenMP Language Terminology
7265 // Structured block - An executable statement with a single entry at the
7266 // top and a single exit at the bottom.
7267 // The point of exit cannot be a branch out of the structured block.
7268 // longjmp() and throw() must not violate the entry/exit criteria.
7269 CS->getCapturedDecl()->setNothrow();
7272 OMPLoopDirective::HelperExprs B;
7273 // In presence of clause 'collapse' with number of loops, it will
7274 // define the nested loops number.
7275 unsigned NestedLoopCount = CheckOpenMPLoop(
7276 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7277 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7278 VarsWithImplicitDSA, B);
7280 if (NestedLoopCount == 0)
7283 assert((CurContext->isDependentContext() || B.builtAll()) &&
7284 "omp for loop exprs were not built");
7286 getCurFunction()->setHasBranchProtectedScope();
7288 DSAStack->setParentTeamsRegionLoc(StartLoc);
7290 return OMPTeamsDistributeParallelForDirective::Create(
7291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7292 DSAStack->isCancelRegion());
7295 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7297 SourceLocation StartLoc,
7298 SourceLocation EndLoc) {
7302 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7303 // 1.2.2 OpenMP Language Terminology
7304 // Structured block - An executable statement with a single entry at the
7305 // top and a single exit at the bottom.
7306 // The point of exit cannot be a branch out of the structured block.
7307 // longjmp() and throw() must not violate the entry/exit criteria.
7308 CS->getCapturedDecl()->setNothrow();
7310 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7311 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7312 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7313 // 1.2.2 OpenMP Language Terminology
7314 // Structured block - An executable statement with a single entry at the
7315 // top and a single exit at the bottom.
7316 // The point of exit cannot be a branch out of the structured block.
7317 // longjmp() and throw() must not violate the entry/exit criteria.
7318 CS->getCapturedDecl()->setNothrow();
7320 getCurFunction()->setHasBranchProtectedScope();
7322 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7326 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7328 SourceLocation EndLoc,
7329 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7333 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7334 // 1.2.2 OpenMP Language Terminology
7335 // Structured block - An executable statement with a single entry at the
7336 // top and a single exit at the bottom.
7337 // The point of exit cannot be a branch out of the structured block.
7338 // longjmp() and throw() must not violate the entry/exit criteria.
7339 CS->getCapturedDecl()->setNothrow();
7340 for (int ThisCaptureLevel =
7341 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7342 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7343 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7344 // 1.2.2 OpenMP Language Terminology
7345 // Structured block - An executable statement with a single entry at the
7346 // top and a single exit at the bottom.
7347 // The point of exit cannot be a branch out of the structured block.
7348 // longjmp() and throw() must not violate the entry/exit criteria.
7349 CS->getCapturedDecl()->setNothrow();
7352 OMPLoopDirective::HelperExprs B;
7353 // In presence of clause 'collapse' with number of loops, it will
7354 // define the nested loops number.
7355 auto NestedLoopCount = CheckOpenMPLoop(
7356 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7357 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7358 VarsWithImplicitDSA, B);
7359 if (NestedLoopCount == 0)
7362 assert((CurContext->isDependentContext() || B.builtAll()) &&
7363 "omp target teams distribute loop exprs were not built");
7365 getCurFunction()->setHasBranchProtectedScope();
7366 return OMPTargetTeamsDistributeDirective::Create(
7367 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7370 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
7371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7372 SourceLocation EndLoc,
7373 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7377 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7378 // 1.2.2 OpenMP Language Terminology
7379 // Structured block - An executable statement with a single entry at the
7380 // top and a single exit at the bottom.
7381 // The point of exit cannot be a branch out of the structured block.
7382 // longjmp() and throw() must not violate the entry/exit criteria.
7383 CS->getCapturedDecl()->setNothrow();
7385 OMPLoopDirective::HelperExprs B;
7386 // In presence of clause 'collapse' with number of loops, it will
7387 // define the nested loops number.
7388 auto NestedLoopCount = CheckOpenMPLoop(
7389 OMPD_target_teams_distribute_parallel_for,
7390 getCollapseNumberExpr(Clauses),
7391 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7392 VarsWithImplicitDSA, B);
7393 if (NestedLoopCount == 0)
7396 assert((CurContext->isDependentContext() || B.builtAll()) &&
7397 "omp target teams distribute parallel for loop exprs were not built");
7399 getCurFunction()->setHasBranchProtectedScope();
7400 return OMPTargetTeamsDistributeParallelForDirective::Create(
7401 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7402 DSAStack->isCancelRegion());
7405 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
7406 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7407 SourceLocation EndLoc,
7408 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7412 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7413 // 1.2.2 OpenMP Language Terminology
7414 // Structured block - An executable statement with a single entry at the
7415 // top and a single exit at the bottom.
7416 // The point of exit cannot be a branch out of the structured block.
7417 // longjmp() and throw() must not violate the entry/exit criteria.
7418 CS->getCapturedDecl()->setNothrow();
7420 OMPLoopDirective::HelperExprs B;
7421 // In presence of clause 'collapse' with number of loops, it will
7422 // define the nested loops number.
7423 auto NestedLoopCount = CheckOpenMPLoop(
7424 OMPD_target_teams_distribute_parallel_for_simd,
7425 getCollapseNumberExpr(Clauses),
7426 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7427 VarsWithImplicitDSA, B);
7428 if (NestedLoopCount == 0)
7431 assert((CurContext->isDependentContext() || B.builtAll()) &&
7432 "omp target teams distribute parallel for simd loop exprs were not "
7435 if (!CurContext->isDependentContext()) {
7436 // Finalize the clauses that need pre-built expressions for CodeGen.
7437 for (auto C : Clauses) {
7438 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7439 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7440 B.NumIterations, *this, CurScope,
7446 if (checkSimdlenSafelenSpecified(*this, Clauses))
7449 getCurFunction()->setHasBranchProtectedScope();
7450 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
7451 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7454 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
7455 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7456 SourceLocation EndLoc,
7457 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7461 auto *CS = cast<CapturedStmt>(AStmt);
7462 // 1.2.2 OpenMP Language Terminology
7463 // Structured block - An executable statement with a single entry at the
7464 // top and a single exit at the bottom.
7465 // The point of exit cannot be a branch out of the structured block.
7466 // longjmp() and throw() must not violate the entry/exit criteria.
7467 CS->getCapturedDecl()->setNothrow();
7468 for (int ThisCaptureLevel =
7469 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7470 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7471 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7472 // 1.2.2 OpenMP Language Terminology
7473 // Structured block - An executable statement with a single entry at the
7474 // top and a single exit at the bottom.
7475 // The point of exit cannot be a branch out of the structured block.
7476 // longjmp() and throw() must not violate the entry/exit criteria.
7477 CS->getCapturedDecl()->setNothrow();
7480 OMPLoopDirective::HelperExprs B;
7481 // In presence of clause 'collapse' with number of loops, it will
7482 // define the nested loops number.
7483 auto NestedLoopCount = CheckOpenMPLoop(
7484 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7485 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7486 VarsWithImplicitDSA, B);
7487 if (NestedLoopCount == 0)
7490 assert((CurContext->isDependentContext() || B.builtAll()) &&
7491 "omp target teams distribute simd loop exprs were not built");
7493 if (!CurContext->isDependentContext()) {
7494 // Finalize the clauses that need pre-built expressions for CodeGen.
7495 for (auto C : Clauses) {
7496 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7497 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7498 B.NumIterations, *this, CurScope,
7504 if (checkSimdlenSafelenSpecified(*this, Clauses))
7507 getCurFunction()->setHasBranchProtectedScope();
7508 return OMPTargetTeamsDistributeSimdDirective::Create(
7509 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7512 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
7513 SourceLocation StartLoc,
7514 SourceLocation LParenLoc,
7515 SourceLocation EndLoc) {
7516 OMPClause *Res = nullptr;
7519 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7521 case OMPC_num_threads:
7522 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7525 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7528 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7531 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7534 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7537 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7539 case OMPC_num_teams:
7540 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7542 case OMPC_thread_limit:
7543 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7546 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7548 case OMPC_grainsize:
7549 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7551 case OMPC_num_tasks:
7552 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7555 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7559 case OMPC_proc_bind:
7562 case OMPC_firstprivate:
7563 case OMPC_lastprivate:
7565 case OMPC_reduction:
7566 case OMPC_task_reduction:
7567 case OMPC_in_reduction:
7571 case OMPC_copyprivate:
7574 case OMPC_mergeable:
7575 case OMPC_threadprivate:
7587 case OMPC_dist_schedule:
7588 case OMPC_defaultmap:
7593 case OMPC_use_device_ptr:
7594 case OMPC_is_device_ptr:
7595 llvm_unreachable("Clause is not allowed.");
7600 // An OpenMP directive such as 'target parallel' has two captured regions:
7601 // for the 'target' and 'parallel' respectively. This function returns
7602 // the region in which to capture expressions associated with a clause.
7603 // A return value of OMPD_unknown signifies that the expression should not
7605 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
7606 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
7607 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7608 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7612 case OMPD_target_parallel:
7613 case OMPD_target_parallel_for:
7614 case OMPD_target_parallel_for_simd:
7615 case OMPD_target_teams_distribute_parallel_for:
7616 case OMPD_target_teams_distribute_parallel_for_simd:
7617 // If this clause applies to the nested 'parallel' region, capture within
7618 // the 'target' region, otherwise do not capture.
7619 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7620 CaptureRegion = OMPD_target;
7622 case OMPD_teams_distribute_parallel_for:
7623 case OMPD_teams_distribute_parallel_for_simd:
7624 CaptureRegion = OMPD_teams;
7626 case OMPD_target_update:
7627 case OMPD_target_enter_data:
7628 case OMPD_target_exit_data:
7629 CaptureRegion = OMPD_task;
7633 case OMPD_parallel_sections:
7634 case OMPD_parallel_for:
7635 case OMPD_parallel_for_simd:
7637 case OMPD_target_simd:
7638 case OMPD_target_teams:
7639 case OMPD_target_teams_distribute:
7640 case OMPD_target_teams_distribute_simd:
7641 case OMPD_distribute_parallel_for:
7642 case OMPD_distribute_parallel_for_simd:
7645 case OMPD_taskloop_simd:
7646 case OMPD_target_data:
7647 // Do not capture if-clause expressions.
7649 case OMPD_threadprivate:
7650 case OMPD_taskyield:
7653 case OMPD_cancellation_point:
7655 case OMPD_declare_reduction:
7656 case OMPD_declare_simd:
7657 case OMPD_declare_target:
7658 case OMPD_end_declare_target:
7668 case OMPD_taskgroup:
7669 case OMPD_distribute:
7672 case OMPD_distribute_simd:
7673 case OMPD_teams_distribute:
7674 case OMPD_teams_distribute_simd:
7675 llvm_unreachable("Unexpected OpenMP directive with if-clause");
7677 llvm_unreachable("Unknown OpenMP directive");
7680 case OMPC_num_threads:
7682 case OMPD_target_parallel:
7683 case OMPD_target_parallel_for:
7684 case OMPD_target_parallel_for_simd:
7685 case OMPD_target_teams_distribute_parallel_for:
7686 case OMPD_target_teams_distribute_parallel_for_simd:
7687 CaptureRegion = OMPD_target;
7689 case OMPD_teams_distribute_parallel_for:
7690 case OMPD_teams_distribute_parallel_for_simd:
7691 CaptureRegion = OMPD_teams;
7694 case OMPD_parallel_sections:
7695 case OMPD_parallel_for:
7696 case OMPD_parallel_for_simd:
7697 case OMPD_distribute_parallel_for:
7698 case OMPD_distribute_parallel_for_simd:
7699 // Do not capture num_threads-clause expressions.
7701 case OMPD_target_data:
7702 case OMPD_target_enter_data:
7703 case OMPD_target_exit_data:
7704 case OMPD_target_update:
7706 case OMPD_target_simd:
7707 case OMPD_target_teams:
7708 case OMPD_target_teams_distribute:
7709 case OMPD_target_teams_distribute_simd:
7713 case OMPD_taskloop_simd:
7714 case OMPD_threadprivate:
7715 case OMPD_taskyield:
7718 case OMPD_cancellation_point:
7720 case OMPD_declare_reduction:
7721 case OMPD_declare_simd:
7722 case OMPD_declare_target:
7723 case OMPD_end_declare_target:
7733 case OMPD_taskgroup:
7734 case OMPD_distribute:
7737 case OMPD_distribute_simd:
7738 case OMPD_teams_distribute:
7739 case OMPD_teams_distribute_simd:
7740 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
7742 llvm_unreachable("Unknown OpenMP directive");
7745 case OMPC_num_teams:
7747 case OMPD_target_teams:
7748 case OMPD_target_teams_distribute:
7749 case OMPD_target_teams_distribute_simd:
7750 case OMPD_target_teams_distribute_parallel_for:
7751 case OMPD_target_teams_distribute_parallel_for_simd:
7752 CaptureRegion = OMPD_target;
7754 case OMPD_teams_distribute_parallel_for:
7755 case OMPD_teams_distribute_parallel_for_simd:
7757 case OMPD_teams_distribute:
7758 case OMPD_teams_distribute_simd:
7759 // Do not capture num_teams-clause expressions.
7761 case OMPD_distribute_parallel_for:
7762 case OMPD_distribute_parallel_for_simd:
7765 case OMPD_taskloop_simd:
7766 case OMPD_target_data:
7767 case OMPD_target_enter_data:
7768 case OMPD_target_exit_data:
7769 case OMPD_target_update:
7772 case OMPD_parallel_sections:
7773 case OMPD_parallel_for:
7774 case OMPD_parallel_for_simd:
7776 case OMPD_target_simd:
7777 case OMPD_target_parallel:
7778 case OMPD_target_parallel_for:
7779 case OMPD_target_parallel_for_simd:
7780 case OMPD_threadprivate:
7781 case OMPD_taskyield:
7784 case OMPD_cancellation_point:
7786 case OMPD_declare_reduction:
7787 case OMPD_declare_simd:
7788 case OMPD_declare_target:
7789 case OMPD_end_declare_target:
7798 case OMPD_taskgroup:
7799 case OMPD_distribute:
7802 case OMPD_distribute_simd:
7803 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
7805 llvm_unreachable("Unknown OpenMP directive");
7808 case OMPC_thread_limit:
7810 case OMPD_target_teams:
7811 case OMPD_target_teams_distribute:
7812 case OMPD_target_teams_distribute_simd:
7813 case OMPD_target_teams_distribute_parallel_for:
7814 case OMPD_target_teams_distribute_parallel_for_simd:
7815 CaptureRegion = OMPD_target;
7817 case OMPD_teams_distribute_parallel_for:
7818 case OMPD_teams_distribute_parallel_for_simd:
7820 case OMPD_teams_distribute:
7821 case OMPD_teams_distribute_simd:
7822 // Do not capture thread_limit-clause expressions.
7824 case OMPD_distribute_parallel_for:
7825 case OMPD_distribute_parallel_for_simd:
7828 case OMPD_taskloop_simd:
7829 case OMPD_target_data:
7830 case OMPD_target_enter_data:
7831 case OMPD_target_exit_data:
7832 case OMPD_target_update:
7835 case OMPD_parallel_sections:
7836 case OMPD_parallel_for:
7837 case OMPD_parallel_for_simd:
7839 case OMPD_target_simd:
7840 case OMPD_target_parallel:
7841 case OMPD_target_parallel_for:
7842 case OMPD_target_parallel_for_simd:
7843 case OMPD_threadprivate:
7844 case OMPD_taskyield:
7847 case OMPD_cancellation_point:
7849 case OMPD_declare_reduction:
7850 case OMPD_declare_simd:
7851 case OMPD_declare_target:
7852 case OMPD_end_declare_target:
7861 case OMPD_taskgroup:
7862 case OMPD_distribute:
7865 case OMPD_distribute_simd:
7866 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
7868 llvm_unreachable("Unknown OpenMP directive");
7873 case OMPD_target_parallel_for:
7874 case OMPD_target_parallel_for_simd:
7875 case OMPD_target_teams_distribute_parallel_for:
7876 case OMPD_target_teams_distribute_parallel_for_simd:
7877 CaptureRegion = OMPD_target;
7879 case OMPD_teams_distribute_parallel_for:
7880 case OMPD_teams_distribute_parallel_for_simd:
7881 CaptureRegion = OMPD_teams;
7883 case OMPD_parallel_for:
7884 case OMPD_parallel_for_simd:
7885 case OMPD_distribute_parallel_for:
7886 case OMPD_distribute_parallel_for_simd:
7887 CaptureRegion = OMPD_parallel;
7891 // Do not capture schedule-clause expressions.
7895 case OMPD_taskloop_simd:
7896 case OMPD_target_data:
7897 case OMPD_target_enter_data:
7898 case OMPD_target_exit_data:
7899 case OMPD_target_update:
7901 case OMPD_teams_distribute:
7902 case OMPD_teams_distribute_simd:
7903 case OMPD_target_teams_distribute:
7904 case OMPD_target_teams_distribute_simd:
7906 case OMPD_target_simd:
7907 case OMPD_target_parallel:
7910 case OMPD_parallel_sections:
7911 case OMPD_threadprivate:
7912 case OMPD_taskyield:
7915 case OMPD_cancellation_point:
7917 case OMPD_declare_reduction:
7918 case OMPD_declare_simd:
7919 case OMPD_declare_target:
7920 case OMPD_end_declare_target:
7927 case OMPD_taskgroup:
7928 case OMPD_distribute:
7931 case OMPD_distribute_simd:
7932 case OMPD_target_teams:
7933 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
7935 llvm_unreachable("Unknown OpenMP directive");
7938 case OMPC_dist_schedule:
7940 case OMPD_teams_distribute_parallel_for:
7941 case OMPD_teams_distribute_parallel_for_simd:
7942 case OMPD_teams_distribute:
7943 case OMPD_teams_distribute_simd:
7944 CaptureRegion = OMPD_teams;
7946 case OMPD_target_teams_distribute_parallel_for:
7947 case OMPD_target_teams_distribute_parallel_for_simd:
7948 case OMPD_target_teams_distribute:
7949 case OMPD_target_teams_distribute_simd:
7950 CaptureRegion = OMPD_target;
7952 case OMPD_distribute_parallel_for:
7953 case OMPD_distribute_parallel_for_simd:
7954 CaptureRegion = OMPD_parallel;
7956 case OMPD_distribute:
7957 case OMPD_distribute_simd:
7958 // Do not capture thread_limit-clause expressions.
7960 case OMPD_parallel_for:
7961 case OMPD_parallel_for_simd:
7962 case OMPD_target_parallel_for_simd:
7963 case OMPD_target_parallel_for:
7966 case OMPD_taskloop_simd:
7967 case OMPD_target_data:
7968 case OMPD_target_enter_data:
7969 case OMPD_target_exit_data:
7970 case OMPD_target_update:
7973 case OMPD_target_simd:
7974 case OMPD_target_parallel:
7977 case OMPD_parallel_sections:
7978 case OMPD_threadprivate:
7979 case OMPD_taskyield:
7982 case OMPD_cancellation_point:
7984 case OMPD_declare_reduction:
7985 case OMPD_declare_simd:
7986 case OMPD_declare_target:
7987 case OMPD_end_declare_target:
7996 case OMPD_taskgroup:
7999 case OMPD_target_teams:
8000 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8002 llvm_unreachable("Unknown OpenMP directive");
8007 case OMPD_target_update:
8008 case OMPD_target_enter_data:
8009 case OMPD_target_exit_data:
8010 CaptureRegion = OMPD_task;
8012 case OMPD_target_teams:
8013 case OMPD_target_teams_distribute:
8014 case OMPD_target_teams_distribute_simd:
8015 case OMPD_target_teams_distribute_parallel_for:
8016 case OMPD_target_teams_distribute_parallel_for_simd:
8017 case OMPD_target_data:
8019 case OMPD_target_simd:
8020 case OMPD_target_parallel:
8021 case OMPD_target_parallel_for:
8022 case OMPD_target_parallel_for_simd:
8023 // Do not capture device-clause expressions.
8025 case OMPD_teams_distribute_parallel_for:
8026 case OMPD_teams_distribute_parallel_for_simd:
8028 case OMPD_teams_distribute:
8029 case OMPD_teams_distribute_simd:
8030 case OMPD_distribute_parallel_for:
8031 case OMPD_distribute_parallel_for_simd:
8034 case OMPD_taskloop_simd:
8037 case OMPD_parallel_sections:
8038 case OMPD_parallel_for:
8039 case OMPD_parallel_for_simd:
8040 case OMPD_threadprivate:
8041 case OMPD_taskyield:
8044 case OMPD_cancellation_point:
8046 case OMPD_declare_reduction:
8047 case OMPD_declare_simd:
8048 case OMPD_declare_target:
8049 case OMPD_end_declare_target:
8058 case OMPD_taskgroup:
8059 case OMPD_distribute:
8062 case OMPD_distribute_simd:
8063 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8065 llvm_unreachable("Unknown OpenMP directive");
8068 case OMPC_firstprivate:
8069 case OMPC_lastprivate:
8070 case OMPC_reduction:
8071 case OMPC_task_reduction:
8072 case OMPC_in_reduction:
8075 case OMPC_proc_bind:
8084 case OMPC_copyprivate:
8088 case OMPC_mergeable:
8089 case OMPC_threadprivate:
8101 case OMPC_grainsize:
8103 case OMPC_num_tasks:
8105 case OMPC_defaultmap:
8110 case OMPC_use_device_ptr:
8111 case OMPC_is_device_ptr:
8112 llvm_unreachable("Unexpected OpenMP clause.");
8114 return CaptureRegion;
8117 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
8118 Expr *Condition, SourceLocation StartLoc,
8119 SourceLocation LParenLoc,
8120 SourceLocation NameModifierLoc,
8121 SourceLocation ColonLoc,
8122 SourceLocation EndLoc) {
8123 Expr *ValExpr = Condition;
8124 Stmt *HelperValStmt = nullptr;
8125 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8126 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8127 !Condition->isInstantiationDependent() &&
8128 !Condition->containsUnexpandedParameterPack()) {
8129 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8130 if (Val.isInvalid())
8133 ValExpr = Val.get();
8135 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8137 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8138 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8139 ValExpr = MakeFullExpr(ValExpr).get();
8140 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8141 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8142 HelperValStmt = buildPreInits(Context, Captures);
8146 return new (Context)
8147 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8148 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8151 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
8152 SourceLocation StartLoc,
8153 SourceLocation LParenLoc,
8154 SourceLocation EndLoc) {
8155 Expr *ValExpr = Condition;
8156 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8157 !Condition->isInstantiationDependent() &&
8158 !Condition->containsUnexpandedParameterPack()) {
8159 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8160 if (Val.isInvalid())
8163 ValExpr = MakeFullExpr(Val.get()).get();
8166 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8168 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
8173 class IntConvertDiagnoser : public ICEConvertDiagnoser {
8175 IntConvertDiagnoser()
8176 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8177 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8178 QualType T) override {
8179 return S.Diag(Loc, diag::err_omp_not_integral) << T;
8181 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8182 QualType T) override {
8183 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8185 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8187 QualType ConvTy) override {
8188 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8190 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8191 QualType ConvTy) override {
8192 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8193 << ConvTy->isEnumeralType() << ConvTy;
8195 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8196 QualType T) override {
8197 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8199 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8200 QualType ConvTy) override {
8201 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8202 << ConvTy->isEnumeralType() << ConvTy;
8204 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8205 QualType) override {
8206 llvm_unreachable("conversion functions are permitted");
8209 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8212 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8213 OpenMPClauseKind CKind,
8214 bool StrictlyPositive) {
8215 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8216 !ValExpr->isInstantiationDependent()) {
8217 SourceLocation Loc = ValExpr->getExprLoc();
8219 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8220 if (Value.isInvalid())
8223 ValExpr = Value.get();
8224 // The expression must evaluate to a non-negative integer value.
8225 llvm::APSInt Result;
8226 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8227 Result.isSigned() &&
8228 !((!StrictlyPositive && Result.isNonNegative()) ||
8229 (StrictlyPositive && Result.isStrictlyPositive()))) {
8230 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8231 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8232 << ValExpr->getSourceRange();
8239 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
8240 SourceLocation StartLoc,
8241 SourceLocation LParenLoc,
8242 SourceLocation EndLoc) {
8243 Expr *ValExpr = NumThreads;
8244 Stmt *HelperValStmt = nullptr;
8246 // OpenMP [2.5, Restrictions]
8247 // The num_threads expression must evaluate to a positive integer value.
8248 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8249 /*StrictlyPositive=*/true))
8252 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8253 OpenMPDirectiveKind CaptureRegion =
8254 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8255 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8256 ValExpr = MakeFullExpr(ValExpr).get();
8257 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8258 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8259 HelperValStmt = buildPreInits(Context, Captures);
8262 return new (Context) OMPNumThreadsClause(
8263 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8266 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8267 OpenMPClauseKind CKind,
8268 bool StrictlyPositive) {
8271 if (E->isValueDependent() || E->isTypeDependent() ||
8272 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
8274 llvm::APSInt Result;
8275 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8276 if (ICE.isInvalid())
8278 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8279 (!StrictlyPositive && !Result.isNonNegative())) {
8280 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8281 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8282 << E->getSourceRange();
8285 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8286 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8287 << E->getSourceRange();
8290 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
8291 DSAStack->setAssociatedLoops(Result.getExtValue());
8292 else if (CKind == OMPC_ordered)
8293 DSAStack->setAssociatedLoops(Result.getExtValue());
8297 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
8298 SourceLocation LParenLoc,
8299 SourceLocation EndLoc) {
8300 // OpenMP [2.8.1, simd construct, Description]
8301 // The parameter of the safelen clause must be a constant
8302 // positive integer expression.
8303 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8304 if (Safelen.isInvalid())
8306 return new (Context)
8307 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8310 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
8311 SourceLocation LParenLoc,
8312 SourceLocation EndLoc) {
8313 // OpenMP [2.8.1, simd construct, Description]
8314 // The parameter of the simdlen clause must be a constant
8315 // positive integer expression.
8316 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8317 if (Simdlen.isInvalid())
8319 return new (Context)
8320 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8323 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
8324 SourceLocation StartLoc,
8325 SourceLocation LParenLoc,
8326 SourceLocation EndLoc) {
8327 // OpenMP [2.7.1, loop construct, Description]
8328 // OpenMP [2.8.1, simd construct, Description]
8329 // OpenMP [2.9.6, distribute construct, Description]
8330 // The parameter of the collapse clause must be a constant
8331 // positive integer expression.
8332 ExprResult NumForLoopsResult =
8333 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8334 if (NumForLoopsResult.isInvalid())
8336 return new (Context)
8337 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8340 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
8341 SourceLocation EndLoc,
8342 SourceLocation LParenLoc,
8343 Expr *NumForLoops) {
8344 // OpenMP [2.7.1, loop construct, Description]
8345 // OpenMP [2.8.1, simd construct, Description]
8346 // OpenMP [2.9.6, distribute construct, Description]
8347 // The parameter of the ordered clause must be a constant
8348 // positive integer expression if any.
8349 if (NumForLoops && LParenLoc.isValid()) {
8350 ExprResult NumForLoopsResult =
8351 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8352 if (NumForLoopsResult.isInvalid())
8354 NumForLoops = NumForLoopsResult.get();
8356 NumForLoops = nullptr;
8357 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
8358 return new (Context)
8359 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
8362 OMPClause *Sema::ActOnOpenMPSimpleClause(
8363 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8364 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8365 OMPClause *Res = nullptr;
8369 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8370 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8372 case OMPC_proc_bind:
8373 Res = ActOnOpenMPProcBindClause(
8374 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8379 case OMPC_num_threads:
8385 case OMPC_firstprivate:
8386 case OMPC_lastprivate:
8388 case OMPC_reduction:
8389 case OMPC_task_reduction:
8390 case OMPC_in_reduction:
8394 case OMPC_copyprivate:
8398 case OMPC_mergeable:
8399 case OMPC_threadprivate:
8411 case OMPC_num_teams:
8412 case OMPC_thread_limit:
8414 case OMPC_grainsize:
8416 case OMPC_num_tasks:
8418 case OMPC_dist_schedule:
8419 case OMPC_defaultmap:
8424 case OMPC_use_device_ptr:
8425 case OMPC_is_device_ptr:
8426 llvm_unreachable("Clause is not allowed.");
8432 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
8433 ArrayRef<unsigned> Exclude = llvm::None) {
8435 unsigned Bound = Last >= 2 ? Last - 2 : 0;
8436 unsigned Skipped = Exclude.size();
8437 auto S = Exclude.begin(), E = Exclude.end();
8438 for (unsigned i = First; i < Last; ++i) {
8439 if (std::find(S, E, i) != E) {
8444 Values += getOpenMPSimpleClauseTypeName(K, i);
8446 if (i == Bound - Skipped)
8448 else if (i != Bound + 1 - Skipped)
8454 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
8455 SourceLocation KindKwLoc,
8456 SourceLocation StartLoc,
8457 SourceLocation LParenLoc,
8458 SourceLocation EndLoc) {
8459 if (Kind == OMPC_DEFAULT_unknown) {
8460 static_assert(OMPC_DEFAULT_unknown > 0,
8461 "OMPC_DEFAULT_unknown not greater than 0");
8462 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8463 << getListOfPossibleValues(OMPC_default, /*First=*/0,
8464 /*Last=*/OMPC_DEFAULT_unknown)
8465 << getOpenMPClauseName(OMPC_default);
8469 case OMPC_DEFAULT_none:
8470 DSAStack->setDefaultDSANone(KindKwLoc);
8472 case OMPC_DEFAULT_shared:
8473 DSAStack->setDefaultDSAShared(KindKwLoc);
8475 case OMPC_DEFAULT_unknown:
8476 llvm_unreachable("Clause kind is not allowed.");
8479 return new (Context)
8480 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8483 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
8484 SourceLocation KindKwLoc,
8485 SourceLocation StartLoc,
8486 SourceLocation LParenLoc,
8487 SourceLocation EndLoc) {
8488 if (Kind == OMPC_PROC_BIND_unknown) {
8489 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8490 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8491 /*Last=*/OMPC_PROC_BIND_unknown)
8492 << getOpenMPClauseName(OMPC_proc_bind);
8495 return new (Context)
8496 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8499 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
8500 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
8501 SourceLocation StartLoc, SourceLocation LParenLoc,
8502 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8503 SourceLocation EndLoc) {
8504 OMPClause *Res = nullptr;
8507 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8508 assert(Argument.size() == NumberOfElements &&
8509 ArgumentLoc.size() == NumberOfElements);
8510 Res = ActOnOpenMPScheduleClause(
8511 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8512 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8513 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8514 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8515 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8518 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8519 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8520 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8523 case OMPC_dist_schedule:
8524 Res = ActOnOpenMPDistScheduleClause(
8525 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8526 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8528 case OMPC_defaultmap:
8529 enum { Modifier, DefaultmapKind };
8530 Res = ActOnOpenMPDefaultmapClause(
8531 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8532 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8533 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8537 case OMPC_num_threads:
8542 case OMPC_proc_bind:
8544 case OMPC_firstprivate:
8545 case OMPC_lastprivate:
8547 case OMPC_reduction:
8548 case OMPC_task_reduction:
8549 case OMPC_in_reduction:
8553 case OMPC_copyprivate:
8557 case OMPC_mergeable:
8558 case OMPC_threadprivate:
8570 case OMPC_num_teams:
8571 case OMPC_thread_limit:
8573 case OMPC_grainsize:
8575 case OMPC_num_tasks:
8581 case OMPC_use_device_ptr:
8582 case OMPC_is_device_ptr:
8583 llvm_unreachable("Clause is not allowed.");
8588 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
8589 OpenMPScheduleClauseModifier M2,
8590 SourceLocation M1Loc, SourceLocation M2Loc) {
8591 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8592 SmallVector<unsigned, 2> Excluded;
8593 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
8594 Excluded.push_back(M2);
8595 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8596 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8597 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8598 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8599 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8600 << getListOfPossibleValues(OMPC_schedule,
8601 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8602 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8604 << getOpenMPClauseName(OMPC_schedule);
8610 OMPClause *Sema::ActOnOpenMPScheduleClause(
8611 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
8612 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8613 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8614 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8615 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8616 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8618 // OpenMP, 2.7.1, Loop Construct, Restrictions
8619 // Either the monotonic modifier or the nonmonotonic modifier can be specified
8621 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8622 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8623 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8624 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8625 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8626 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8627 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8628 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8631 if (Kind == OMPC_SCHEDULE_unknown) {
8633 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8634 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8635 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8636 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8639 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8640 /*Last=*/OMPC_SCHEDULE_unknown);
8642 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8643 << Values << getOpenMPClauseName(OMPC_schedule);
8646 // OpenMP, 2.7.1, Loop Construct, Restrictions
8647 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
8648 // schedule(guided).
8649 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
8650 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
8651 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
8652 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
8653 diag::err_omp_schedule_nonmonotonic_static);
8656 Expr *ValExpr = ChunkSize;
8657 Stmt *HelperValStmt = nullptr;
8659 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
8660 !ChunkSize->isInstantiationDependent() &&
8661 !ChunkSize->containsUnexpandedParameterPack()) {
8662 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
8664 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
8665 if (Val.isInvalid())
8668 ValExpr = Val.get();
8670 // OpenMP [2.7.1, Restrictions]
8671 // chunk_size must be a loop invariant integer expression with a positive
8673 llvm::APSInt Result;
8674 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
8675 if (Result.isSigned() && !Result.isStrictlyPositive()) {
8676 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
8677 << "schedule" << 1 << ChunkSize->getSourceRange();
8680 } else if (getOpenMPCaptureRegionForClause(
8681 DSAStack->getCurrentDirective(), OMPC_schedule) !=
8683 !CurContext->isDependentContext()) {
8684 ValExpr = MakeFullExpr(ValExpr).get();
8685 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8687 HelperValStmt = buildPreInits(Context, Captures);
8692 return new (Context)
8693 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
8694 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
8697 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
8698 SourceLocation StartLoc,
8699 SourceLocation EndLoc) {
8700 OMPClause *Res = nullptr;
8703 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
8706 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
8709 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
8711 case OMPC_mergeable:
8712 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
8715 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
8718 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
8721 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
8724 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
8727 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
8730 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
8733 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
8736 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
8740 case OMPC_num_threads:
8746 case OMPC_firstprivate:
8747 case OMPC_lastprivate:
8749 case OMPC_reduction:
8750 case OMPC_task_reduction:
8751 case OMPC_in_reduction:
8755 case OMPC_copyprivate:
8757 case OMPC_proc_bind:
8758 case OMPC_threadprivate:
8763 case OMPC_num_teams:
8764 case OMPC_thread_limit:
8766 case OMPC_grainsize:
8767 case OMPC_num_tasks:
8769 case OMPC_dist_schedule:
8770 case OMPC_defaultmap:
8775 case OMPC_use_device_ptr:
8776 case OMPC_is_device_ptr:
8777 llvm_unreachable("Clause is not allowed.");
8782 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
8783 SourceLocation EndLoc) {
8784 DSAStack->setNowaitRegion();
8785 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
8788 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
8789 SourceLocation EndLoc) {
8790 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
8793 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
8794 SourceLocation EndLoc) {
8795 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
8798 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
8799 SourceLocation EndLoc) {
8800 return new (Context) OMPReadClause(StartLoc, EndLoc);
8803 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
8804 SourceLocation EndLoc) {
8805 return new (Context) OMPWriteClause(StartLoc, EndLoc);
8808 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
8809 SourceLocation EndLoc) {
8810 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
8813 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
8814 SourceLocation EndLoc) {
8815 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
8818 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
8819 SourceLocation EndLoc) {
8820 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
8823 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
8824 SourceLocation EndLoc) {
8825 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
8828 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
8829 SourceLocation EndLoc) {
8830 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
8833 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
8834 SourceLocation EndLoc) {
8835 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
8838 OMPClause *Sema::ActOnOpenMPVarListClause(
8839 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
8840 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
8841 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
8842 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
8843 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
8844 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
8845 SourceLocation DepLinMapLoc) {
8846 OMPClause *Res = nullptr;
8849 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8851 case OMPC_firstprivate:
8852 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8854 case OMPC_lastprivate:
8855 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8858 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
8860 case OMPC_reduction:
8861 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8862 EndLoc, ReductionIdScopeSpec, ReductionId);
8864 case OMPC_task_reduction:
8865 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8866 EndLoc, ReductionIdScopeSpec,
8869 case OMPC_in_reduction:
8871 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8872 EndLoc, ReductionIdScopeSpec, ReductionId);
8875 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
8876 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8879 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
8883 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
8885 case OMPC_copyprivate:
8886 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8889 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
8892 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
8893 StartLoc, LParenLoc, EndLoc);
8896 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
8897 DepLinMapLoc, ColonLoc, VarList, StartLoc,
8901 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
8904 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
8906 case OMPC_use_device_ptr:
8907 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8909 case OMPC_is_device_ptr:
8910 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8914 case OMPC_num_threads:
8919 case OMPC_proc_bind:
8924 case OMPC_mergeable:
8925 case OMPC_threadprivate:
8934 case OMPC_num_teams:
8935 case OMPC_thread_limit:
8937 case OMPC_grainsize:
8939 case OMPC_num_tasks:
8941 case OMPC_dist_schedule:
8942 case OMPC_defaultmap:
8945 llvm_unreachable("Clause is not allowed.");
8950 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
8951 ExprObjectKind OK, SourceLocation Loc) {
8952 ExprResult Res = BuildDeclRefExpr(
8953 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
8954 if (!Res.isUsable())
8956 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
8957 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
8958 if (!Res.isUsable())
8961 if (VK != VK_LValue && Res.get()->isGLValue()) {
8962 Res = DefaultLvalueConversion(Res.get());
8963 if (!Res.isUsable())
8969 static std::pair<ValueDecl *, bool>
8970 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
8971 SourceRange &ERange, bool AllowArraySection = false) {
8972 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
8973 RefExpr->containsUnexpandedParameterPack())
8974 return std::make_pair(nullptr, true);
8976 // OpenMP [3.1, C/C++]
8977 // A list item is a variable name.
8978 // OpenMP [2.9.3.3, Restrictions, p.1]
8979 // A variable that is part of another variable (as an array or
8980 // structure element) cannot appear in a private clause.
8981 RefExpr = RefExpr->IgnoreParens();
8986 } IsArrayExpr = NoArrayExpr;
8987 if (AllowArraySection) {
8988 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8989 auto *Base = ASE->getBase()->IgnoreParenImpCasts();
8990 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8991 Base = TempASE->getBase()->IgnoreParenImpCasts();
8993 IsArrayExpr = ArraySubscript;
8994 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8995 auto *Base = OASE->getBase()->IgnoreParenImpCasts();
8996 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
8997 Base = TempOASE->getBase()->IgnoreParenImpCasts();
8998 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8999 Base = TempASE->getBase()->IgnoreParenImpCasts();
9001 IsArrayExpr = OMPArraySection;
9004 ELoc = RefExpr->getExprLoc();
9005 ERange = RefExpr->getSourceRange();
9006 RefExpr = RefExpr->IgnoreParenImpCasts();
9007 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9008 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9009 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9010 (S.getCurrentThisType().isNull() || !ME ||
9011 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9012 !isa<FieldDecl>(ME->getMemberDecl()))) {
9013 if (IsArrayExpr != NoArrayExpr)
9014 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9019 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9020 : diag::err_omp_expected_var_name_member_expr)
9021 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9023 return std::make_pair(nullptr, false);
9025 return std::make_pair(
9026 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9029 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
9030 SourceLocation StartLoc,
9031 SourceLocation LParenLoc,
9032 SourceLocation EndLoc) {
9033 SmallVector<Expr *, 8> Vars;
9034 SmallVector<Expr *, 8> PrivateCopies;
9035 for (auto &RefExpr : VarList) {
9036 assert(RefExpr && "NULL expr in OpenMP private clause.");
9037 SourceLocation ELoc;
9039 Expr *SimpleRefExpr = RefExpr;
9040 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9042 // It will be analyzed later.
9043 Vars.push_back(RefExpr);
9044 PrivateCopies.push_back(nullptr);
9046 ValueDecl *D = Res.first;
9050 QualType Type = D->getType();
9051 auto *VD = dyn_cast<VarDecl>(D);
9053 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9054 // A variable that appears in a private clause must not have an incomplete
9055 // type or a reference type.
9056 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9058 Type = Type.getNonReferenceType();
9060 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9062 // Variables with the predetermined data-sharing attributes may not be
9063 // listed in data-sharing attributes clauses, except for the cases
9064 // listed below. For these exceptions only, listing a predetermined
9065 // variable in a data-sharing attribute clause is allowed and overrides
9066 // the variable's predetermined data-sharing attributes.
9067 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9068 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9069 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9070 << getOpenMPClauseName(OMPC_private);
9071 ReportOriginalDSA(*this, DSAStack, D, DVar);
9075 auto CurrDir = DSAStack->getCurrentDirective();
9076 // Variably modified types are not supported for tasks.
9077 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9078 isOpenMPTaskingDirective(CurrDir)) {
9079 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9080 << getOpenMPClauseName(OMPC_private) << Type
9081 << getOpenMPDirectiveName(CurrDir);
9084 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9085 Diag(D->getLocation(),
9086 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9091 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9092 // A list item cannot appear in both a map clause and a data-sharing
9093 // attribute clause on the same construct
9094 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
9095 CurrDir == OMPD_target_teams ||
9096 CurrDir == OMPD_target_teams_distribute ||
9097 CurrDir == OMPD_target_teams_distribute_parallel_for ||
9098 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
9099 CurrDir == OMPD_target_teams_distribute_simd ||
9100 CurrDir == OMPD_target_parallel_for_simd ||
9101 CurrDir == OMPD_target_parallel_for) {
9102 OpenMPClauseKind ConflictKind;
9103 if (DSAStack->checkMappableExprComponentListsForDecl(
9104 VD, /*CurrentRegionOnly=*/true,
9105 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9106 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9107 ConflictKind = WhereFoundClauseKind;
9110 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9111 << getOpenMPClauseName(OMPC_private)
9112 << getOpenMPClauseName(ConflictKind)
9113 << getOpenMPDirectiveName(CurrDir);
9114 ReportOriginalDSA(*this, DSAStack, D, DVar);
9119 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9120 // A variable of class type (or array thereof) that appears in a private
9121 // clause requires an accessible, unambiguous default constructor for the
9123 // Generate helper private variable and initialize it with the default
9124 // value. The address of the original variable is replaced by the address of
9125 // the new private variable in CodeGen. This new variable is not added to
9126 // IdResolver, so the code in the OpenMP region uses original variable for
9127 // proper diagnostics.
9128 Type = Type.getUnqualifiedType();
9129 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9130 D->hasAttrs() ? &D->getAttrs() : nullptr);
9131 ActOnUninitializedDecl(VDPrivate);
9132 if (VDPrivate->isInvalidDecl())
9134 auto VDPrivateRefExpr = buildDeclRefExpr(
9135 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9137 DeclRefExpr *Ref = nullptr;
9138 if (!VD && !CurContext->isDependentContext())
9139 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9140 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9141 Vars.push_back((VD || CurContext->isDependentContext())
9142 ? RefExpr->IgnoreParens()
9144 PrivateCopies.push_back(VDPrivateRefExpr);
9150 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9155 class DiagsUninitializedSeveretyRAII {
9157 DiagnosticsEngine &Diags;
9158 SourceLocation SavedLoc;
9162 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9164 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9166 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9167 /*Map*/ diag::Severity::Ignored, Loc);
9170 ~DiagsUninitializedSeveretyRAII() {
9172 Diags.popMappings(SavedLoc);
9177 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
9178 SourceLocation StartLoc,
9179 SourceLocation LParenLoc,
9180 SourceLocation EndLoc) {
9181 SmallVector<Expr *, 8> Vars;
9182 SmallVector<Expr *, 8> PrivateCopies;
9183 SmallVector<Expr *, 8> Inits;
9184 SmallVector<Decl *, 4> ExprCaptures;
9185 bool IsImplicitClause =
9186 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9187 auto ImplicitClauseLoc = DSAStack->getConstructLoc();
9189 for (auto &RefExpr : VarList) {
9190 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9191 SourceLocation ELoc;
9193 Expr *SimpleRefExpr = RefExpr;
9194 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9196 // It will be analyzed later.
9197 Vars.push_back(RefExpr);
9198 PrivateCopies.push_back(nullptr);
9199 Inits.push_back(nullptr);
9201 ValueDecl *D = Res.first;
9205 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9206 QualType Type = D->getType();
9207 auto *VD = dyn_cast<VarDecl>(D);
9209 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9210 // A variable that appears in a private clause must not have an incomplete
9211 // type or a reference type.
9212 if (RequireCompleteType(ELoc, Type,
9213 diag::err_omp_firstprivate_incomplete_type))
9215 Type = Type.getNonReferenceType();
9217 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9218 // A variable of class type (or array thereof) that appears in a private
9219 // clause requires an accessible, unambiguous copy constructor for the
9221 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9223 // If an implicit firstprivate variable found it was checked already.
9224 DSAStackTy::DSAVarData TopDVar;
9225 if (!IsImplicitClause) {
9226 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9228 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9229 bool IsConstant = ElemType.isConstant(Context);
9230 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9231 // A list item that specifies a given variable may not appear in more
9232 // than one clause on the same directive, except that a variable may be
9233 // specified in both firstprivate and lastprivate clauses.
9234 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9235 // A list item may appear in a firstprivate or lastprivate clause but not
9237 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9238 (isOpenMPDistributeDirective(CurrDir) ||
9239 DVar.CKind != OMPC_lastprivate) &&
9241 Diag(ELoc, diag::err_omp_wrong_dsa)
9242 << getOpenMPClauseName(DVar.CKind)
9243 << getOpenMPClauseName(OMPC_firstprivate);
9244 ReportOriginalDSA(*this, DSAStack, D, DVar);
9248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9250 // Variables with the predetermined data-sharing attributes may not be
9251 // listed in data-sharing attributes clauses, except for the cases
9252 // listed below. For these exceptions only, listing a predetermined
9253 // variable in a data-sharing attribute clause is allowed and overrides
9254 // the variable's predetermined data-sharing attributes.
9255 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9256 // in a Construct, C/C++, p.2]
9257 // Variables with const-qualified type having no mutable member may be
9258 // listed in a firstprivate clause, even if they are static data members.
9259 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9260 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9261 Diag(ELoc, diag::err_omp_wrong_dsa)
9262 << getOpenMPClauseName(DVar.CKind)
9263 << getOpenMPClauseName(OMPC_firstprivate);
9264 ReportOriginalDSA(*this, DSAStack, D, DVar);
9268 // OpenMP [2.9.3.4, Restrictions, p.2]
9269 // A list item that is private within a parallel region must not appear
9270 // in a firstprivate clause on a worksharing construct if any of the
9271 // worksharing regions arising from the worksharing construct ever bind
9272 // to any of the parallel regions arising from the parallel construct.
9273 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9274 // A list item that is private within a teams region must not appear in a
9275 // firstprivate clause on a distribute construct if any of the distribute
9276 // regions arising from the distribute construct ever bind to any of the
9277 // teams regions arising from the teams construct.
9278 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9279 // A list item that appears in a reduction clause of a teams construct
9280 // must not appear in a firstprivate clause on a distribute construct if
9281 // any of the distribute regions arising from the distribute construct
9282 // ever bind to any of the teams regions arising from the teams construct.
9283 if ((isOpenMPWorksharingDirective(CurrDir) ||
9284 isOpenMPDistributeDirective(CurrDir)) &&
9285 !isOpenMPParallelDirective(CurrDir) &&
9286 !isOpenMPTeamsDirective(CurrDir)) {
9287 DVar = DSAStack->getImplicitDSA(D, true);
9288 if (DVar.CKind != OMPC_shared &&
9289 (isOpenMPParallelDirective(DVar.DKind) ||
9290 isOpenMPTeamsDirective(DVar.DKind) ||
9291 DVar.DKind == OMPD_unknown)) {
9292 Diag(ELoc, diag::err_omp_required_access)
9293 << getOpenMPClauseName(OMPC_firstprivate)
9294 << getOpenMPClauseName(OMPC_shared);
9295 ReportOriginalDSA(*this, DSAStack, D, DVar);
9299 // OpenMP [2.9.3.4, Restrictions, p.3]
9300 // A list item that appears in a reduction clause of a parallel construct
9301 // must not appear in a firstprivate clause on a worksharing or task
9302 // construct if any of the worksharing or task regions arising from the
9303 // worksharing or task construct ever bind to any of the parallel regions
9304 // arising from the parallel construct.
9305 // OpenMP [2.9.3.4, Restrictions, p.4]
9306 // A list item that appears in a reduction clause in worksharing
9307 // construct must not appear in a firstprivate clause in a task construct
9308 // encountered during execution of any of the worksharing regions arising
9309 // from the worksharing construct.
9310 if (isOpenMPTaskingDirective(CurrDir)) {
9311 DVar = DSAStack->hasInnermostDSA(
9312 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
9313 [](OpenMPDirectiveKind K) -> bool {
9314 return isOpenMPParallelDirective(K) ||
9315 isOpenMPWorksharingDirective(K) ||
9316 isOpenMPTeamsDirective(K);
9318 /*FromParent=*/true);
9319 if (DVar.CKind == OMPC_reduction &&
9320 (isOpenMPParallelDirective(DVar.DKind) ||
9321 isOpenMPWorksharingDirective(DVar.DKind) ||
9322 isOpenMPTeamsDirective(DVar.DKind))) {
9323 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9324 << getOpenMPDirectiveName(DVar.DKind);
9325 ReportOriginalDSA(*this, DSAStack, D, DVar);
9330 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9331 // A list item cannot appear in both a map clause and a data-sharing
9332 // attribute clause on the same construct
9333 if (isOpenMPTargetExecutionDirective(CurrDir)) {
9334 OpenMPClauseKind ConflictKind;
9335 if (DSAStack->checkMappableExprComponentListsForDecl(
9336 VD, /*CurrentRegionOnly=*/true,
9337 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9338 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9339 ConflictKind = WhereFoundClauseKind;
9342 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9343 << getOpenMPClauseName(OMPC_firstprivate)
9344 << getOpenMPClauseName(ConflictKind)
9345 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9346 ReportOriginalDSA(*this, DSAStack, D, DVar);
9352 // Variably modified types are not supported for tasks.
9353 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9354 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
9355 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9356 << getOpenMPClauseName(OMPC_firstprivate) << Type
9357 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9360 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9361 Diag(D->getLocation(),
9362 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9367 Type = Type.getUnqualifiedType();
9368 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9369 D->hasAttrs() ? &D->getAttrs() : nullptr);
9370 // Generate helper private variable and initialize it with the value of the
9371 // original variable. The address of the original variable is replaced by
9372 // the address of the new private variable in the CodeGen. This new variable
9373 // is not added to IdResolver, so the code in the OpenMP region uses
9374 // original variable for proper diagnostics and variable capturing.
9375 Expr *VDInitRefExpr = nullptr;
9376 // For arrays generate initializer for single element and replace it by the
9377 // original array element in CodeGen.
9378 if (Type->isArrayType()) {
9380 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9381 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9382 auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
9383 ElemType = ElemType.getUnqualifiedType();
9384 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9385 ".firstprivate.temp");
9386 InitializedEntity Entity =
9387 InitializedEntity::InitializeVariable(VDInitTemp);
9388 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
9390 InitializationSequence InitSeq(*this, Entity, Kind, Init);
9391 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9392 if (Result.isInvalid())
9393 VDPrivate->setInvalidDecl();
9395 VDPrivate->setInit(Result.getAs<Expr>());
9396 // Remove temp variable declaration.
9397 Context.Deallocate(VDInitTemp);
9399 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9400 ".firstprivate.temp");
9401 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9402 RefExpr->getExprLoc());
9403 AddInitializerToDecl(VDPrivate,
9404 DefaultLvalueConversion(VDInitRefExpr).get(),
9405 /*DirectInit=*/false);
9407 if (VDPrivate->isInvalidDecl()) {
9408 if (IsImplicitClause) {
9409 Diag(RefExpr->getExprLoc(),
9410 diag::note_omp_task_predetermined_firstprivate_here);
9414 CurContext->addDecl(VDPrivate);
9415 auto VDPrivateRefExpr = buildDeclRefExpr(
9416 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9417 RefExpr->getExprLoc());
9418 DeclRefExpr *Ref = nullptr;
9419 if (!VD && !CurContext->isDependentContext()) {
9420 if (TopDVar.CKind == OMPC_lastprivate)
9421 Ref = TopDVar.PrivateCopy;
9423 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9424 if (!IsOpenMPCapturedDecl(D))
9425 ExprCaptures.push_back(Ref->getDecl());
9428 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9429 Vars.push_back((VD || CurContext->isDependentContext())
9430 ? RefExpr->IgnoreParens()
9432 PrivateCopies.push_back(VDPrivateRefExpr);
9433 Inits.push_back(VDInitRefExpr);
9439 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9440 Vars, PrivateCopies, Inits,
9441 buildPreInits(Context, ExprCaptures));
9444 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
9445 SourceLocation StartLoc,
9446 SourceLocation LParenLoc,
9447 SourceLocation EndLoc) {
9448 SmallVector<Expr *, 8> Vars;
9449 SmallVector<Expr *, 8> SrcExprs;
9450 SmallVector<Expr *, 8> DstExprs;
9451 SmallVector<Expr *, 8> AssignmentOps;
9452 SmallVector<Decl *, 4> ExprCaptures;
9453 SmallVector<Expr *, 4> ExprPostUpdates;
9454 for (auto &RefExpr : VarList) {
9455 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9456 SourceLocation ELoc;
9458 Expr *SimpleRefExpr = RefExpr;
9459 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9461 // It will be analyzed later.
9462 Vars.push_back(RefExpr);
9463 SrcExprs.push_back(nullptr);
9464 DstExprs.push_back(nullptr);
9465 AssignmentOps.push_back(nullptr);
9467 ValueDecl *D = Res.first;
9471 QualType Type = D->getType();
9472 auto *VD = dyn_cast<VarDecl>(D);
9474 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9475 // A variable that appears in a lastprivate clause must not have an
9476 // incomplete type or a reference type.
9477 if (RequireCompleteType(ELoc, Type,
9478 diag::err_omp_lastprivate_incomplete_type))
9480 Type = Type.getNonReferenceType();
9482 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9483 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9485 // Variables with the predetermined data-sharing attributes may not be
9486 // listed in data-sharing attributes clauses, except for the cases
9488 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9489 // A list item may appear in a firstprivate or lastprivate clause but not
9491 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9492 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9493 (isOpenMPDistributeDirective(CurrDir) ||
9494 DVar.CKind != OMPC_firstprivate) &&
9495 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9496 Diag(ELoc, diag::err_omp_wrong_dsa)
9497 << getOpenMPClauseName(DVar.CKind)
9498 << getOpenMPClauseName(OMPC_lastprivate);
9499 ReportOriginalDSA(*this, DSAStack, D, DVar);
9503 // OpenMP [2.14.3.5, Restrictions, p.2]
9504 // A list item that is private within a parallel region, or that appears in
9505 // the reduction clause of a parallel construct, must not appear in a
9506 // lastprivate clause on a worksharing construct if any of the corresponding
9507 // worksharing regions ever binds to any of the corresponding parallel
9509 DSAStackTy::DSAVarData TopDVar = DVar;
9510 if (isOpenMPWorksharingDirective(CurrDir) &&
9511 !isOpenMPParallelDirective(CurrDir) &&
9512 !isOpenMPTeamsDirective(CurrDir)) {
9513 DVar = DSAStack->getImplicitDSA(D, true);
9514 if (DVar.CKind != OMPC_shared) {
9515 Diag(ELoc, diag::err_omp_required_access)
9516 << getOpenMPClauseName(OMPC_lastprivate)
9517 << getOpenMPClauseName(OMPC_shared);
9518 ReportOriginalDSA(*this, DSAStack, D, DVar);
9523 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9524 // A variable of class type (or array thereof) that appears in a
9525 // lastprivate clause requires an accessible, unambiguous default
9526 // constructor for the class type, unless the list item is also specified
9527 // in a firstprivate clause.
9528 // A variable of class type (or array thereof) that appears in a
9529 // lastprivate clause requires an accessible, unambiguous copy assignment
9530 // operator for the class type.
9531 Type = Context.getBaseElementType(Type).getNonReferenceType();
9532 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9533 Type.getUnqualifiedType(), ".lastprivate.src",
9534 D->hasAttrs() ? &D->getAttrs() : nullptr);
9535 auto *PseudoSrcExpr =
9536 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9538 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9539 D->hasAttrs() ? &D->getAttrs() : nullptr);
9540 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9541 // For arrays generate assignment operation for single element and replace
9542 // it by the original array element in CodeGen.
9543 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9544 PseudoDstExpr, PseudoSrcExpr);
9545 if (AssignmentOp.isInvalid())
9547 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9548 /*DiscardedValue=*/true);
9549 if (AssignmentOp.isInvalid())
9552 DeclRefExpr *Ref = nullptr;
9553 if (!VD && !CurContext->isDependentContext()) {
9554 if (TopDVar.CKind == OMPC_firstprivate)
9555 Ref = TopDVar.PrivateCopy;
9557 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9558 if (!IsOpenMPCapturedDecl(D))
9559 ExprCaptures.push_back(Ref->getDecl());
9561 if (TopDVar.CKind == OMPC_firstprivate ||
9562 (!IsOpenMPCapturedDecl(D) &&
9563 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9564 ExprResult RefRes = DefaultLvalueConversion(Ref);
9565 if (!RefRes.isUsable())
9567 ExprResult PostUpdateRes =
9568 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9570 if (!PostUpdateRes.isUsable())
9572 ExprPostUpdates.push_back(
9573 IgnoredValueConversions(PostUpdateRes.get()).get());
9576 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9577 Vars.push_back((VD || CurContext->isDependentContext())
9578 ? RefExpr->IgnoreParens()
9580 SrcExprs.push_back(PseudoSrcExpr);
9581 DstExprs.push_back(PseudoDstExpr);
9582 AssignmentOps.push_back(AssignmentOp.get());
9588 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9589 Vars, SrcExprs, DstExprs, AssignmentOps,
9590 buildPreInits(Context, ExprCaptures),
9591 buildPostUpdate(*this, ExprPostUpdates));
9594 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
9595 SourceLocation StartLoc,
9596 SourceLocation LParenLoc,
9597 SourceLocation EndLoc) {
9598 SmallVector<Expr *, 8> Vars;
9599 for (auto &RefExpr : VarList) {
9600 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9601 SourceLocation ELoc;
9603 Expr *SimpleRefExpr = RefExpr;
9604 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9606 // It will be analyzed later.
9607 Vars.push_back(RefExpr);
9609 ValueDecl *D = Res.first;
9613 auto *VD = dyn_cast<VarDecl>(D);
9614 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9616 // Variables with the predetermined data-sharing attributes may not be
9617 // listed in data-sharing attributes clauses, except for the cases
9618 // listed below. For these exceptions only, listing a predetermined
9619 // variable in a data-sharing attribute clause is allowed and overrides
9620 // the variable's predetermined data-sharing attributes.
9621 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9622 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9624 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9625 << getOpenMPClauseName(OMPC_shared);
9626 ReportOriginalDSA(*this, DSAStack, D, DVar);
9630 DeclRefExpr *Ref = nullptr;
9631 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9632 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9633 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9634 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9635 ? RefExpr->IgnoreParens()
9642 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9646 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9650 bool VisitDeclRefExpr(DeclRefExpr *E) {
9651 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
9652 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
9653 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
9655 if (DVar.CKind != OMPC_unknown)
9657 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
9658 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
9659 /*FromParent=*/true);
9660 if (DVarPrivate.CKind != OMPC_unknown)
9666 bool VisitStmt(Stmt *S) {
9667 for (auto Child : S->children()) {
9668 if (Child && Visit(Child))
9673 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
9678 // Transform MemberExpression for specified FieldDecl of current class to
9679 // DeclRefExpr to specified OMPCapturedExprDecl.
9680 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
9681 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
9683 DeclRefExpr *CapturedExpr;
9686 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
9687 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
9689 ExprResult TransformMemberExpr(MemberExpr *E) {
9690 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
9691 E->getMemberDecl() == Field) {
9692 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
9693 return CapturedExpr;
9695 return BaseTransform::TransformMemberExpr(E);
9697 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
9701 template <typename T>
9702 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups,
9703 const llvm::function_ref<T(ValueDecl *)> &Gen) {
9704 for (auto &Set : Lookups) {
9705 for (auto *D : Set) {
9706 if (auto Res = Gen(cast<ValueDecl>(D)))
9714 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
9715 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
9716 const DeclarationNameInfo &ReductionId, QualType Ty,
9717 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
9718 if (ReductionIdScopeSpec.isInvalid())
9720 SmallVector<UnresolvedSet<8>, 4> Lookups;
9722 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
9723 Lookup.suppressDiagnostics();
9724 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
9725 auto *D = Lookup.getRepresentativeDecl();
9728 } while (S && !S->isDeclScope(D));
9731 Lookups.push_back(UnresolvedSet<8>());
9732 Lookups.back().append(Lookup.begin(), Lookup.end());
9735 } else if (auto *ULE =
9736 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
9737 Lookups.push_back(UnresolvedSet<8>());
9738 Decl *PrevD = nullptr;
9739 for (auto *D : ULE->decls()) {
9741 Lookups.push_back(UnresolvedSet<8>());
9742 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
9743 Lookups.back().addDecl(DRD);
9747 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
9748 Ty->isInstantiationDependentType() ||
9749 Ty->containsUnexpandedParameterPack() ||
9750 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
9751 return !D->isInvalidDecl() &&
9752 (D->getType()->isDependentType() ||
9753 D->getType()->isInstantiationDependentType() ||
9754 D->getType()->containsUnexpandedParameterPack());
9756 UnresolvedSet<8> ResSet;
9757 for (auto &Set : Lookups) {
9758 ResSet.append(Set.begin(), Set.end());
9759 // The last item marks the end of all declarations at the specified scope.
9760 ResSet.addDecl(Set[Set.size() - 1]);
9762 return UnresolvedLookupExpr::Create(
9763 SemaRef.Context, /*NamingClass=*/nullptr,
9764 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
9765 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
9767 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9768 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
9769 if (!D->isInvalidDecl() &&
9770 SemaRef.Context.hasSameType(D->getType(), Ty))
9774 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9775 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9776 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
9777 if (!D->isInvalidDecl() &&
9778 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
9779 !Ty.isMoreQualifiedThan(D->getType()))
9783 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
9784 /*DetectVirtual=*/false);
9785 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
9786 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
9787 VD->getType().getUnqualifiedType()))) {
9788 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
9790 Sema::AR_inaccessible) {
9791 SemaRef.BuildBasePathArray(Paths, BasePath);
9792 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9797 if (ReductionIdScopeSpec.isSet()) {
9798 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
9805 /// Data for the reduction-based clauses.
9806 struct ReductionData {
9807 /// List of original reduction items.
9808 SmallVector<Expr *, 8> Vars;
9809 /// List of private copies of the reduction items.
9810 SmallVector<Expr *, 8> Privates;
9811 /// LHS expressions for the reduction_op expressions.
9812 SmallVector<Expr *, 8> LHSs;
9813 /// RHS expressions for the reduction_op expressions.
9814 SmallVector<Expr *, 8> RHSs;
9815 /// Reduction operation expression.
9816 SmallVector<Expr *, 8> ReductionOps;
9817 /// Taskgroup descriptors for the corresponding reduction items in
9818 /// in_reduction clauses.
9819 SmallVector<Expr *, 8> TaskgroupDescriptors;
9820 /// List of captures for clause.
9821 SmallVector<Decl *, 4> ExprCaptures;
9822 /// List of postupdate expressions.
9823 SmallVector<Expr *, 4> ExprPostUpdates;
9824 ReductionData() = delete;
9825 /// Reserves required memory for the reduction data.
9826 ReductionData(unsigned Size) {
9828 Privates.reserve(Size);
9831 ReductionOps.reserve(Size);
9832 TaskgroupDescriptors.reserve(Size);
9833 ExprCaptures.reserve(Size);
9834 ExprPostUpdates.reserve(Size);
9836 /// Stores reduction item and reduction operation only (required for dependent
9837 /// reduction item).
9838 void push(Expr *Item, Expr *ReductionOp) {
9839 Vars.emplace_back(Item);
9840 Privates.emplace_back(nullptr);
9841 LHSs.emplace_back(nullptr);
9842 RHSs.emplace_back(nullptr);
9843 ReductionOps.emplace_back(ReductionOp);
9844 TaskgroupDescriptors.emplace_back(nullptr);
9846 /// Stores reduction data.
9847 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
9848 Expr *TaskgroupDescriptor) {
9849 Vars.emplace_back(Item);
9850 Privates.emplace_back(Private);
9851 LHSs.emplace_back(LHS);
9852 RHSs.emplace_back(RHS);
9853 ReductionOps.emplace_back(ReductionOp);
9854 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
9859 static bool CheckOMPArraySectionConstantForReduction(
9860 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
9861 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
9862 const Expr *Length = OASE->getLength();
9863 if (Length == nullptr) {
9864 // For array sections of the form [1:] or [:], we would need to analyze
9865 // the lower bound...
9866 if (OASE->getColonLoc().isValid())
9869 // This is an array subscript which has implicit length 1!
9870 SingleElement = true;
9871 ArraySizes.push_back(llvm::APSInt::get(1));
9873 llvm::APSInt ConstantLengthValue;
9874 if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
9877 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
9878 ArraySizes.push_back(ConstantLengthValue);
9881 // Get the base of this array section and walk up from there.
9882 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9884 // We require length = 1 for all array sections except the right-most to
9885 // guarantee that the memory region is contiguous and has no holes in it.
9886 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
9887 Length = TempOASE->getLength();
9888 if (Length == nullptr) {
9889 // For array sections of the form [1:] or [:], we would need to analyze
9890 // the lower bound...
9891 if (OASE->getColonLoc().isValid())
9894 // This is an array subscript which has implicit length 1!
9895 ArraySizes.push_back(llvm::APSInt::get(1));
9897 llvm::APSInt ConstantLengthValue;
9898 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
9899 ConstantLengthValue.getSExtValue() != 1)
9902 ArraySizes.push_back(ConstantLengthValue);
9904 Base = TempOASE->getBase()->IgnoreParenImpCasts();
9907 // If we have a single element, we don't need to add the implicit lengths.
9908 if (!SingleElement) {
9909 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
9910 // Has implicit length 1!
9911 ArraySizes.push_back(llvm::APSInt::get(1));
9912 Base = TempASE->getBase()->IgnoreParenImpCasts();
9916 // This array section can be privatized as a single value or as a constant
9921 static bool ActOnOMPReductionKindClause(
9922 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
9923 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
9924 SourceLocation ColonLoc, SourceLocation EndLoc,
9925 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
9926 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
9927 auto DN = ReductionId.getName();
9928 auto OOK = DN.getCXXOverloadedOperator();
9929 BinaryOperatorKind BOK = BO_Comma;
9931 ASTContext &Context = S.Context;
9932 // OpenMP [2.14.3.6, reduction clause]
9934 // reduction-identifier is either an identifier or one of the following
9935 // operators: +, -, *, &, |, ^, && and ||
9937 // reduction-identifier is either an id-expression or one of the following
9938 // operators: +, -, *, &, |, ^, && and ||
9965 case OO_Array_Delete:
9974 case OO_GreaterEqual:
9979 case OO_PercentEqual:
9984 case OO_GreaterGreater:
9985 case OO_LessLessEqual:
9986 case OO_GreaterGreaterEqual:
9988 case OO_ExclaimEqual:
9997 case OO_Conditional:
9999 case NUM_OVERLOADED_OPERATORS:
10000 llvm_unreachable("Unexpected reduction identifier");
10002 if (auto *II = DN.getAsIdentifierInfo()) {
10003 if (II->isStr("max"))
10005 else if (II->isStr("min"))
10010 SourceRange ReductionIdRange;
10011 if (ReductionIdScopeSpec.isValid())
10012 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10014 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10015 ReductionIdRange.setEnd(ReductionId.getEndLoc());
10017 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10018 bool FirstIter = true;
10019 for (auto RefExpr : VarList) {
10020 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10021 // OpenMP [2.1, C/C++]
10022 // A list item is a variable or array section, subject to the restrictions
10023 // specified in Section 2.4 on page 42 and in each of the sections
10024 // describing clauses and directives for which a list appears.
10025 // OpenMP [2.14.3.3, Restrictions, p.1]
10026 // A variable that is part of another variable (as an array or
10027 // structure element) cannot appear in a private clause.
10028 if (!FirstIter && IR != ER)
10031 SourceLocation ELoc;
10032 SourceRange ERange;
10033 Expr *SimpleRefExpr = RefExpr;
10034 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10035 /*AllowArraySection=*/true);
10037 // Try to find 'declare reduction' corresponding construct before using
10038 // builtin/overloaded operators.
10039 QualType Type = Context.DependentTy;
10040 CXXCastPath BasePath;
10041 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10042 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10043 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10044 Expr *ReductionOp = nullptr;
10045 if (S.CurContext->isDependentContext() &&
10046 (DeclareReductionRef.isUnset() ||
10047 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10048 ReductionOp = DeclareReductionRef.get();
10049 // It will be analyzed later.
10050 RD.push(RefExpr, ReductionOp);
10052 ValueDecl *D = Res.first;
10056 Expr *TaskgroupDescriptor = nullptr;
10058 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10059 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10061 Type = ASE->getType().getNonReferenceType();
10063 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10064 if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
10065 Type = ATy->getElementType();
10067 Type = BaseType->getPointeeType();
10068 Type = Type.getNonReferenceType();
10070 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10071 auto *VD = dyn_cast<VarDecl>(D);
10073 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10074 // A variable that appears in a private clause must not have an incomplete
10075 // type or a reference type.
10076 if (S.RequireCompleteType(ELoc, Type,
10077 diag::err_omp_reduction_incomplete_type))
10079 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10080 // A list item that appears in a reduction clause must not be
10081 // const-qualified.
10082 if (Type.getNonReferenceType().isConstant(Context)) {
10083 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10084 if (!ASE && !OASE) {
10085 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10086 VarDecl::DeclarationOnly;
10087 S.Diag(D->getLocation(),
10088 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10093 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10094 // If a list-item is a reference type then it must bind to the same object
10095 // for all threads of the team.
10096 if (!ASE && !OASE && VD) {
10097 VarDecl *VDDef = VD->getDefinition();
10098 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10099 DSARefChecker Check(Stack);
10100 if (Check.Visit(VDDef->getInit())) {
10101 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10102 << getOpenMPClauseName(ClauseKind) << ERange;
10103 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10109 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10111 // Variables with the predetermined data-sharing attributes may not be
10112 // listed in data-sharing attributes clauses, except for the cases
10113 // listed below. For these exceptions only, listing a predetermined
10114 // variable in a data-sharing attribute clause is allowed and overrides
10115 // the variable's predetermined data-sharing attributes.
10116 // OpenMP [2.14.3.6, Restrictions, p.3]
10117 // Any number of reduction clauses can be specified on the directive,
10118 // but a list item can appear only once in the reduction clauses for that
10120 DSAStackTy::DSAVarData DVar;
10121 DVar = Stack->getTopDSA(D, false);
10122 if (DVar.CKind == OMPC_reduction) {
10123 S.Diag(ELoc, diag::err_omp_once_referenced)
10124 << getOpenMPClauseName(ClauseKind);
10126 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10128 } else if (DVar.CKind != OMPC_unknown) {
10129 S.Diag(ELoc, diag::err_omp_wrong_dsa)
10130 << getOpenMPClauseName(DVar.CKind)
10131 << getOpenMPClauseName(OMPC_reduction);
10132 ReportOriginalDSA(S, Stack, D, DVar);
10136 // OpenMP [2.14.3.6, Restrictions, p.1]
10137 // A list item that appears in a reduction clause of a worksharing
10138 // construct must be shared in the parallel regions to which any of the
10139 // worksharing regions arising from the worksharing construct bind.
10140 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10141 if (isOpenMPWorksharingDirective(CurrDir) &&
10142 !isOpenMPParallelDirective(CurrDir) &&
10143 !isOpenMPTeamsDirective(CurrDir)) {
10144 DVar = Stack->getImplicitDSA(D, true);
10145 if (DVar.CKind != OMPC_shared) {
10146 S.Diag(ELoc, diag::err_omp_required_access)
10147 << getOpenMPClauseName(OMPC_reduction)
10148 << getOpenMPClauseName(OMPC_shared);
10149 ReportOriginalDSA(S, Stack, D, DVar);
10154 // Try to find 'declare reduction' corresponding construct before using
10155 // builtin/overloaded operators.
10156 CXXCastPath BasePath;
10157 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10158 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10159 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10160 if (DeclareReductionRef.isInvalid())
10162 if (S.CurContext->isDependentContext() &&
10163 (DeclareReductionRef.isUnset() ||
10164 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10165 RD.push(RefExpr, DeclareReductionRef.get());
10168 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
10169 // Not allowed reduction identifier is found.
10170 S.Diag(ReductionId.getLocStart(),
10171 diag::err_omp_unknown_reduction_identifier)
10172 << Type << ReductionIdRange;
10176 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10177 // The type of a list item that appears in a reduction clause must be valid
10178 // for the reduction-identifier. For a max or min reduction in C, the type
10179 // of the list item must be an allowed arithmetic data type: char, int,
10180 // float, double, or _Bool, possibly modified with long, short, signed, or
10181 // unsigned. For a max or min reduction in C++, the type of the list item
10182 // must be an allowed arithmetic data type: char, wchar_t, int, float,
10183 // double, or bool, possibly modified with long, short, signed, or unsigned.
10184 if (DeclareReductionRef.isUnset()) {
10185 if ((BOK == BO_GT || BOK == BO_LT) &&
10186 !(Type->isScalarType() ||
10187 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10188 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10189 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10190 if (!ASE && !OASE) {
10191 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10192 VarDecl::DeclarationOnly;
10193 S.Diag(D->getLocation(),
10194 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10199 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10200 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10201 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10202 << getOpenMPClauseName(ClauseKind);
10203 if (!ASE && !OASE) {
10204 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10205 VarDecl::DeclarationOnly;
10206 S.Diag(D->getLocation(),
10207 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10214 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10215 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10216 D->hasAttrs() ? &D->getAttrs() : nullptr);
10217 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10218 D->hasAttrs() ? &D->getAttrs() : nullptr);
10219 auto PrivateTy = Type;
10221 // Try if we can determine constant lengths for all array sections and avoid
10223 bool ConstantLengthOASE = false;
10225 bool SingleElement;
10226 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
10227 ConstantLengthOASE = CheckOMPArraySectionConstantForReduction(
10228 Context, OASE, SingleElement, ArraySizes);
10230 // If we don't have a single element, we must emit a constant array type.
10231 if (ConstantLengthOASE && !SingleElement) {
10232 for (auto &Size : ArraySizes) {
10233 PrivateTy = Context.getConstantArrayType(
10234 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10239 if ((OASE && !ConstantLengthOASE) ||
10241 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
10242 if (!Context.getTargetInfo().isVLASupported() &&
10243 S.shouldDiagnoseTargetSupportFromOpenMP()) {
10244 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10245 S.Diag(ELoc, diag::note_vla_unsupported);
10248 // For arrays/array sections only:
10249 // Create pseudo array type for private copy. The size for this array will
10250 // be generated during codegen.
10251 // For array subscripts or single variables Private Ty is the same as Type
10252 // (type of the variable or single array element).
10253 PrivateTy = Context.getVariableArrayType(
10255 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10256 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10257 } else if (!ASE && !OASE &&
10258 Context.getAsArrayType(D->getType().getNonReferenceType()))
10259 PrivateTy = D->getType().getNonReferenceType();
10261 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10262 D->hasAttrs() ? &D->getAttrs() : nullptr);
10263 // Add initializer for private variable.
10264 Expr *Init = nullptr;
10265 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10266 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10267 if (DeclareReductionRef.isUsable()) {
10268 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10269 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10270 if (DRD->getInitializer()) {
10272 RHSVD->setInit(DRDRef);
10273 RHSVD->setInitStyle(VarDecl::CallInit);
10281 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10282 if (Type->isScalarType() || Type->isAnyComplexType())
10283 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10287 if (Type->isScalarType() || Type->isAnyComplexType()) {
10288 // '*' and '&&' reduction ops - initializer is '1'.
10289 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10293 // '&' reduction op - initializer is '~0'.
10294 QualType OrigType = Type;
10295 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10296 Type = ComplexTy->getElementType();
10297 if (Type->isRealFloatingType()) {
10298 llvm::APFloat InitValue =
10299 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10301 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10303 } else if (Type->isScalarType()) {
10304 auto Size = Context.getTypeSize(Type);
10305 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10306 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10307 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10309 if (Init && OrigType->isAnyComplexType()) {
10310 // Init = 0xFFFF + 0xFFFFi;
10311 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10312 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10319 // 'min' reduction op - initializer is 'Largest representable number in
10320 // the reduction list item type'.
10321 // 'max' reduction op - initializer is 'Least representable number in
10322 // the reduction list item type'.
10323 if (Type->isIntegerType() || Type->isPointerType()) {
10324 bool IsSigned = Type->hasSignedIntegerRepresentation();
10325 auto Size = Context.getTypeSize(Type);
10327 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10328 llvm::APInt InitValue =
10329 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10330 : llvm::APInt::getMinValue(Size)
10331 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10332 : llvm::APInt::getMaxValue(Size);
10333 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10334 if (Type->isPointerType()) {
10335 // Cast to pointer type.
10336 auto CastExpr = S.BuildCStyleCastExpr(
10337 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10338 if (CastExpr.isInvalid())
10340 Init = CastExpr.get();
10342 } else if (Type->isRealFloatingType()) {
10343 llvm::APFloat InitValue = llvm::APFloat::getLargest(
10344 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10345 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10374 llvm_unreachable("Unexpected reduction operation");
10377 if (Init && DeclareReductionRef.isUnset())
10378 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10380 S.ActOnUninitializedDecl(RHSVD);
10381 if (RHSVD->isInvalidDecl())
10383 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
10384 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10385 << Type << ReductionIdRange;
10386 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10387 VarDecl::DeclarationOnly;
10388 S.Diag(D->getLocation(),
10389 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10393 // Store initializer for single element in private copy. Will be used during
10395 PrivateVD->setInit(RHSVD->getInit());
10396 PrivateVD->setInitStyle(RHSVD->getInitStyle());
10397 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10398 ExprResult ReductionOp;
10399 if (DeclareReductionRef.isUsable()) {
10400 QualType RedTy = DeclareReductionRef.get()->getType();
10401 QualType PtrRedTy = Context.getPointerType(RedTy);
10402 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10403 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10404 if (!BasePath.empty()) {
10405 LHS = S.DefaultLvalueConversion(LHS.get());
10406 RHS = S.DefaultLvalueConversion(RHS.get());
10407 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10408 CK_UncheckedDerivedToBase, LHS.get(),
10409 &BasePath, LHS.get()->getValueKind());
10410 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10411 CK_UncheckedDerivedToBase, RHS.get(),
10412 &BasePath, RHS.get()->getValueKind());
10414 FunctionProtoType::ExtProtoInfo EPI;
10415 QualType Params[] = {PtrRedTy, PtrRedTy};
10416 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10417 auto *OVE = new (Context) OpaqueValueExpr(
10418 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10419 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10420 Expr *Args[] = {LHS.get(), RHS.get()};
10421 ReductionOp = new (Context)
10422 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10424 ReductionOp = S.BuildBinOp(
10425 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10426 if (ReductionOp.isUsable()) {
10427 if (BOK != BO_LT && BOK != BO_GT) {
10429 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10430 BO_Assign, LHSDRE, ReductionOp.get());
10432 auto *ConditionalOp = new (Context)
10433 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10434 Type, VK_LValue, OK_Ordinary);
10436 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10437 BO_Assign, LHSDRE, ConditionalOp);
10439 if (ReductionOp.isUsable())
10440 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10442 if (!ReductionOp.isUsable())
10446 // OpenMP [2.15.4.6, Restrictions, p.2]
10447 // A list item that appears in an in_reduction clause of a task construct
10448 // must appear in a task_reduction clause of a construct associated with a
10449 // taskgroup region that includes the participating task in its taskgroup
10450 // set. The construct associated with the innermost region that meets this
10451 // condition must specify the same reduction-identifier as the in_reduction
10453 if (ClauseKind == OMPC_in_reduction) {
10454 SourceRange ParentSR;
10455 BinaryOperatorKind ParentBOK;
10456 const Expr *ParentReductionOp;
10457 Expr *ParentBOKTD, *ParentReductionOpTD;
10458 DSAStackTy::DSAVarData ParentBOKDSA =
10459 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10461 DSAStackTy::DSAVarData ParentReductionOpDSA =
10462 Stack->getTopMostTaskgroupReductionData(
10463 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10464 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10465 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10466 if (!IsParentBOK && !IsParentReductionOp) {
10467 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10470 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10471 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10472 IsParentReductionOp) {
10473 bool EmitError = true;
10474 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10475 llvm::FoldingSetNodeID RedId, ParentRedId;
10476 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10477 DeclareReductionRef.get()->Profile(RedId, Context,
10478 /*Canonical=*/true);
10479 EmitError = RedId != ParentRedId;
10482 S.Diag(ReductionId.getLocStart(),
10483 diag::err_omp_reduction_identifier_mismatch)
10484 << ReductionIdRange << RefExpr->getSourceRange();
10485 S.Diag(ParentSR.getBegin(),
10486 diag::note_omp_previous_reduction_identifier)
10488 << (IsParentBOK ? ParentBOKDSA.RefExpr
10489 : ParentReductionOpDSA.RefExpr)
10490 ->getSourceRange();
10494 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10495 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
10498 DeclRefExpr *Ref = nullptr;
10499 Expr *VarsExpr = RefExpr->IgnoreParens();
10500 if (!VD && !S.CurContext->isDependentContext()) {
10502 TransformExprToCaptures RebuildToCapture(S, D);
10504 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10505 Ref = RebuildToCapture.getCapturedExpr();
10507 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
10509 if (!S.IsOpenMPCapturedDecl(D)) {
10510 RD.ExprCaptures.emplace_back(Ref->getDecl());
10511 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10512 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10513 if (!RefRes.isUsable())
10515 ExprResult PostUpdateRes =
10516 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10518 if (!PostUpdateRes.isUsable())
10520 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10521 Stack->getCurrentDirective() == OMPD_taskgroup) {
10522 S.Diag(RefExpr->getExprLoc(),
10523 diag::err_omp_reduction_non_addressable_expression)
10524 << RefExpr->getSourceRange();
10527 RD.ExprPostUpdates.emplace_back(
10528 S.IgnoredValueConversions(PostUpdateRes.get()).get());
10532 // All reduction items are still marked as reduction (to do not increase
10533 // code base size).
10534 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10535 if (CurrDir == OMPD_taskgroup) {
10536 if (DeclareReductionRef.isUsable())
10537 Stack->addTaskgroupReductionData(D, ReductionIdRange,
10538 DeclareReductionRef.get());
10540 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10542 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10543 TaskgroupDescriptor);
10545 return RD.Vars.empty();
10548 OMPClause *Sema::ActOnOpenMPReductionClause(
10549 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10550 SourceLocation ColonLoc, SourceLocation EndLoc,
10551 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10552 ArrayRef<Expr *> UnresolvedReductions) {
10553 ReductionData RD(VarList.size());
10555 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
10556 StartLoc, LParenLoc, ColonLoc, EndLoc,
10557 ReductionIdScopeSpec, ReductionId,
10558 UnresolvedReductions, RD))
10561 return OMPReductionClause::Create(
10562 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10563 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10564 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10565 buildPreInits(Context, RD.ExprCaptures),
10566 buildPostUpdate(*this, RD.ExprPostUpdates));
10569 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
10570 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10571 SourceLocation ColonLoc, SourceLocation EndLoc,
10572 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10573 ArrayRef<Expr *> UnresolvedReductions) {
10574 ReductionData RD(VarList.size());
10576 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction,
10577 VarList, StartLoc, LParenLoc, ColonLoc,
10578 EndLoc, ReductionIdScopeSpec, ReductionId,
10579 UnresolvedReductions, RD))
10582 return OMPTaskReductionClause::Create(
10583 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10584 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10585 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10586 buildPreInits(Context, RD.ExprCaptures),
10587 buildPostUpdate(*this, RD.ExprPostUpdates));
10590 OMPClause *Sema::ActOnOpenMPInReductionClause(
10591 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10592 SourceLocation ColonLoc, SourceLocation EndLoc,
10593 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10594 ArrayRef<Expr *> UnresolvedReductions) {
10595 ReductionData RD(VarList.size());
10597 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
10598 StartLoc, LParenLoc, ColonLoc, EndLoc,
10599 ReductionIdScopeSpec, ReductionId,
10600 UnresolvedReductions, RD))
10603 return OMPInReductionClause::Create(
10604 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10605 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10606 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10607 buildPreInits(Context, RD.ExprCaptures),
10608 buildPostUpdate(*this, RD.ExprPostUpdates));
10611 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
10612 SourceLocation LinLoc) {
10613 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10614 LinKind == OMPC_LINEAR_unknown) {
10615 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10621 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc,
10622 OpenMPLinearClauseKind LinKind,
10624 auto *VD = dyn_cast_or_null<VarDecl>(D);
10625 // A variable must not have an incomplete type or a reference type.
10626 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10628 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10629 !Type->isReferenceType()) {
10630 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10631 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10634 Type = Type.getNonReferenceType();
10636 // A list item must not be const-qualified.
10637 if (Type.isConstant(Context)) {
10638 Diag(ELoc, diag::err_omp_const_variable)
10639 << getOpenMPClauseName(OMPC_linear);
10643 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10644 Diag(D->getLocation(),
10645 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10651 // A list item must be of integral or pointer type.
10652 Type = Type.getUnqualifiedType().getCanonicalType();
10653 const auto *Ty = Type.getTypePtrOrNull();
10654 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
10655 !Ty->isPointerType())) {
10656 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
10660 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10661 Diag(D->getLocation(),
10662 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10670 OMPClause *Sema::ActOnOpenMPLinearClause(
10671 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
10672 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
10673 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
10674 SmallVector<Expr *, 8> Vars;
10675 SmallVector<Expr *, 8> Privates;
10676 SmallVector<Expr *, 8> Inits;
10677 SmallVector<Decl *, 4> ExprCaptures;
10678 SmallVector<Expr *, 4> ExprPostUpdates;
10679 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
10680 LinKind = OMPC_LINEAR_val;
10681 for (auto &RefExpr : VarList) {
10682 assert(RefExpr && "NULL expr in OpenMP linear clause.");
10683 SourceLocation ELoc;
10684 SourceRange ERange;
10685 Expr *SimpleRefExpr = RefExpr;
10686 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10687 /*AllowArraySection=*/false);
10689 // It will be analyzed later.
10690 Vars.push_back(RefExpr);
10691 Privates.push_back(nullptr);
10692 Inits.push_back(nullptr);
10694 ValueDecl *D = Res.first;
10698 QualType Type = D->getType();
10699 auto *VD = dyn_cast<VarDecl>(D);
10701 // OpenMP [2.14.3.7, linear clause]
10702 // A list-item cannot appear in more than one linear clause.
10703 // A list-item that appears in a linear clause cannot appear in any
10704 // other data-sharing attribute clause.
10705 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
10706 if (DVar.RefExpr) {
10707 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10708 << getOpenMPClauseName(OMPC_linear);
10709 ReportOriginalDSA(*this, DSAStack, D, DVar);
10713 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
10715 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
10717 // Build private copy of original var.
10718 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(),
10719 D->hasAttrs() ? &D->getAttrs() : nullptr);
10720 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
10721 // Build var to save initial value.
10722 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
10724 DeclRefExpr *Ref = nullptr;
10725 if (!VD && !CurContext->isDependentContext()) {
10726 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10727 if (!IsOpenMPCapturedDecl(D)) {
10728 ExprCaptures.push_back(Ref->getDecl());
10729 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10730 ExprResult RefRes = DefaultLvalueConversion(Ref);
10731 if (!RefRes.isUsable())
10733 ExprResult PostUpdateRes =
10734 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
10735 SimpleRefExpr, RefRes.get());
10736 if (!PostUpdateRes.isUsable())
10738 ExprPostUpdates.push_back(
10739 IgnoredValueConversions(PostUpdateRes.get()).get());
10743 if (LinKind == OMPC_LINEAR_uval)
10744 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
10746 InitExpr = VD ? SimpleRefExpr : Ref;
10747 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
10748 /*DirectInit=*/false);
10749 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
10751 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
10752 Vars.push_back((VD || CurContext->isDependentContext())
10753 ? RefExpr->IgnoreParens()
10755 Privates.push_back(PrivateRef);
10756 Inits.push_back(InitRef);
10762 Expr *StepExpr = Step;
10763 Expr *CalcStepExpr = nullptr;
10764 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
10765 !Step->isInstantiationDependent() &&
10766 !Step->containsUnexpandedParameterPack()) {
10767 SourceLocation StepLoc = Step->getLocStart();
10768 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
10769 if (Val.isInvalid())
10771 StepExpr = Val.get();
10773 // Build var to save the step value.
10775 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
10776 ExprResult SaveRef =
10777 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
10778 ExprResult CalcStep =
10779 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
10780 CalcStep = ActOnFinishFullExpr(CalcStep.get());
10782 // Warn about zero linear step (it would be probably better specified as
10783 // making corresponding variables 'const').
10784 llvm::APSInt Result;
10785 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
10786 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
10787 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
10788 << (Vars.size() > 1);
10789 if (!IsConstant && CalcStep.isUsable()) {
10790 // Calculate the step beforehand instead of doing this on each iteration.
10791 // (This is not used if the number of iterations may be kfold-ed).
10792 CalcStepExpr = CalcStep.get();
10796 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
10797 ColonLoc, EndLoc, Vars, Privates, Inits,
10798 StepExpr, CalcStepExpr,
10799 buildPreInits(Context, ExprCaptures),
10800 buildPostUpdate(*this, ExprPostUpdates));
10803 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
10804 Expr *NumIterations, Sema &SemaRef,
10805 Scope *S, DSAStackTy *Stack) {
10806 // Walk the vars and build update/final expressions for the CodeGen.
10807 SmallVector<Expr *, 8> Updates;
10808 SmallVector<Expr *, 8> Finals;
10809 Expr *Step = Clause.getStep();
10810 Expr *CalcStep = Clause.getCalcStep();
10811 // OpenMP [2.14.3.7, linear clause]
10812 // If linear-step is not specified it is assumed to be 1.
10813 if (Step == nullptr)
10814 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10815 else if (CalcStep) {
10816 Step = cast<BinaryOperator>(CalcStep)->getLHS();
10818 bool HasErrors = false;
10819 auto CurInit = Clause.inits().begin();
10820 auto CurPrivate = Clause.privates().begin();
10821 auto LinKind = Clause.getModifier();
10822 for (auto &RefExpr : Clause.varlists()) {
10823 SourceLocation ELoc;
10824 SourceRange ERange;
10825 Expr *SimpleRefExpr = RefExpr;
10826 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
10827 /*AllowArraySection=*/false);
10828 ValueDecl *D = Res.first;
10829 if (Res.second || !D) {
10830 Updates.push_back(nullptr);
10831 Finals.push_back(nullptr);
10835 auto &&Info = Stack->isLoopControlVariable(D);
10836 // OpenMP [2.15.11, distribute simd Construct]
10837 // A list item may not appear in a linear clause, unless it is the loop
10838 // iteration variable.
10839 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
10840 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
10842 diag::err_omp_linear_distribute_var_non_loop_iteration);
10843 Updates.push_back(nullptr);
10844 Finals.push_back(nullptr);
10848 Expr *InitExpr = *CurInit;
10850 // Build privatized reference to the current linear var.
10851 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
10853 if (LinKind == OMPC_LINEAR_uval)
10854 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
10857 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
10858 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
10859 /*RefersToCapture=*/true);
10861 // Build update: Var = InitExpr + IV * Step
10865 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
10866 InitExpr, IV, Step, /* Subtract */ false);
10868 Update = *CurPrivate;
10869 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
10870 /*DiscardedValue=*/true);
10872 // Build final: Var = InitExpr + NumIterations * Step
10875 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
10876 InitExpr, NumIterations, Step,
10877 /* Subtract */ false);
10879 Final = *CurPrivate;
10880 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
10881 /*DiscardedValue=*/true);
10883 if (!Update.isUsable() || !Final.isUsable()) {
10884 Updates.push_back(nullptr);
10885 Finals.push_back(nullptr);
10888 Updates.push_back(Update.get());
10889 Finals.push_back(Final.get());
10894 Clause.setUpdates(Updates);
10895 Clause.setFinals(Finals);
10899 OMPClause *Sema::ActOnOpenMPAlignedClause(
10900 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
10901 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
10903 SmallVector<Expr *, 8> Vars;
10904 for (auto &RefExpr : VarList) {
10905 assert(RefExpr && "NULL expr in OpenMP linear clause.");
10906 SourceLocation ELoc;
10907 SourceRange ERange;
10908 Expr *SimpleRefExpr = RefExpr;
10909 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10910 /*AllowArraySection=*/false);
10912 // It will be analyzed later.
10913 Vars.push_back(RefExpr);
10915 ValueDecl *D = Res.first;
10919 QualType QType = D->getType();
10920 auto *VD = dyn_cast<VarDecl>(D);
10922 // OpenMP [2.8.1, simd construct, Restrictions]
10923 // The type of list items appearing in the aligned clause must be
10924 // array, pointer, reference to array, or reference to pointer.
10925 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
10926 const Type *Ty = QType.getTypePtrOrNull();
10927 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
10928 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
10929 << QType << getLangOpts().CPlusPlus << ERange;
10932 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10933 Diag(D->getLocation(),
10934 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10939 // OpenMP [2.8.1, simd construct, Restrictions]
10940 // A list-item cannot appear in more than one aligned clause.
10941 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
10942 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
10943 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
10944 << getOpenMPClauseName(OMPC_aligned);
10948 DeclRefExpr *Ref = nullptr;
10949 if (!VD && IsOpenMPCapturedDecl(D))
10950 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10951 Vars.push_back(DefaultFunctionArrayConversion(
10952 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
10956 // OpenMP [2.8.1, simd construct, Description]
10957 // The parameter of the aligned clause, alignment, must be a constant
10958 // positive integer expression.
10959 // If no optional parameter is specified, implementation-defined default
10960 // alignments for SIMD instructions on the target platforms are assumed.
10961 if (Alignment != nullptr) {
10962 ExprResult AlignResult =
10963 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
10964 if (AlignResult.isInvalid())
10966 Alignment = AlignResult.get();
10971 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
10972 EndLoc, Vars, Alignment);
10975 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
10976 SourceLocation StartLoc,
10977 SourceLocation LParenLoc,
10978 SourceLocation EndLoc) {
10979 SmallVector<Expr *, 8> Vars;
10980 SmallVector<Expr *, 8> SrcExprs;
10981 SmallVector<Expr *, 8> DstExprs;
10982 SmallVector<Expr *, 8> AssignmentOps;
10983 for (auto &RefExpr : VarList) {
10984 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
10985 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10986 // It will be analyzed later.
10987 Vars.push_back(RefExpr);
10988 SrcExprs.push_back(nullptr);
10989 DstExprs.push_back(nullptr);
10990 AssignmentOps.push_back(nullptr);
10994 SourceLocation ELoc = RefExpr->getExprLoc();
10995 // OpenMP [2.1, C/C++]
10996 // A list item is a variable name.
10997 // OpenMP [2.14.4.1, Restrictions, p.1]
10998 // A list item that appears in a copyin clause must be threadprivate.
10999 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
11000 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11001 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11002 << 0 << RefExpr->getSourceRange();
11006 Decl *D = DE->getDecl();
11007 VarDecl *VD = cast<VarDecl>(D);
11009 QualType Type = VD->getType();
11010 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11011 // It will be analyzed later.
11012 Vars.push_back(DE);
11013 SrcExprs.push_back(nullptr);
11014 DstExprs.push_back(nullptr);
11015 AssignmentOps.push_back(nullptr);
11019 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11020 // A list item that appears in a copyin clause must be threadprivate.
11021 if (!DSAStack->isThreadPrivate(VD)) {
11022 Diag(ELoc, diag::err_omp_required_access)
11023 << getOpenMPClauseName(OMPC_copyin)
11024 << getOpenMPDirectiveName(OMPD_threadprivate);
11028 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11029 // A variable of class type (or array thereof) that appears in a
11030 // copyin clause requires an accessible, unambiguous copy assignment
11031 // operator for the class type.
11032 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11034 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11035 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11036 auto *PseudoSrcExpr = buildDeclRefExpr(
11037 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11039 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11040 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11041 auto *PseudoDstExpr =
11042 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11043 // For arrays generate assignment operation for single element and replace
11044 // it by the original array element in CodeGen.
11045 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
11046 PseudoDstExpr, PseudoSrcExpr);
11047 if (AssignmentOp.isInvalid())
11049 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11050 /*DiscardedValue=*/true);
11051 if (AssignmentOp.isInvalid())
11054 DSAStack->addDSA(VD, DE, OMPC_copyin);
11055 Vars.push_back(DE);
11056 SrcExprs.push_back(PseudoSrcExpr);
11057 DstExprs.push_back(PseudoDstExpr);
11058 AssignmentOps.push_back(AssignmentOp.get());
11064 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11065 SrcExprs, DstExprs, AssignmentOps);
11068 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
11069 SourceLocation StartLoc,
11070 SourceLocation LParenLoc,
11071 SourceLocation EndLoc) {
11072 SmallVector<Expr *, 8> Vars;
11073 SmallVector<Expr *, 8> SrcExprs;
11074 SmallVector<Expr *, 8> DstExprs;
11075 SmallVector<Expr *, 8> AssignmentOps;
11076 for (auto &RefExpr : VarList) {
11077 assert(RefExpr && "NULL expr in OpenMP linear clause.");
11078 SourceLocation ELoc;
11079 SourceRange ERange;
11080 Expr *SimpleRefExpr = RefExpr;
11081 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11082 /*AllowArraySection=*/false);
11084 // It will be analyzed later.
11085 Vars.push_back(RefExpr);
11086 SrcExprs.push_back(nullptr);
11087 DstExprs.push_back(nullptr);
11088 AssignmentOps.push_back(nullptr);
11090 ValueDecl *D = Res.first;
11094 QualType Type = D->getType();
11095 auto *VD = dyn_cast<VarDecl>(D);
11097 // OpenMP [2.14.4.2, Restrictions, p.2]
11098 // A list item that appears in a copyprivate clause may not appear in a
11099 // private or firstprivate clause on the single construct.
11100 if (!VD || !DSAStack->isThreadPrivate(VD)) {
11101 auto DVar = DSAStack->getTopDSA(D, false);
11102 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11104 Diag(ELoc, diag::err_omp_wrong_dsa)
11105 << getOpenMPClauseName(DVar.CKind)
11106 << getOpenMPClauseName(OMPC_copyprivate);
11107 ReportOriginalDSA(*this, DSAStack, D, DVar);
11111 // OpenMP [2.11.4.2, Restrictions, p.1]
11112 // All list items that appear in a copyprivate clause must be either
11113 // threadprivate or private in the enclosing context.
11114 if (DVar.CKind == OMPC_unknown) {
11115 DVar = DSAStack->getImplicitDSA(D, false);
11116 if (DVar.CKind == OMPC_shared) {
11117 Diag(ELoc, diag::err_omp_required_access)
11118 << getOpenMPClauseName(OMPC_copyprivate)
11119 << "threadprivate or private in the enclosing context";
11120 ReportOriginalDSA(*this, DSAStack, D, DVar);
11126 // Variably modified types are not supported.
11127 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11128 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11129 << getOpenMPClauseName(OMPC_copyprivate) << Type
11130 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11133 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11134 Diag(D->getLocation(),
11135 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11140 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11141 // A variable of class type (or array thereof) that appears in a
11142 // copyin clause requires an accessible, unambiguous copy assignment
11143 // operator for the class type.
11144 Type = Context.getBaseElementType(Type.getNonReferenceType())
11145 .getUnqualifiedType();
11147 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11148 D->hasAttrs() ? &D->getAttrs() : nullptr);
11149 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11151 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11152 D->hasAttrs() ? &D->getAttrs() : nullptr);
11153 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11154 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11155 PseudoDstExpr, PseudoSrcExpr);
11156 if (AssignmentOp.isInvalid())
11158 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11159 /*DiscardedValue=*/true);
11160 if (AssignmentOp.isInvalid())
11163 // No need to mark vars as copyprivate, they are already threadprivate or
11164 // implicitly private.
11165 assert(VD || IsOpenMPCapturedDecl(D));
11167 VD ? RefExpr->IgnoreParens()
11168 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11169 SrcExprs.push_back(PseudoSrcExpr);
11170 DstExprs.push_back(PseudoDstExpr);
11171 AssignmentOps.push_back(AssignmentOp.get());
11177 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11178 Vars, SrcExprs, DstExprs, AssignmentOps);
11181 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
11182 SourceLocation StartLoc,
11183 SourceLocation LParenLoc,
11184 SourceLocation EndLoc) {
11185 if (VarList.empty())
11188 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11192 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
11193 SourceLocation DepLoc, SourceLocation ColonLoc,
11194 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11195 SourceLocation LParenLoc, SourceLocation EndLoc) {
11196 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
11197 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11198 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11199 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11202 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
11203 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11204 DepKind == OMPC_DEPEND_sink)) {
11205 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11206 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11207 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11208 /*Last=*/OMPC_DEPEND_unknown, Except)
11209 << getOpenMPClauseName(OMPC_depend);
11212 SmallVector<Expr *, 8> Vars;
11213 DSAStackTy::OperatorOffsetTy OpsOffs;
11214 llvm::APSInt DepCounter(/*BitWidth=*/32);
11215 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11216 if (DepKind == OMPC_DEPEND_sink) {
11217 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
11218 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11219 TotalDepCount.setIsUnsigned(/*Val=*/true);
11222 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
11223 DSAStack->getParentOrderedRegionParam()) {
11224 for (auto &RefExpr : VarList) {
11225 assert(RefExpr && "NULL expr in OpenMP shared clause.");
11226 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11227 // It will be analyzed later.
11228 Vars.push_back(RefExpr);
11232 SourceLocation ELoc = RefExpr->getExprLoc();
11233 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
11234 if (DepKind == OMPC_DEPEND_sink) {
11235 if (DepCounter >= TotalDepCount) {
11236 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11240 // OpenMP [2.13.9, Summary]
11241 // depend(dependence-type : vec), where dependence-type is:
11242 // 'sink' and where vec is the iteration vector, which has the form:
11243 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11244 // where n is the value specified by the ordered clause in the loop
11245 // directive, xi denotes the loop iteration variable of the i-th nested
11246 // loop associated with the loop directive, and di is a constant
11247 // non-negative integer.
11248 if (CurContext->isDependentContext()) {
11249 // It will be analyzed later.
11250 Vars.push_back(RefExpr);
11253 SimpleExpr = SimpleExpr->IgnoreImplicit();
11254 OverloadedOperatorKind OOK = OO_None;
11255 SourceLocation OOLoc;
11256 Expr *LHS = SimpleExpr;
11257 Expr *RHS = nullptr;
11258 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11259 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11260 OOLoc = BO->getOperatorLoc();
11261 LHS = BO->getLHS()->IgnoreParenImpCasts();
11262 RHS = BO->getRHS()->IgnoreParenImpCasts();
11263 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11264 OOK = OCE->getOperator();
11265 OOLoc = OCE->getOperatorLoc();
11266 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11267 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11268 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11269 OOK = MCE->getMethodDecl()
11272 .getCXXOverloadedOperator();
11273 OOLoc = MCE->getCallee()->getExprLoc();
11274 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11275 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11277 SourceLocation ELoc;
11278 SourceRange ERange;
11279 auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11280 /*AllowArraySection=*/false);
11282 // It will be analyzed later.
11283 Vars.push_back(RefExpr);
11285 ValueDecl *D = Res.first;
11289 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11290 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11294 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11295 RHS, OMPC_depend, /*StrictlyPositive=*/false);
11296 if (RHSRes.isInvalid())
11299 if (!CurContext->isDependentContext() &&
11300 DSAStack->getParentOrderedRegionParam() &&
11301 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
11302 ValueDecl* VD = DSAStack->getParentLoopControlVariable(
11303 DepCounter.getZExtValue());
11305 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11308 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11312 OpsOffs.push_back({RHS, OOK});
11314 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11315 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11319 .getNonReferenceType()
11320 ->isPointerType() &&
11321 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11322 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11323 << RefExpr->getSourceRange();
11326 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11327 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11328 ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
11329 RefExpr->IgnoreParenImpCasts());
11330 getDiagnostics().setSuppressAllDiagnostics(Suppress);
11331 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11332 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11333 << RefExpr->getSourceRange();
11337 Vars.push_back(RefExpr->IgnoreParenImpCasts());
11340 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11341 TotalDepCount > VarList.size() &&
11342 DSAStack->getParentOrderedRegionParam() &&
11343 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11344 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
11345 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11347 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11351 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11352 DepKind, DepLoc, ColonLoc, Vars);
11353 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
11354 DSAStack->addDoacrossDependClause(C, OpsOffs);
11358 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
11359 SourceLocation LParenLoc,
11360 SourceLocation EndLoc) {
11361 Expr *ValExpr = Device;
11362 Stmt *HelperValStmt = nullptr;
11364 // OpenMP [2.9.1, Restrictions]
11365 // The device expression must evaluate to a non-negative integer value.
11366 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11367 /*StrictlyPositive=*/false))
11370 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11371 OpenMPDirectiveKind CaptureRegion =
11372 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11373 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11374 ValExpr = MakeFullExpr(ValExpr).get();
11375 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11376 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11377 HelperValStmt = buildPreInits(Context, Captures);
11380 return new (Context)
11381 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc);
11384 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11385 DSAStackTy *Stack, QualType QTy) {
11387 if (QTy->isIncompleteType(&ND)) {
11388 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11394 /// \brief Return true if it can be proven that the provided array expression
11395 /// (array section or array subscript) does NOT specify the whole size of the
11396 /// array whose base type is \a BaseQTy.
11397 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
11399 QualType BaseQTy) {
11400 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11402 // If this is an array subscript, it refers to the whole size if the size of
11403 // the dimension is constant and equals 1. Also, an array section assumes the
11404 // format of an array subscript if no colon is used.
11405 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11406 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11407 return ATy->getSize().getSExtValue() != 1;
11408 // Size can't be evaluated statically.
11412 assert(OASE && "Expecting array section if not an array subscript.");
11413 auto *LowerBound = OASE->getLowerBound();
11414 auto *Length = OASE->getLength();
11416 // If there is a lower bound that does not evaluates to zero, we are not
11417 // covering the whole dimension.
11419 llvm::APSInt ConstLowerBound;
11420 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11421 return false; // Can't get the integer value as a constant.
11422 if (ConstLowerBound.getSExtValue())
11426 // If we don't have a length we covering the whole dimension.
11430 // If the base is a pointer, we don't have a way to get the size of the
11432 if (BaseQTy->isPointerType())
11435 // We can only check if the length is the same as the size of the dimension
11436 // if we have a constant array.
11437 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11441 llvm::APSInt ConstLength;
11442 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11443 return false; // Can't get the integer value as a constant.
11445 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11448 // Return true if it can be proven that the provided array expression (array
11449 // section or array subscript) does NOT specify a single element of the array
11450 // whose base type is \a BaseQTy.
11451 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
11453 QualType BaseQTy) {
11454 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11456 // An array subscript always refer to a single element. Also, an array section
11457 // assumes the format of an array subscript if no colon is used.
11458 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11461 assert(OASE && "Expecting array section if not an array subscript.");
11462 auto *Length = OASE->getLength();
11464 // If we don't have a length we have to check if the array has unitary size
11465 // for this dimension. Also, we should always expect a length if the base type
11468 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11469 return ATy->getSize().getSExtValue() != 1;
11470 // We cannot assume anything.
11474 // Check if the length evaluates to 1.
11475 llvm::APSInt ConstLength;
11476 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11477 return false; // Can't get the integer value as a constant.
11479 return ConstLength.getSExtValue() != 1;
11482 // Return the expression of the base of the mappable expression or null if it
11483 // cannot be determined and do all the necessary checks to see if the expression
11484 // is valid as a standalone mappable expression. In the process, record all the
11485 // components of the expression.
11486 static Expr *CheckMapClauseExpressionBase(
11487 Sema &SemaRef, Expr *E,
11488 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
11489 OpenMPClauseKind CKind, bool NoDiagnose) {
11490 SourceLocation ELoc = E->getExprLoc();
11491 SourceRange ERange = E->getSourceRange();
11493 // The base of elements of list in a map clause have to be either:
11494 // - a reference to variable or field.
11495 // - a member expression.
11496 // - an array expression.
11498 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11499 // reference to 'r'.
11506 // #pragma omp target map (S.Arr[:12]);
11510 // We want to retrieve the member expression 'this->S';
11512 Expr *RelevantExpr = nullptr;
11514 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11515 // If a list item is an array section, it must specify contiguous storage.
11517 // For this restriction it is sufficient that we make sure only references
11518 // to variables or fields and array expressions, and that no array sections
11519 // exist except in the rightmost expression (unless they cover the whole
11520 // dimension of the array). E.g. these would be invalid:
11522 // r.ArrS[3:5].Arr[6:7]
11526 // but these would be valid:
11527 // r.ArrS[3].Arr[6:7]
11531 bool AllowUnitySizeArraySection = true;
11532 bool AllowWholeSizeArraySection = true;
11534 while (!RelevantExpr) {
11535 E = E->IgnoreParenImpCasts();
11537 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11538 if (!isa<VarDecl>(CurE->getDecl()))
11541 RelevantExpr = CurE;
11543 // If we got a reference to a declaration, we should not expect any array
11544 // section before that.
11545 AllowUnitySizeArraySection = false;
11546 AllowWholeSizeArraySection = false;
11548 // Record the component.
11549 CurComponents.emplace_back(CurE, CurE->getDecl());
11550 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11551 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11553 if (isa<CXXThisExpr>(BaseE))
11554 // We found a base expression: this->Val.
11555 RelevantExpr = CurE;
11559 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11561 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11562 << CurE->getSourceRange();
11570 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11572 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11573 // A bit-field cannot appear in a map clause.
11575 if (FD->isBitField()) {
11577 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11578 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11586 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11587 // If the type of a list item is a reference to a type T then the type
11588 // will be considered to be T for all purposes of this clause.
11589 QualType CurType = BaseE->getType().getNonReferenceType();
11591 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11592 // A list item cannot be a variable that is a member of a structure with
11595 if (auto *RT = CurType->getAs<RecordType>()) {
11596 if (RT->isUnionType()) {
11598 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11599 << CurE->getSourceRange();
11606 // If we got a member expression, we should not expect any array section
11609 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11610 // If a list item is an element of a structure, only the rightmost symbol
11611 // of the variable reference can be an array section.
11613 AllowUnitySizeArraySection = false;
11614 AllowWholeSizeArraySection = false;
11616 // Record the component.
11617 CurComponents.emplace_back(CurE, FD);
11618 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11619 E = CurE->getBase()->IgnoreParenImpCasts();
11621 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11623 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11624 << 0 << CurE->getSourceRange();
11630 // If we got an array subscript that express the whole dimension we
11631 // can have any array expressions before. If it only expressing part of
11632 // the dimension, we can only have unitary-size array expressions.
11633 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
11635 AllowWholeSizeArraySection = false;
11637 // Record the component - we don't have any declaration associated.
11638 CurComponents.emplace_back(CurE, nullptr);
11639 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11640 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
11641 E = CurE->getBase()->IgnoreParenImpCasts();
11644 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11646 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11647 // If the type of a list item is a reference to a type T then the type
11648 // will be considered to be T for all purposes of this clause.
11649 if (CurType->isReferenceType())
11650 CurType = CurType->getPointeeType();
11652 bool IsPointer = CurType->isAnyPointerType();
11654 if (!IsPointer && !CurType->isArrayType()) {
11655 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11656 << 0 << CurE->getSourceRange();
11661 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
11663 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
11665 if (AllowWholeSizeArraySection) {
11666 // Any array section is currently allowed. Allowing a whole size array
11667 // section implies allowing a unity array section as well.
11669 // If this array section refers to the whole dimension we can still
11670 // accept other array sections before this one, except if the base is a
11671 // pointer. Otherwise, only unitary sections are accepted.
11672 if (NotWhole || IsPointer)
11673 AllowWholeSizeArraySection = false;
11674 } else if (AllowUnitySizeArraySection && NotUnity) {
11675 // A unity or whole array section is not allowed and that is not
11676 // compatible with the properties of the current array section.
11678 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
11679 << CurE->getSourceRange();
11683 // Record the component - we don't have any declaration associated.
11684 CurComponents.emplace_back(CurE, nullptr);
11687 // If nothing else worked, this is not a valid map clause expression.
11689 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
11696 return RelevantExpr;
11699 // Return true if expression E associated with value VD has conflicts with other
11700 // map information.
11701 static bool CheckMapConflicts(
11702 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
11703 bool CurrentRegionOnly,
11704 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
11705 OpenMPClauseKind CKind) {
11707 SourceLocation ELoc = E->getExprLoc();
11708 SourceRange ERange = E->getSourceRange();
11710 // In order to easily check the conflicts we need to match each component of
11711 // the expression under test with the components of the expressions that are
11712 // already in the stack.
11714 assert(!CurComponents.empty() && "Map clause expression with no components!");
11715 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
11716 "Map clause expression with unexpected base!");
11718 // Variables to help detecting enclosing problems in data environment nests.
11719 bool IsEnclosedByDataEnvironmentExpr = false;
11720 const Expr *EnclosingExpr = nullptr;
11722 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
11723 VD, CurrentRegionOnly,
11724 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
11726 OpenMPClauseKind) -> bool {
11728 assert(!StackComponents.empty() &&
11729 "Map clause expression with no components!");
11730 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
11731 "Map clause expression with unexpected base!");
11733 // The whole expression in the stack.
11734 auto *RE = StackComponents.front().getAssociatedExpression();
11736 // Expressions must start from the same base. Here we detect at which
11737 // point both expressions diverge from each other and see if we can
11738 // detect if the memory referred to both expressions is contiguous and
11740 auto CI = CurComponents.rbegin();
11741 auto CE = CurComponents.rend();
11742 auto SI = StackComponents.rbegin();
11743 auto SE = StackComponents.rend();
11744 for (; CI != CE && SI != SE; ++CI, ++SI) {
11746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
11747 // At most one list item can be an array item derived from a given
11748 // variable in map clauses of the same construct.
11749 if (CurrentRegionOnly &&
11750 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
11751 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
11752 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
11753 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
11754 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
11755 diag::err_omp_multiple_array_items_in_map_clause)
11756 << CI->getAssociatedExpression()->getSourceRange();
11757 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
11758 diag::note_used_here)
11759 << SI->getAssociatedExpression()->getSourceRange();
11763 // Do both expressions have the same kind?
11764 if (CI->getAssociatedExpression()->getStmtClass() !=
11765 SI->getAssociatedExpression()->getStmtClass())
11768 // Are we dealing with different variables/fields?
11769 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
11772 // Check if the extra components of the expressions in the enclosing
11773 // data environment are redundant for the current base declaration.
11774 // If they are, the maps completely overlap, which is legal.
11775 for (; SI != SE; ++SI) {
11778 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
11779 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
11780 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>(
11781 SI->getAssociatedExpression())) {
11782 auto *E = OASE->getBase()->IgnoreParenImpCasts();
11784 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11786 if (Type.isNull() || Type->isAnyPointerType() ||
11787 CheckArrayExpressionDoesNotReferToWholeSize(
11788 SemaRef, SI->getAssociatedExpression(), Type))
11792 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11793 // List items of map clauses in the same construct must not share
11794 // original storage.
11796 // If the expressions are exactly the same or one is a subset of the
11797 // other, it means they are sharing storage.
11798 if (CI == CE && SI == SE) {
11799 if (CurrentRegionOnly) {
11800 if (CKind == OMPC_map)
11801 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11803 assert(CKind == OMPC_to || CKind == OMPC_from);
11804 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11807 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11808 << RE->getSourceRange();
11811 // If we find the same expression in the enclosing data environment,
11813 IsEnclosedByDataEnvironmentExpr = true;
11818 QualType DerivedType =
11819 std::prev(CI)->getAssociatedDeclaration()->getType();
11820 SourceLocation DerivedLoc =
11821 std::prev(CI)->getAssociatedExpression()->getExprLoc();
11823 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11824 // If the type of a list item is a reference to a type T then the type
11825 // will be considered to be T for all purposes of this clause.
11826 DerivedType = DerivedType.getNonReferenceType();
11828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
11829 // A variable for which the type is pointer and an array section
11830 // derived from that variable must not appear as list items of map
11831 // clauses of the same construct.
11833 // Also, cover one of the cases in:
11834 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11835 // If any part of the original storage of a list item has corresponding
11836 // storage in the device data environment, all of the original storage
11837 // must have corresponding storage in the device data environment.
11839 if (DerivedType->isAnyPointerType()) {
11840 if (CI == CE || SI == SE) {
11843 diag::err_omp_pointer_mapped_along_with_derived_section)
11846 assert(CI != CE && SI != SE);
11847 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
11850 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11851 << RE->getSourceRange();
11855 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11856 // List items of map clauses in the same construct must not share
11857 // original storage.
11859 // An expression is a subset of the other.
11860 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
11861 if (CKind == OMPC_map)
11862 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11864 assert(CKind == OMPC_to || CKind == OMPC_from);
11865 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11868 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11869 << RE->getSourceRange();
11873 // The current expression uses the same base as other expression in the
11874 // data environment but does not contain it completely.
11875 if (!CurrentRegionOnly && SI != SE)
11876 EnclosingExpr = RE;
11878 // The current expression is a subset of the expression in the data
11880 IsEnclosedByDataEnvironmentExpr |=
11881 (!CurrentRegionOnly && CI != CE && SI == SE);
11886 if (CurrentRegionOnly)
11889 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11890 // If any part of the original storage of a list item has corresponding
11891 // storage in the device data environment, all of the original storage must
11892 // have corresponding storage in the device data environment.
11893 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
11894 // If a list item is an element of a structure, and a different element of
11895 // the structure has a corresponding list item in the device data environment
11896 // prior to a task encountering the construct associated with the map clause,
11897 // then the list item must also have a corresponding list item in the device
11898 // data environment prior to the task encountering the construct.
11900 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
11902 diag::err_omp_original_storage_is_shared_and_does_not_contain)
11904 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
11905 << EnclosingExpr->getSourceRange();
11913 // Utility struct that gathers all the related lists associated with a mappable
11915 struct MappableVarListInfo final {
11916 // The list of expressions.
11917 ArrayRef<Expr *> VarList;
11918 // The list of processed expressions.
11919 SmallVector<Expr *, 16> ProcessedVarList;
11920 // The mappble components for each expression.
11921 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
11922 // The base declaration of the variable.
11923 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
11925 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
11926 // We have a list of components and base declarations for each entry in the
11928 VarComponents.reserve(VarList.size());
11929 VarBaseDeclarations.reserve(VarList.size());
11934 // Check the validity of the provided variable list for the provided clause kind
11935 // \a CKind. In the check process the valid expressions, and mappable expression
11936 // components and variables are extracted and used to fill \a Vars,
11937 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
11938 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
11940 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
11941 OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
11942 SourceLocation StartLoc,
11943 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
11944 bool IsMapTypeImplicit = false) {
11945 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
11946 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
11947 "Unexpected clause kind with mappable expressions!");
11949 // Keep track of the mappable components and base declarations in this clause.
11950 // Each entry in the list is going to have a list of components associated. We
11951 // record each set of the components so that we can build the clause later on.
11952 // In the end we should have the same amount of declarations and component
11955 for (auto &RE : MVLI.VarList) {
11956 assert(RE && "Null expr in omp to/from/map clause");
11957 SourceLocation ELoc = RE->getExprLoc();
11959 auto *VE = RE->IgnoreParenLValueCasts();
11961 if (VE->isValueDependent() || VE->isTypeDependent() ||
11962 VE->isInstantiationDependent() ||
11963 VE->containsUnexpandedParameterPack()) {
11964 // We can only analyze this information once the missing information is
11966 MVLI.ProcessedVarList.push_back(RE);
11970 auto *SimpleExpr = RE->IgnoreParenCasts();
11972 if (!RE->IgnoreParenImpCasts()->isLValue()) {
11974 diag::err_omp_expected_named_var_member_or_array_expression)
11975 << RE->getSourceRange();
11979 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
11980 ValueDecl *CurDeclaration = nullptr;
11982 // Obtain the array or member expression bases if required. Also, fill the
11983 // components array with all the components identified in the process.
11984 auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents,
11985 CKind, /*NoDiagnose=*/false);
11989 assert(!CurComponents.empty() &&
11990 "Invalid mappable expression information.");
11992 // For the following checks, we rely on the base declaration which is
11993 // expected to be associated with the last component. The declaration is
11994 // expected to be a variable or a field (if 'this' is being mapped).
11995 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
11996 assert(CurDeclaration && "Null decl on map clause.");
11998 CurDeclaration->isCanonicalDecl() &&
11999 "Expecting components to have associated only canonical declarations.");
12001 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12002 auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12004 assert((VD || FD) && "Only variables or fields are expected here!");
12007 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12008 // threadprivate variables cannot appear in a map clause.
12009 // OpenMP 4.5 [2.10.5, target update Construct]
12010 // threadprivate variables cannot appear in a from clause.
12011 if (VD && DSAS->isThreadPrivate(VD)) {
12012 auto DVar = DSAS->getTopDSA(VD, false);
12013 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12014 << getOpenMPClauseName(CKind);
12015 ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
12019 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12020 // A list item cannot appear in both a map clause and a data-sharing
12021 // attribute clause on the same construct.
12023 // Check conflicts with other map clause expressions. We check the conflicts
12024 // with the current construct separately from the enclosing data
12025 // environment, because the restrictions are different. We only have to
12026 // check conflicts across regions for the map clauses.
12027 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12028 /*CurrentRegionOnly=*/true, CurComponents, CKind))
12030 if (CKind == OMPC_map &&
12031 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12032 /*CurrentRegionOnly=*/false, CurComponents, CKind))
12035 // OpenMP 4.5 [2.10.5, target update Construct]
12036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12037 // If the type of a list item is a reference to a type T then the type will
12038 // be considered to be T for all purposes of this clause.
12039 QualType Type = CurDeclaration->getType().getNonReferenceType();
12041 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12042 // A list item in a to or from clause must have a mappable type.
12043 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12044 // A list item must have a mappable type.
12045 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12049 if (CKind == OMPC_map) {
12050 // target enter data
12051 // OpenMP [2.10.2, Restrictions, p. 99]
12052 // A map-type must be specified in all map clauses and must be either
12054 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12055 if (DKind == OMPD_target_enter_data &&
12056 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12057 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12058 << (IsMapTypeImplicit ? 1 : 0)
12059 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12060 << getOpenMPDirectiveName(DKind);
12064 // target exit_data
12065 // OpenMP [2.10.3, Restrictions, p. 102]
12066 // A map-type must be specified in all map clauses and must be either
12067 // from, release, or delete.
12068 if (DKind == OMPD_target_exit_data &&
12069 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12070 MapType == OMPC_MAP_delete)) {
12071 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12072 << (IsMapTypeImplicit ? 1 : 0)
12073 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12074 << getOpenMPDirectiveName(DKind);
12078 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12079 // A list item cannot appear in both a map clause and a data-sharing
12080 // attribute clause on the same construct
12081 if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
12082 DKind == OMPD_target_teams_distribute ||
12083 DKind == OMPD_target_teams_distribute_parallel_for ||
12084 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
12085 DKind == OMPD_target_teams_distribute_simd) && VD) {
12086 auto DVar = DSAS->getTopDSA(VD, false);
12087 if (isOpenMPPrivate(DVar.CKind)) {
12088 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12089 << getOpenMPClauseName(DVar.CKind)
12090 << getOpenMPClauseName(OMPC_map)
12091 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12092 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
12098 // Save the current expression.
12099 MVLI.ProcessedVarList.push_back(RE);
12101 // Store the components in the stack so that they can be used to check
12102 // against other clauses later on.
12103 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12104 /*WhereFoundClauseKind=*/OMPC_map);
12106 // Save the components and declaration to create the clause. For purposes of
12107 // the clause creation, any component list that has has base 'this' uses
12108 // null as base declaration.
12109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12110 MVLI.VarComponents.back().append(CurComponents.begin(),
12111 CurComponents.end());
12112 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12118 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
12119 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12120 SourceLocation MapLoc, SourceLocation ColonLoc,
12121 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12122 SourceLocation LParenLoc, SourceLocation EndLoc) {
12123 MappableVarListInfo MVLI(VarList);
12124 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
12125 MapType, IsMapTypeImplicit);
12127 // We need to produce a map clause even if we don't have variables so that
12128 // other diagnostics related with non-existing map clauses are accurate.
12129 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12130 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12131 MVLI.VarComponents, MapTypeModifier, MapType,
12132 IsMapTypeImplicit, MapLoc);
12135 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
12136 TypeResult ParsedType) {
12137 assert(ParsedType.isUsable());
12139 QualType ReductionType = GetTypeFromParser(ParsedType.get());
12140 if (ReductionType.isNull())
12143 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12144 // A type name in a declare reduction directive cannot be a function type, an
12145 // array type, a reference type, or a type qualified with const, volatile or
12147 if (ReductionType.hasQualifiers()) {
12148 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12152 if (ReductionType->isFunctionType()) {
12153 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12156 if (ReductionType->isReferenceType()) {
12157 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12160 if (ReductionType->isArrayType()) {
12161 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12164 return ReductionType;
12167 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
12168 Scope *S, DeclContext *DC, DeclarationName Name,
12169 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12170 AccessSpecifier AS, Decl *PrevDeclInScope) {
12171 SmallVector<Decl *, 8> Decls;
12172 Decls.reserve(ReductionTypes.size());
12174 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12175 forRedeclarationInCurContext());
12176 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12177 // A reduction-identifier may not be re-declared in the current scope for the
12178 // same type or for a type that is compatible according to the base language
12180 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12181 OMPDeclareReductionDecl *PrevDRD = nullptr;
12182 bool InCompoundScope = true;
12183 if (S != nullptr) {
12184 // Find previous declaration with the same name not referenced in other
12186 FunctionScopeInfo *ParentFn = getEnclosingFunction();
12188 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12189 LookupName(Lookup, S);
12190 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12191 /*AllowInlineNamespace=*/false);
12192 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12193 auto Filter = Lookup.makeFilter();
12194 while (Filter.hasNext()) {
12195 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12196 if (InCompoundScope) {
12197 auto I = UsedAsPrevious.find(PrevDecl);
12198 if (I == UsedAsPrevious.end())
12199 UsedAsPrevious[PrevDecl] = false;
12200 if (auto *D = PrevDecl->getPrevDeclInScope())
12201 UsedAsPrevious[D] = true;
12203 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12204 PrevDecl->getLocation();
12207 if (InCompoundScope) {
12208 for (auto &PrevData : UsedAsPrevious) {
12209 if (!PrevData.second) {
12210 PrevDRD = PrevData.first;
12215 } else if (PrevDeclInScope != nullptr) {
12216 auto *PrevDRDInScope = PrevDRD =
12217 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12219 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12220 PrevDRDInScope->getLocation();
12221 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12222 } while (PrevDRDInScope != nullptr);
12224 for (auto &TyData : ReductionTypes) {
12225 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12226 bool Invalid = false;
12227 if (I != PreviousRedeclTypes.end()) {
12228 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12230 Diag(I->second, diag::note_previous_definition);
12233 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12234 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12235 Name, TyData.first, PrevDRD);
12237 DRD->setAccess(AS);
12238 Decls.push_back(DRD);
12240 DRD->setInvalidDecl();
12245 return DeclGroupPtrTy::make(
12246 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12249 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
12250 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12252 // Enter new function scope.
12253 PushFunctionScope();
12254 getCurFunction()->setHasBranchProtectedScope();
12255 getCurFunction()->setHasOMPDeclareReductionCombiner();
12258 PushDeclContext(S, DRD);
12262 PushExpressionEvaluationContext(
12263 ExpressionEvaluationContext::PotentiallyEvaluated);
12265 QualType ReductionType = DRD->getType();
12266 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12267 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12268 // uses semantics of argument handles by value, but it should be passed by
12269 // reference. C lang does not support references, so pass all parameters as
12271 // Create 'T omp_in;' variable.
12273 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12274 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12275 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12276 // uses semantics of argument handles by value, but it should be passed by
12277 // reference. C lang does not support references, so pass all parameters as
12279 // Create 'T omp_out;' variable.
12281 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12282 if (S != nullptr) {
12283 PushOnScopeChains(OmpInParm, S);
12284 PushOnScopeChains(OmpOutParm, S);
12286 DRD->addDecl(OmpInParm);
12287 DRD->addDecl(OmpOutParm);
12291 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
12292 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12293 DiscardCleanupsInEvaluationContext();
12294 PopExpressionEvaluationContext();
12297 PopFunctionScopeInfo();
12299 if (Combiner != nullptr)
12300 DRD->setCombiner(Combiner);
12302 DRD->setInvalidDecl();
12305 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
12306 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12308 // Enter new function scope.
12309 PushFunctionScope();
12310 getCurFunction()->setHasBranchProtectedScope();
12313 PushDeclContext(S, DRD);
12317 PushExpressionEvaluationContext(
12318 ExpressionEvaluationContext::PotentiallyEvaluated);
12320 QualType ReductionType = DRD->getType();
12321 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12322 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12323 // uses semantics of argument handles by value, but it should be passed by
12324 // reference. C lang does not support references, so pass all parameters as
12326 // Create 'T omp_priv;' variable.
12327 auto *OmpPrivParm =
12328 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12329 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12330 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12331 // uses semantics of argument handles by value, but it should be passed by
12332 // reference. C lang does not support references, so pass all parameters as
12334 // Create 'T omp_orig;' variable.
12335 auto *OmpOrigParm =
12336 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12337 if (S != nullptr) {
12338 PushOnScopeChains(OmpPrivParm, S);
12339 PushOnScopeChains(OmpOrigParm, S);
12341 DRD->addDecl(OmpPrivParm);
12342 DRD->addDecl(OmpOrigParm);
12344 return OmpPrivParm;
12347 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
12348 VarDecl *OmpPrivParm) {
12349 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12350 DiscardCleanupsInEvaluationContext();
12351 PopExpressionEvaluationContext();
12354 PopFunctionScopeInfo();
12356 if (Initializer != nullptr) {
12357 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12358 } else if (OmpPrivParm->hasInit()) {
12359 DRD->setInitializer(OmpPrivParm->getInit(),
12360 OmpPrivParm->isDirectInit()
12361 ? OMPDeclareReductionDecl::DirectInit
12362 : OMPDeclareReductionDecl::CopyInit);
12364 DRD->setInvalidDecl();
12368 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
12369 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12370 for (auto *D : DeclReductions.get()) {
12372 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12374 PushOnScopeChains(DRD, S, /*AddToContext=*/false);
12376 D->setInvalidDecl();
12378 return DeclReductions;
12381 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
12382 SourceLocation StartLoc,
12383 SourceLocation LParenLoc,
12384 SourceLocation EndLoc) {
12385 Expr *ValExpr = NumTeams;
12386 Stmt *HelperValStmt = nullptr;
12388 // OpenMP [teams Constrcut, Restrictions]
12389 // The num_teams expression must evaluate to a positive integer value.
12390 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12391 /*StrictlyPositive=*/true))
12394 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12395 OpenMPDirectiveKind CaptureRegion =
12396 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12397 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12398 ValExpr = MakeFullExpr(ValExpr).get();
12399 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12400 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12401 HelperValStmt = buildPreInits(Context, Captures);
12404 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12405 StartLoc, LParenLoc, EndLoc);
12408 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
12409 SourceLocation StartLoc,
12410 SourceLocation LParenLoc,
12411 SourceLocation EndLoc) {
12412 Expr *ValExpr = ThreadLimit;
12413 Stmt *HelperValStmt = nullptr;
12415 // OpenMP [teams Constrcut, Restrictions]
12416 // The thread_limit expression must evaluate to a positive integer value.
12417 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12418 /*StrictlyPositive=*/true))
12421 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12422 OpenMPDirectiveKind CaptureRegion =
12423 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12424 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12425 ValExpr = MakeFullExpr(ValExpr).get();
12426 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12427 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12428 HelperValStmt = buildPreInits(Context, Captures);
12431 return new (Context) OMPThreadLimitClause(
12432 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12435 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
12436 SourceLocation StartLoc,
12437 SourceLocation LParenLoc,
12438 SourceLocation EndLoc) {
12439 Expr *ValExpr = Priority;
12441 // OpenMP [2.9.1, task Constrcut]
12442 // The priority-value is a non-negative numerical scalar expression.
12443 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12444 /*StrictlyPositive=*/false))
12447 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12450 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
12451 SourceLocation StartLoc,
12452 SourceLocation LParenLoc,
12453 SourceLocation EndLoc) {
12454 Expr *ValExpr = Grainsize;
12456 // OpenMP [2.9.2, taskloop Constrcut]
12457 // The parameter of the grainsize clause must be a positive integer
12459 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12460 /*StrictlyPositive=*/true))
12463 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12466 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
12467 SourceLocation StartLoc,
12468 SourceLocation LParenLoc,
12469 SourceLocation EndLoc) {
12470 Expr *ValExpr = NumTasks;
12472 // OpenMP [2.9.2, taskloop Constrcut]
12473 // The parameter of the num_tasks clause must be a positive integer
12475 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12476 /*StrictlyPositive=*/true))
12479 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12482 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
12483 SourceLocation LParenLoc,
12484 SourceLocation EndLoc) {
12485 // OpenMP [2.13.2, critical construct, Description]
12486 // ... where hint-expression is an integer constant expression that evaluates
12487 // to a valid lock hint.
12488 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12489 if (HintExpr.isInvalid())
12491 return new (Context)
12492 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12495 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
12496 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12497 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12498 SourceLocation EndLoc) {
12499 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12500 std::string Values;
12502 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12504 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12505 << Values << getOpenMPClauseName(OMPC_dist_schedule);
12508 Expr *ValExpr = ChunkSize;
12509 Stmt *HelperValStmt = nullptr;
12511 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12512 !ChunkSize->isInstantiationDependent() &&
12513 !ChunkSize->containsUnexpandedParameterPack()) {
12514 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12516 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12517 if (Val.isInvalid())
12520 ValExpr = Val.get();
12522 // OpenMP [2.7.1, Restrictions]
12523 // chunk_size must be a loop invariant integer expression with a positive
12525 llvm::APSInt Result;
12526 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12527 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12528 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12529 << "dist_schedule" << ChunkSize->getSourceRange();
12532 } else if (getOpenMPCaptureRegionForClause(
12533 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12535 !CurContext->isDependentContext()) {
12536 ValExpr = MakeFullExpr(ValExpr).get();
12537 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12538 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12539 HelperValStmt = buildPreInits(Context, Captures);
12544 return new (Context)
12545 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12546 Kind, ValExpr, HelperValStmt);
12549 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
12550 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
12551 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12552 SourceLocation KindLoc, SourceLocation EndLoc) {
12553 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12554 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12556 SourceLocation Loc;
12558 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12559 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12560 OMPC_DEFAULTMAP_MODIFIER_tofrom);
12563 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12564 OMPC_DEFAULTMAP_scalar);
12568 Diag(Loc, diag::err_omp_unexpected_clause_value)
12569 << Value << getOpenMPClauseName(OMPC_defaultmap);
12572 DSAStack->setDefaultDMAToFromScalar(StartLoc);
12574 return new (Context)
12575 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12578 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
12579 DeclContext *CurLexicalContext = getCurLexicalContext();
12580 if (!CurLexicalContext->isFileContext() &&
12581 !CurLexicalContext->isExternCContext() &&
12582 !CurLexicalContext->isExternCXXContext() &&
12583 !isa<CXXRecordDecl>(CurLexicalContext) &&
12584 !isa<ClassTemplateDecl>(CurLexicalContext) &&
12585 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12586 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12587 Diag(Loc, diag::err_omp_region_not_file_context);
12590 if (IsInOpenMPDeclareTargetContext) {
12591 Diag(Loc, diag::err_omp_enclosed_declare_target);
12595 IsInOpenMPDeclareTargetContext = true;
12599 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
12600 assert(IsInOpenMPDeclareTargetContext &&
12601 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12603 IsInOpenMPDeclareTargetContext = false;
12606 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
12607 CXXScopeSpec &ScopeSpec,
12608 const DeclarationNameInfo &Id,
12609 OMPDeclareTargetDeclAttr::MapTypeTy MT,
12610 NamedDeclSetType &SameDirectiveDecls) {
12611 LookupResult Lookup(*this, Id, LookupOrdinaryName);
12612 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12614 if (Lookup.isAmbiguous())
12616 Lookup.suppressDiagnostics();
12618 if (!Lookup.isSingleResult()) {
12619 if (TypoCorrection Corrected =
12620 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12621 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12622 CTK_ErrorRecovery)) {
12623 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12625 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12629 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12633 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12634 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12635 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12636 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
12638 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
12639 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
12641 if (ASTMutationListener *ML = Context.getASTMutationListener())
12642 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
12643 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
12644 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
12645 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
12649 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
12652 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
12653 Sema &SemaRef, Decl *D) {
12656 Decl *LD = nullptr;
12657 if (isa<TagDecl>(D)) {
12658 LD = cast<TagDecl>(D)->getDefinition();
12659 } else if (isa<VarDecl>(D)) {
12660 LD = cast<VarDecl>(D)->getDefinition();
12662 // If this is an implicit variable that is legal and we do not need to do
12664 if (cast<VarDecl>(D)->isImplicit()) {
12665 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12666 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12668 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12669 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12673 } else if (isa<FunctionDecl>(D)) {
12674 const FunctionDecl *FD = nullptr;
12675 if (cast<FunctionDecl>(D)->hasBody(FD))
12676 LD = const_cast<FunctionDecl *>(FD);
12678 // If the definition is associated with the current declaration in the
12679 // target region (it can be e.g. a lambda) that is legal and we do not need
12680 // to do anything else.
12682 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12683 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12685 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12686 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12692 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12693 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
12694 // Outlined declaration is not declared target.
12695 if (LD->isOutOfLine()) {
12696 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12697 SemaRef.Diag(SL, diag::note_used_here) << SR;
12699 DeclContext *DC = LD->getDeclContext();
12701 if (isa<FunctionDecl>(DC) &&
12702 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
12704 DC = DC->getParent();
12709 // Is not declared in target context.
12710 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12711 SemaRef.Diag(SL, diag::note_used_here) << SR;
12713 // Mark decl as declared target to prevent further diagnostic.
12714 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12715 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12717 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12718 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12722 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
12723 Sema &SemaRef, DSAStackTy *Stack,
12725 if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
12727 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType()))
12732 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
12733 SourceLocation IdLoc) {
12734 if (!D || D->isInvalidDecl())
12736 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
12737 SourceLocation SL = E ? E->getLocStart() : D->getLocation();
12738 // 2.10.6: threadprivate variable cannot appear in a declare target directive.
12739 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12740 if (DSAStack->isThreadPrivate(VD)) {
12741 Diag(SL, diag::err_omp_threadprivate_in_target);
12742 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
12746 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
12747 // Problem if any with var declared with incomplete type will be reported
12748 // as normal, so no need to check it here.
12749 if ((E || !VD->getType()->isIncompleteType()) &&
12750 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
12751 // Mark decl as declared target to prevent further diagnostic.
12752 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
12753 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12754 Context, OMPDeclareTargetDeclAttr::MT_To);
12756 if (ASTMutationListener *ML = Context.getASTMutationListener())
12757 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
12762 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12763 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12764 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12765 OMPDeclareTargetDeclAttr::MT_Link)) {
12766 assert(IdLoc.isValid() && "Source location is expected");
12767 Diag(IdLoc, diag::err_omp_function_in_link_clause);
12768 Diag(FD->getLocation(), diag::note_defined_here) << FD;
12773 // Checking declaration inside declare target region.
12774 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
12775 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
12776 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12777 Context, OMPDeclareTargetDeclAttr::MT_To);
12779 if (ASTMutationListener *ML = Context.getASTMutationListener())
12780 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12784 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
12787 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
12788 SourceLocation StartLoc,
12789 SourceLocation LParenLoc,
12790 SourceLocation EndLoc) {
12791 MappableVarListInfo MVLI(VarList);
12792 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
12793 if (MVLI.ProcessedVarList.empty())
12796 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12797 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12798 MVLI.VarComponents);
12801 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
12802 SourceLocation StartLoc,
12803 SourceLocation LParenLoc,
12804 SourceLocation EndLoc) {
12805 MappableVarListInfo MVLI(VarList);
12806 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
12807 if (MVLI.ProcessedVarList.empty())
12810 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12811 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12812 MVLI.VarComponents);
12815 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
12816 SourceLocation StartLoc,
12817 SourceLocation LParenLoc,
12818 SourceLocation EndLoc) {
12819 MappableVarListInfo MVLI(VarList);
12820 SmallVector<Expr *, 8> PrivateCopies;
12821 SmallVector<Expr *, 8> Inits;
12823 for (auto &RefExpr : VarList) {
12824 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
12825 SourceLocation ELoc;
12826 SourceRange ERange;
12827 Expr *SimpleRefExpr = RefExpr;
12828 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12830 // It will be analyzed later.
12831 MVLI.ProcessedVarList.push_back(RefExpr);
12832 PrivateCopies.push_back(nullptr);
12833 Inits.push_back(nullptr);
12835 ValueDecl *D = Res.first;
12839 QualType Type = D->getType();
12840 Type = Type.getNonReferenceType().getUnqualifiedType();
12842 auto *VD = dyn_cast<VarDecl>(D);
12844 // Item should be a pointer or reference to pointer.
12845 if (!Type->isPointerType()) {
12846 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
12847 << 0 << RefExpr->getSourceRange();
12851 // Build the private variable and the expression that refers to it.
12852 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
12853 D->hasAttrs() ? &D->getAttrs() : nullptr);
12854 if (VDPrivate->isInvalidDecl())
12857 CurContext->addDecl(VDPrivate);
12858 auto VDPrivateRefExpr = buildDeclRefExpr(
12859 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12861 // Add temporary variable to initialize the private copy of the pointer.
12863 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
12864 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12865 RefExpr->getExprLoc());
12866 AddInitializerToDecl(VDPrivate,
12867 DefaultLvalueConversion(VDInitRefExpr).get(),
12868 /*DirectInit=*/false);
12870 // If required, build a capture to implement the privatization initialized
12871 // with the current list item value.
12872 DeclRefExpr *Ref = nullptr;
12874 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12875 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
12876 PrivateCopies.push_back(VDPrivateRefExpr);
12877 Inits.push_back(VDInitRefExpr);
12879 // We need to add a data sharing attribute for this variable to make sure it
12880 // is correctly captured. A variable that shows up in a use_device_ptr has
12881 // similar properties of a first private variable.
12882 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12884 // Create a mappable component for the list item. List items in this clause
12885 // only need a component.
12886 MVLI.VarBaseDeclarations.push_back(D);
12887 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12888 MVLI.VarComponents.back().push_back(
12889 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
12892 if (MVLI.ProcessedVarList.empty())
12895 return OMPUseDevicePtrClause::Create(
12896 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12897 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
12900 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
12901 SourceLocation StartLoc,
12902 SourceLocation LParenLoc,
12903 SourceLocation EndLoc) {
12904 MappableVarListInfo MVLI(VarList);
12905 for (auto &RefExpr : VarList) {
12906 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
12907 SourceLocation ELoc;
12908 SourceRange ERange;
12909 Expr *SimpleRefExpr = RefExpr;
12910 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12912 // It will be analyzed later.
12913 MVLI.ProcessedVarList.push_back(RefExpr);
12915 ValueDecl *D = Res.first;
12919 QualType Type = D->getType();
12920 // item should be a pointer or array or reference to pointer or array
12921 if (!Type.getNonReferenceType()->isPointerType() &&
12922 !Type.getNonReferenceType()->isArrayType()) {
12923 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
12924 << 0 << RefExpr->getSourceRange();
12928 // Check if the declaration in the clause does not show up in any data
12929 // sharing attribute.
12930 auto DVar = DSAStack->getTopDSA(D, false);
12931 if (isOpenMPPrivate(DVar.CKind)) {
12932 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12933 << getOpenMPClauseName(DVar.CKind)
12934 << getOpenMPClauseName(OMPC_is_device_ptr)
12935 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12936 ReportOriginalDSA(*this, DSAStack, D, DVar);
12940 Expr *ConflictExpr;
12941 if (DSAStack->checkMappableExprComponentListsForDecl(
12942 D, /*CurrentRegionOnly=*/true,
12944 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
12945 OpenMPClauseKind) -> bool {
12946 ConflictExpr = R.front().getAssociatedExpression();
12949 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
12950 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
12951 << ConflictExpr->getSourceRange();
12955 // Store the components in the stack so that they can be used to check
12956 // against other clauses later on.
12957 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
12958 DSAStack->addMappableExpressionComponents(
12959 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
12961 // Record the expression we've just processed.
12962 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
12964 // Create a mappable component for the list item. List items in this clause
12965 // only need a component. We use a null declaration to signal fields in
12967 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
12968 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
12969 "Unexpected device pointer expression!");
12970 MVLI.VarBaseDeclarations.push_back(
12971 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
12972 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12973 MVLI.VarComponents.back().push_back(MC);
12976 if (MVLI.ProcessedVarList.empty())
12979 return OMPIsDevicePtrClause::Create(
12980 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12981 MVLI.VarBaseDeclarations, MVLI.VarComponents);