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()) {
1293 IsByRef = !DSAStack->hasExplicitDSA(
1294 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1295 Level, /*NotLastprivate=*/true);
1298 // When passing data by copy, we need to make sure it fits the uintptr size
1299 // and alignment, because the runtime library only deals with uintptr types.
1300 // If it does not fit the uintptr size, we need to pass the data by reference
1303 (Ctx.getTypeSizeInChars(Ty) >
1304 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1305 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1312 unsigned Sema::getOpenMPNestingLevel() const {
1313 assert(getLangOpts().OpenMP);
1314 return DSAStack->getNestingLevel();
1317 bool Sema::isInOpenMPTargetExecutionDirective() const {
1318 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1319 !DSAStack->isClauseParsingMode()) ||
1320 DSAStack->hasDirective(
1321 [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
1322 SourceLocation) -> bool {
1323 return isOpenMPTargetExecutionDirective(K);
1328 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) {
1329 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1330 D = getCanonicalDecl(D);
1332 // If we are attempting to capture a global variable in a directive with
1333 // 'target' we return true so that this global is also mapped to the device.
1335 // FIXME: If the declaration is enclosed in a 'declare target' directive,
1336 // then it should not be captured. Therefore, an extra check has to be
1337 // inserted here once support for 'declare target' is added.
1339 auto *VD = dyn_cast<VarDecl>(D);
1340 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1343 if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1344 (!DSAStack->isClauseParsingMode() ||
1345 DSAStack->getParentDirective() != OMPD_unknown)) {
1346 auto &&Info = DSAStack->isLoopControlVariable(D);
1348 (VD && VD->hasLocalStorage() &&
1349 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1350 (VD && DSAStack->isForceVarCapturing()))
1351 return VD ? VD : Info.second;
1352 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1353 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1354 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1355 DVarPrivate = DSAStack->hasDSA(
1356 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1357 DSAStack->isClauseParsingMode());
1358 if (DVarPrivate.CKind != OMPC_unknown)
1359 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1364 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1365 unsigned Level) const {
1366 SmallVector<OpenMPDirectiveKind, 4> Regions;
1367 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1368 FunctionScopesIndex -= Regions.size();
1371 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) {
1372 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1373 return DSAStack->hasExplicitDSA(
1374 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1376 (DSAStack->isClauseParsingMode() &&
1377 DSAStack->getClauseParsingMode() == OMPC_private) ||
1378 // Consider taskgroup reduction descriptor variable a private to avoid
1379 // possible capture in the region.
1380 (DSAStack->hasExplicitDirective(
1381 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1383 DSAStack->isTaskgroupReductionRef(D, Level));
1386 void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) {
1387 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1388 D = getCanonicalDecl(D);
1389 OpenMPClauseKind OMPC = OMPC_unknown;
1390 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1391 const unsigned NewLevel = I - 1;
1392 if (DSAStack->hasExplicitDSA(D,
1393 [&OMPC](const OpenMPClauseKind K) {
1394 if (isOpenMPPrivate(K)) {
1402 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1404 [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
1405 OpenMPClauseKind) { return true; })) {
1409 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1411 OMPC = OMPC_firstprivate;
1415 if (OMPC != OMPC_unknown)
1416 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1419 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) {
1420 assert(LangOpts.OpenMP && "OpenMP is not allowed");
1421 // Return true if the current level is no longer enclosed in a target region.
1423 auto *VD = dyn_cast<VarDecl>(D);
1424 return VD && !VD->hasLocalStorage() &&
1425 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1429 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1431 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
1432 const DeclarationNameInfo &DirName,
1433 Scope *CurScope, SourceLocation Loc) {
1434 DSAStack->push(DKind, DirName, CurScope, Loc);
1435 PushExpressionEvaluationContext(
1436 ExpressionEvaluationContext::PotentiallyEvaluated);
1439 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
1440 DSAStack->setClauseParsingMode(K);
1443 void Sema::EndOpenMPClause() {
1444 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1447 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1448 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1449 // A variable of class type (or array thereof) that appears in a lastprivate
1450 // clause requires an accessible, unambiguous default constructor for the
1451 // class type, unless the list item is also specified in a firstprivate
1453 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1454 for (auto *C : D->clauses()) {
1455 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1456 SmallVector<Expr *, 8> PrivateCopies;
1457 for (auto *DE : Clause->varlists()) {
1458 if (DE->isValueDependent() || DE->isTypeDependent()) {
1459 PrivateCopies.push_back(nullptr);
1462 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1463 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1464 QualType Type = VD->getType().getNonReferenceType();
1465 auto DVar = DSAStack->getTopDSA(VD, false);
1466 if (DVar.CKind == OMPC_lastprivate) {
1467 // Generate helper private variable and initialize it with the
1468 // default value. The address of the original variable is replaced
1469 // by the address of the new private variable in CodeGen. This new
1470 // variable is not added to IdResolver, so the code in the OpenMP
1471 // region uses original variable for proper diagnostics.
1472 auto *VDPrivate = buildVarDecl(
1473 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1474 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1475 ActOnUninitializedDecl(VDPrivate);
1476 if (VDPrivate->isInvalidDecl())
1478 PrivateCopies.push_back(buildDeclRefExpr(
1479 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1481 // The variable is also a firstprivate, so initialization sequence
1482 // for private copy is generated already.
1483 PrivateCopies.push_back(nullptr);
1486 // Set initializers to private copies if no errors were found.
1487 if (PrivateCopies.size() == Clause->varlist_size())
1488 Clause->setPrivateCopies(PrivateCopies);
1494 DiscardCleanupsInEvaluationContext();
1495 PopExpressionEvaluationContext();
1498 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1499 Expr *NumIterations, Sema &SemaRef,
1500 Scope *S, DSAStackTy *Stack);
1504 class VarDeclFilterCCC : public CorrectionCandidateCallback {
1509 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1510 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1511 NamedDecl *ND = Candidate.getCorrectionDecl();
1512 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1513 return VD->hasGlobalStorage() &&
1514 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1515 SemaRef.getCurScope());
1521 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1526 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1527 bool ValidateCandidate(const TypoCorrection &Candidate) override {
1528 NamedDecl *ND = Candidate.getCorrectionDecl();
1529 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1530 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1531 SemaRef.getCurScope());
1539 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
1540 CXXScopeSpec &ScopeSpec,
1541 const DeclarationNameInfo &Id) {
1542 LookupResult Lookup(*this, Id, LookupOrdinaryName);
1543 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1545 if (Lookup.isAmbiguous())
1549 if (!Lookup.isSingleResult()) {
1550 if (TypoCorrection Corrected = CorrectTypo(
1551 Id, LookupOrdinaryName, CurScope, nullptr,
1552 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1553 diagnoseTypo(Corrected,
1554 PDiag(Lookup.empty()
1555 ? diag::err_undeclared_var_use_suggest
1556 : diag::err_omp_expected_var_arg_suggest)
1558 VD = Corrected.getCorrectionDeclAs<VarDecl>();
1560 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1561 : diag::err_omp_expected_var_arg)
1566 if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1567 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1568 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1572 Lookup.suppressDiagnostics();
1574 // OpenMP [2.9.2, Syntax, C/C++]
1575 // Variables must be file-scope, namespace-scope, or static block-scope.
1576 if (!VD->hasGlobalStorage()) {
1577 Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1578 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1580 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1581 Diag(VD->getLocation(),
1582 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1587 VarDecl *CanonicalVD = VD->getCanonicalDecl();
1588 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1589 // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1590 // A threadprivate directive for file-scope variables must appear outside
1591 // any definition or declaration.
1592 if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1593 !getCurLexicalContext()->isTranslationUnit()) {
1594 Diag(Id.getLoc(), diag::err_omp_var_scope)
1595 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1597 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1598 Diag(VD->getLocation(),
1599 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1603 // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1604 // A threadprivate directive for static class member variables must appear
1605 // in the class definition, in the same scope in which the member
1606 // variables are declared.
1607 if (CanonicalVD->isStaticDataMember() &&
1608 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1609 Diag(Id.getLoc(), diag::err_omp_var_scope)
1610 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1612 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1613 Diag(VD->getLocation(),
1614 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1618 // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1619 // A threadprivate directive for namespace-scope variables must appear
1620 // outside any definition or declaration other than the namespace
1621 // definition itself.
1622 if (CanonicalVD->getDeclContext()->isNamespace() &&
1623 (!getCurLexicalContext()->isFileContext() ||
1624 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1625 Diag(Id.getLoc(), diag::err_omp_var_scope)
1626 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1628 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1629 Diag(VD->getLocation(),
1630 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1634 // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1635 // A threadprivate directive for static block-scope variables must appear
1636 // in the scope of the variable and not in a nested scope.
1637 if (CanonicalVD->isStaticLocal() && CurScope &&
1638 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1639 Diag(Id.getLoc(), diag::err_omp_var_scope)
1640 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1642 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1643 Diag(VD->getLocation(),
1644 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1649 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1650 // A threadprivate directive must lexically precede all references to any
1651 // of the variables in its list.
1652 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1653 Diag(Id.getLoc(), diag::err_omp_var_used)
1654 << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1658 QualType ExprType = VD->getType().getNonReferenceType();
1659 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1660 SourceLocation(), VD,
1661 /*RefersToEnclosingVariableOrCapture=*/false,
1662 Id.getLoc(), ExprType, VK_LValue);
1665 Sema::DeclGroupPtrTy
1666 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
1667 ArrayRef<Expr *> VarList) {
1668 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1669 CurContext->addDecl(D);
1670 return DeclGroupPtrTy::make(DeclGroupRef(D));
1676 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1680 bool VisitDeclRefExpr(const DeclRefExpr *E) {
1681 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1682 if (VD->hasLocalStorage()) {
1683 SemaRef.Diag(E->getLocStart(),
1684 diag::err_omp_local_var_in_threadprivate_init)
1685 << E->getSourceRange();
1686 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1687 << VD << VD->getSourceRange();
1693 bool VisitStmt(const Stmt *S) {
1694 for (auto Child : S->children()) {
1695 if (Child && Visit(Child))
1700 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1704 OMPThreadPrivateDecl *
1705 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
1706 SmallVector<Expr *, 8> Vars;
1707 for (auto &RefExpr : VarList) {
1708 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1709 VarDecl *VD = cast<VarDecl>(DE->getDecl());
1710 SourceLocation ILoc = DE->getExprLoc();
1712 // Mark variable as used.
1713 VD->setReferenced();
1714 VD->markUsed(Context);
1716 QualType QType = VD->getType();
1717 if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1718 // It will be analyzed later.
1723 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1724 // A threadprivate variable must not have an incomplete type.
1725 if (RequireCompleteType(ILoc, VD->getType(),
1726 diag::err_omp_threadprivate_incomplete_type)) {
1730 // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1731 // A threadprivate variable must not have a reference type.
1732 if (VD->getType()->isReferenceType()) {
1733 Diag(ILoc, diag::err_omp_ref_type_arg)
1734 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1736 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1737 Diag(VD->getLocation(),
1738 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1743 // Check if this is a TLS variable. If TLS is not being supported, produce
1744 // the corresponding diagnostic.
1745 if ((VD->getTLSKind() != VarDecl::TLS_None &&
1746 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1747 getLangOpts().OpenMPUseTLS &&
1748 getASTContext().getTargetInfo().isTLSSupported())) ||
1749 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1750 !VD->isLocalVarDecl())) {
1751 Diag(ILoc, diag::err_omp_var_thread_local)
1752 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1754 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1755 Diag(VD->getLocation(),
1756 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1761 // Check if initial value of threadprivate variable reference variable with
1762 // local storage (it is not supported by runtime).
1763 if (auto Init = VD->getAnyInitializer()) {
1764 LocalVarRefChecker Checker(*this);
1765 if (Checker.Visit(Init))
1769 Vars.push_back(RefExpr);
1770 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1771 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1772 Context, SourceRange(Loc, Loc)));
1773 if (auto *ML = Context.getASTMutationListener())
1774 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1776 OMPThreadPrivateDecl *D = nullptr;
1777 if (!Vars.empty()) {
1778 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1780 D->setAccess(AS_public);
1785 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1786 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1787 bool IsLoopIterVar = false) {
1789 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1790 << getOpenMPClauseName(DVar.CKind);
1794 PDSA_StaticMemberShared,
1795 PDSA_StaticLocalVarShared,
1796 PDSA_LoopIterVarPrivate,
1797 PDSA_LoopIterVarLinear,
1798 PDSA_LoopIterVarLastprivate,
1799 PDSA_ConstVarShared,
1800 PDSA_GlobalVarShared,
1801 PDSA_TaskVarFirstprivate,
1802 PDSA_LocalVarPrivate,
1804 } Reason = PDSA_Implicit;
1805 bool ReportHint = false;
1806 auto ReportLoc = D->getLocation();
1807 auto *VD = dyn_cast<VarDecl>(D);
1808 if (IsLoopIterVar) {
1809 if (DVar.CKind == OMPC_private)
1810 Reason = PDSA_LoopIterVarPrivate;
1811 else if (DVar.CKind == OMPC_lastprivate)
1812 Reason = PDSA_LoopIterVarLastprivate;
1814 Reason = PDSA_LoopIterVarLinear;
1815 } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1816 DVar.CKind == OMPC_firstprivate) {
1817 Reason = PDSA_TaskVarFirstprivate;
1818 ReportLoc = DVar.ImplicitDSALoc;
1819 } else if (VD && VD->isStaticLocal())
1820 Reason = PDSA_StaticLocalVarShared;
1821 else if (VD && VD->isStaticDataMember())
1822 Reason = PDSA_StaticMemberShared;
1823 else if (VD && VD->isFileVarDecl())
1824 Reason = PDSA_GlobalVarShared;
1825 else if (D->getType().isConstant(SemaRef.getASTContext()))
1826 Reason = PDSA_ConstVarShared;
1827 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1829 Reason = PDSA_LocalVarPrivate;
1831 if (Reason != PDSA_Implicit) {
1832 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1833 << Reason << ReportHint
1834 << getOpenMPDirectiveName(Stack->getCurrentDirective());
1835 } else if (DVar.ImplicitDSALoc.isValid()) {
1836 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1837 << getOpenMPClauseName(DVar.CKind);
1842 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1847 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1848 llvm::SmallVector<Expr *, 8> ImplicitMap;
1849 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1850 llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1853 void VisitDeclRefExpr(DeclRefExpr *E) {
1854 if (E->isTypeDependent() || E->isValueDependent() ||
1855 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1857 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1858 VD = VD->getCanonicalDecl();
1859 // Skip internally declared variables.
1860 if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1863 auto DVar = Stack->getTopDSA(VD, false);
1864 // Check if the variable has explicit DSA set and stop analysis if it so.
1865 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1868 // Skip internally declared static variables.
1869 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1872 auto ELoc = E->getExprLoc();
1873 auto DKind = Stack->getCurrentDirective();
1874 // The default(none) clause requires that each variable that is referenced
1875 // in the construct, and does not have a predetermined data-sharing
1876 // attribute, must have its data-sharing attribute explicitly determined
1877 // by being listed in a data-sharing attribute clause.
1878 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1879 isParallelOrTaskRegion(DKind) &&
1880 VarsWithInheritedDSA.count(VD) == 0) {
1881 VarsWithInheritedDSA[VD] = E;
1885 if (isOpenMPTargetExecutionDirective(DKind) &&
1886 !Stack->isLoopControlVariable(VD).first) {
1887 if (!Stack->checkMappableExprComponentListsForDecl(
1888 VD, /*CurrentRegionOnly=*/true,
1889 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1892 // Variable is used if it has been marked as an array, array
1893 // section or the variable iself.
1894 return StackComponents.size() == 1 ||
1896 std::next(StackComponents.rbegin()),
1897 StackComponents.rend(),
1898 [](const OMPClauseMappableExprCommon::
1899 MappableComponent &MC) {
1900 return MC.getAssociatedDeclaration() ==
1902 (isa<OMPArraySectionExpr>(
1903 MC.getAssociatedExpression()) ||
1904 isa<ArraySubscriptExpr>(
1905 MC.getAssociatedExpression()));
1908 bool IsFirstprivate = false;
1909 // By default lambdas are captured as firstprivates.
1910 if (const auto *RD =
1911 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1912 IsFirstprivate = RD->isLambda();
1915 (VD->getType().getNonReferenceType()->isScalarType() &&
1916 Stack->getDefaultDMA() != DMA_tofrom_scalar);
1918 ImplicitFirstprivate.emplace_back(E);
1920 ImplicitMap.emplace_back(E);
1925 // OpenMP [2.9.3.6, Restrictions, p.2]
1926 // A list item that appears in a reduction clause of the innermost
1927 // enclosing worksharing or parallel construct may not be accessed in an
1929 DVar = Stack->hasInnermostDSA(
1930 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1931 [](OpenMPDirectiveKind K) -> bool {
1932 return isOpenMPParallelDirective(K) ||
1933 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1935 /*FromParent=*/true);
1936 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1938 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1939 ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1943 // Define implicit data-sharing attributes for task.
1944 DVar = Stack->getImplicitDSA(VD, false);
1945 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1946 !Stack->isLoopControlVariable(VD).first)
1947 ImplicitFirstprivate.push_back(E);
1950 void VisitMemberExpr(MemberExpr *E) {
1951 if (E->isTypeDependent() || E->isValueDependent() ||
1952 E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
1954 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1955 OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1956 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1959 auto DVar = Stack->getTopDSA(FD, false);
1960 // Check if the variable has explicit DSA set and stop analysis if it
1962 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1965 if (isOpenMPTargetExecutionDirective(DKind) &&
1966 !Stack->isLoopControlVariable(FD).first &&
1967 !Stack->checkMappableExprComponentListsForDecl(
1968 FD, /*CurrentRegionOnly=*/true,
1969 [](OMPClauseMappableExprCommon::MappableExprComponentListRef
1972 return isa<CXXThisExpr>(
1974 StackComponents.back().getAssociatedExpression())
1978 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1979 // A bit-field cannot appear in a map clause.
1981 if (FD->isBitField())
1983 ImplicitMap.emplace_back(E);
1987 auto ELoc = E->getExprLoc();
1988 // OpenMP [2.9.3.6, Restrictions, p.2]
1989 // A list item that appears in a reduction clause of the innermost
1990 // enclosing worksharing or parallel construct may not be accessed in
1991 // an explicit task.
1992 DVar = Stack->hasInnermostDSA(
1993 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1994 [](OpenMPDirectiveKind K) -> bool {
1995 return isOpenMPParallelDirective(K) ||
1996 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
1998 /*FromParent=*/true);
1999 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2001 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2002 ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2006 // Define implicit data-sharing attributes for task.
2007 DVar = Stack->getImplicitDSA(FD, false);
2008 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2009 !Stack->isLoopControlVariable(FD).first)
2010 ImplicitFirstprivate.push_back(E);
2013 if (isOpenMPTargetExecutionDirective(DKind)) {
2014 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
2015 if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2016 /*NoDiagnose=*/true))
2018 auto *VD = cast<ValueDecl>(
2019 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2020 if (!Stack->checkMappableExprComponentListsForDecl(
2021 VD, /*CurrentRegionOnly=*/true,
2023 OMPClauseMappableExprCommon::MappableExprComponentListRef
2026 auto CCI = CurComponents.rbegin();
2027 auto CCE = CurComponents.rend();
2028 for (const auto &SC : llvm::reverse(StackComponents)) {
2029 // Do both expressions have the same kind?
2030 if (CCI->getAssociatedExpression()->getStmtClass() !=
2031 SC.getAssociatedExpression()->getStmtClass())
2032 if (!(isa<OMPArraySectionExpr>(
2033 SC.getAssociatedExpression()) &&
2034 isa<ArraySubscriptExpr>(
2035 CCI->getAssociatedExpression())))
2038 Decl *CCD = CCI->getAssociatedDeclaration();
2039 Decl *SCD = SC.getAssociatedDeclaration();
2040 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2041 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2044 std::advance(CCI, 1);
2050 Visit(E->getBase());
2053 Visit(E->getBase());
2055 void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2056 for (auto *C : S->clauses()) {
2057 // Skip analysis of arguments of implicitly defined firstprivate clause
2058 // for task|target directives.
2059 // Skip analysis of arguments of implicitly defined map clause for target
2061 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2063 for (auto *CC : C->children()) {
2070 void VisitStmt(Stmt *S) {
2071 for (auto *C : S->children()) {
2072 if (C && !isa<OMPExecutableDirective>(C))
2077 bool isErrorFound() { return ErrorFound; }
2078 ArrayRef<Expr *> getImplicitFirstprivate() const {
2079 return ImplicitFirstprivate;
2081 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2082 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2083 return VarsWithInheritedDSA;
2086 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2087 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2091 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
2094 case OMPD_parallel_for:
2095 case OMPD_parallel_for_simd:
2096 case OMPD_parallel_sections:
2098 case OMPD_teams_distribute:
2099 case OMPD_teams_distribute_simd: {
2100 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2101 QualType KmpInt32PtrTy =
2102 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2103 Sema::CapturedParamNameType Params[] = {
2104 std::make_pair(".global_tid.", KmpInt32PtrTy),
2105 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2106 std::make_pair(StringRef(), QualType()) // __context with shared vars
2108 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2112 case OMPD_target_teams:
2113 case OMPD_target_parallel:
2114 case OMPD_target_parallel_for:
2115 case OMPD_target_parallel_for_simd:
2116 case OMPD_target_teams_distribute:
2117 case OMPD_target_teams_distribute_simd: {
2118 Sema::CapturedParamNameType ParamsTarget[] = {
2119 std::make_pair(StringRef(), QualType()) // __context with shared vars
2121 // Start a captured region for 'target' with no implicit parameters.
2122 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2124 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2125 QualType KmpInt32PtrTy =
2126 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2127 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2128 std::make_pair(".global_tid.", KmpInt32PtrTy),
2129 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2130 std::make_pair(StringRef(), QualType()) // __context with shared vars
2132 // Start a captured region for 'teams' or 'parallel'. Both regions have
2133 // the same implicit parameters.
2134 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2135 ParamsTeamsOrParallel);
2146 case OMPD_taskgroup:
2147 case OMPD_distribute:
2148 case OMPD_distribute_simd:
2151 case OMPD_target_data:
2153 case OMPD_target_simd: {
2154 Sema::CapturedParamNameType Params[] = {
2155 std::make_pair(StringRef(), QualType()) // __context with shared vars
2157 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2162 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2163 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2164 FunctionProtoType::ExtProtoInfo EPI;
2165 EPI.Variadic = true;
2166 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2167 Sema::CapturedParamNameType Params[] = {
2168 std::make_pair(".global_tid.", KmpInt32Ty),
2169 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2170 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2171 std::make_pair(".copy_fn.",
2172 Context.getPointerType(CopyFnType).withConst()),
2173 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2174 std::make_pair(StringRef(), QualType()) // __context with shared vars
2176 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2178 // Mark this captured region as inlined, because we don't use outlined
2179 // function directly.
2180 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2181 AlwaysInlineAttr::CreateImplicit(
2182 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2186 case OMPD_taskloop_simd: {
2187 QualType KmpInt32Ty =
2188 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2189 QualType KmpUInt64Ty =
2190 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2191 QualType KmpInt64Ty =
2192 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2193 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2194 FunctionProtoType::ExtProtoInfo EPI;
2195 EPI.Variadic = true;
2196 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2197 Sema::CapturedParamNameType Params[] = {
2198 std::make_pair(".global_tid.", KmpInt32Ty),
2199 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2200 std::make_pair(".privates.",
2201 Context.VoidPtrTy.withConst().withRestrict()),
2204 Context.getPointerType(CopyFnType).withConst().withRestrict()),
2205 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2206 std::make_pair(".lb.", KmpUInt64Ty),
2207 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2208 std::make_pair(".liter.", KmpInt32Ty),
2209 std::make_pair(".reductions.",
2210 Context.VoidPtrTy.withConst().withRestrict()),
2211 std::make_pair(StringRef(), QualType()) // __context with shared vars
2213 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2215 // Mark this captured region as inlined, because we don't use outlined
2216 // function directly.
2217 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2218 AlwaysInlineAttr::CreateImplicit(
2219 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2222 case OMPD_distribute_parallel_for_simd:
2223 case OMPD_distribute_parallel_for:
2224 case OMPD_target_teams_distribute_parallel_for:
2225 case OMPD_target_teams_distribute_parallel_for_simd: {
2226 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2227 QualType KmpInt32PtrTy =
2228 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2229 Sema::CapturedParamNameType Params[] = {
2230 std::make_pair(".global_tid.", KmpInt32PtrTy),
2231 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2232 std::make_pair(".previous.lb.", Context.getSizeType()),
2233 std::make_pair(".previous.ub.", Context.getSizeType()),
2234 std::make_pair(StringRef(), QualType()) // __context with shared vars
2236 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2240 case OMPD_teams_distribute_parallel_for:
2241 case OMPD_teams_distribute_parallel_for_simd: {
2242 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2243 QualType KmpInt32PtrTy =
2244 Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2246 Sema::CapturedParamNameType ParamsTeams[] = {
2247 std::make_pair(".global_tid.", KmpInt32PtrTy),
2248 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2249 std::make_pair(StringRef(), QualType()) // __context with shared vars
2251 // Start a captured region for 'target' with no implicit parameters.
2252 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2255 Sema::CapturedParamNameType ParamsParallel[] = {
2256 std::make_pair(".global_tid.", KmpInt32PtrTy),
2257 std::make_pair(".bound_tid.", KmpInt32PtrTy),
2258 std::make_pair(".previous.lb.", Context.getSizeType()),
2259 std::make_pair(".previous.ub.", Context.getSizeType()),
2260 std::make_pair(StringRef(), QualType()) // __context with shared vars
2262 // Start a captured region for 'teams' or 'parallel'. Both regions have
2263 // the same implicit parameters.
2264 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2268 case OMPD_target_update:
2269 case OMPD_target_enter_data:
2270 case OMPD_target_exit_data: {
2271 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2272 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2273 FunctionProtoType::ExtProtoInfo EPI;
2274 EPI.Variadic = true;
2275 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2276 Sema::CapturedParamNameType Params[] = {
2277 std::make_pair(".global_tid.", KmpInt32Ty),
2278 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2279 std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2280 std::make_pair(".copy_fn.",
2281 Context.getPointerType(CopyFnType).withConst()),
2282 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2283 std::make_pair(StringRef(), QualType()) // __context with shared vars
2285 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2287 // Mark this captured region as inlined, because we don't use outlined
2288 // function directly.
2289 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2290 AlwaysInlineAttr::CreateImplicit(
2291 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2294 case OMPD_threadprivate:
2295 case OMPD_taskyield:
2298 case OMPD_cancellation_point:
2301 case OMPD_declare_reduction:
2302 case OMPD_declare_simd:
2303 case OMPD_declare_target:
2304 case OMPD_end_declare_target:
2305 llvm_unreachable("OpenMP Directive is not allowed");
2307 llvm_unreachable("Unknown OpenMP directive");
2311 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
2312 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2313 getOpenMPCaptureRegions(CaptureRegions, DKind);
2314 return CaptureRegions.size();
2317 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2318 Expr *CaptureExpr, bool WithInit,
2319 bool AsExpression) {
2320 assert(CaptureExpr);
2321 ASTContext &C = S.getASTContext();
2322 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2323 QualType Ty = Init->getType();
2324 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2325 if (S.getLangOpts().CPlusPlus)
2326 Ty = C.getLValueReferenceType(Ty);
2328 Ty = C.getPointerType(Ty);
2330 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2331 if (!Res.isUsable())
2337 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2338 CaptureExpr->getLocStart());
2340 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2341 S.CurContext->addHiddenDecl(CED);
2342 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2346 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2348 OMPCapturedExprDecl *CD;
2349 if (auto *VD = S.IsOpenMPCapturedDecl(D))
2350 CD = cast<OMPCapturedExprDecl>(VD);
2352 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2353 /*AsExpression=*/false);
2354 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2355 CaptureExpr->getExprLoc());
2358 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2361 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
2362 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
2363 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2364 CaptureExpr->getExprLoc());
2366 ExprResult Res = Ref;
2367 if (!S.getLangOpts().CPlusPlus &&
2368 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2369 Ref->getType()->isPointerType())
2370 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2371 if (!Res.isUsable())
2373 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
2377 // OpenMP directives parsed in this section are represented as a
2378 // CapturedStatement with an associated statement. If a syntax error
2379 // is detected during the parsing of the associated statement, the
2380 // compiler must abort processing and close the CapturedStatement.
2382 // Combined directives such as 'target parallel' have more than one
2383 // nested CapturedStatements. This RAII ensures that we unwind out
2384 // of all the nested CapturedStatements when an error is found.
2385 class CaptureRegionUnwinderRAII {
2389 OpenMPDirectiveKind DKind;
2392 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2393 OpenMPDirectiveKind DKind)
2394 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2395 ~CaptureRegionUnwinderRAII() {
2397 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2398 while (--ThisCaptureLevel >= 0)
2399 S.ActOnCapturedRegionError();
2405 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
2406 ArrayRef<OMPClause *> Clauses) {
2407 bool ErrorFound = false;
2408 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2409 *this, ErrorFound, DSAStack->getCurrentDirective());
2410 if (!S.isUsable()) {
2415 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2416 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2417 OMPOrderedClause *OC = nullptr;
2418 OMPScheduleClause *SC = nullptr;
2419 SmallVector<OMPLinearClause *, 4> LCs;
2420 SmallVector<OMPClauseWithPreInit *, 8> PICs;
2421 // This is required for proper codegen.
2422 for (auto *Clause : Clauses) {
2423 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2424 Clause->getClauseKind() == OMPC_in_reduction) {
2425 // Capture taskgroup task_reduction descriptors inside the tasking regions
2426 // with the corresponding in_reduction items.
2427 auto *IRC = cast<OMPInReductionClause>(Clause);
2428 for (auto *E : IRC->taskgroup_descriptors())
2430 MarkDeclarationsReferencedInExpr(E);
2432 if (isOpenMPPrivate(Clause->getClauseKind()) ||
2433 Clause->getClauseKind() == OMPC_copyprivate ||
2434 (getLangOpts().OpenMPUseTLS &&
2435 getASTContext().getTargetInfo().isTLSSupported() &&
2436 Clause->getClauseKind() == OMPC_copyin)) {
2437 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2438 // Mark all variables in private list clauses as used in inner region.
2439 for (auto *VarRef : Clause->children()) {
2440 if (auto *E = cast_or_null<Expr>(VarRef)) {
2441 MarkDeclarationsReferencedInExpr(E);
2444 DSAStack->setForceVarCapturing(/*V=*/false);
2445 } else if (CaptureRegions.size() > 1 ||
2446 CaptureRegions.back() != OMPD_unknown) {
2447 if (auto *C = OMPClauseWithPreInit::get(Clause))
2449 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2450 if (auto *E = C->getPostUpdateExpr())
2451 MarkDeclarationsReferencedInExpr(E);
2454 if (Clause->getClauseKind() == OMPC_schedule)
2455 SC = cast<OMPScheduleClause>(Clause);
2456 else if (Clause->getClauseKind() == OMPC_ordered)
2457 OC = cast<OMPOrderedClause>(Clause);
2458 else if (Clause->getClauseKind() == OMPC_linear)
2459 LCs.push_back(cast<OMPLinearClause>(Clause));
2461 // OpenMP, 2.7.1 Loop Construct, Restrictions
2462 // The nonmonotonic modifier cannot be specified if an ordered clause is
2465 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2466 SC->getSecondScheduleModifier() ==
2467 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2469 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2470 ? SC->getFirstScheduleModifierLoc()
2471 : SC->getSecondScheduleModifierLoc(),
2472 diag::err_omp_schedule_nonmonotonic_ordered)
2473 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2476 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2477 for (auto *C : LCs) {
2478 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2479 << SourceRange(OC->getLocStart(), OC->getLocEnd());
2483 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2484 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2485 OC->getNumForLoops()) {
2486 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2487 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2494 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2495 // Mark all variables in private list clauses as used in inner region.
2496 // Required for proper codegen of combined directives.
2497 // TODO: add processing for other clauses.
2498 if (ThisCaptureRegion != OMPD_unknown) {
2499 for (auto *C : PICs) {
2500 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2501 // Find the particular capture region for the clause if the
2502 // directive is a combined one with multiple capture regions.
2503 // If the directive is not a combined one, the capture region
2504 // associated with the clause is OMPD_unknown and is generated
2506 if (CaptureRegion == ThisCaptureRegion ||
2507 CaptureRegion == OMPD_unknown) {
2508 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2509 for (auto *D : DS->decls())
2510 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2515 SR = ActOnCapturedRegionEnd(SR.get());
2520 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2521 OpenMPDirectiveKind CancelRegion,
2522 SourceLocation StartLoc) {
2523 // CancelRegion is only needed for cancel and cancellation_point.
2524 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2527 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2528 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2531 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2532 << getOpenMPDirectiveName(CancelRegion);
2536 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2537 OpenMPDirectiveKind CurrentRegion,
2538 const DeclarationNameInfo &CurrentName,
2539 OpenMPDirectiveKind CancelRegion,
2540 SourceLocation StartLoc) {
2541 if (Stack->getCurScope()) {
2542 auto ParentRegion = Stack->getParentDirective();
2543 auto OffendingRegion = ParentRegion;
2544 bool NestingProhibited = false;
2545 bool CloseNesting = true;
2546 bool OrphanSeen = false;
2549 ShouldBeInParallelRegion,
2550 ShouldBeInOrderedRegion,
2551 ShouldBeInTargetRegion,
2552 ShouldBeInTeamsRegion
2553 } Recommend = NoRecommend;
2554 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2555 // OpenMP [2.16, Nesting of Regions]
2556 // OpenMP constructs may not be nested inside a simd region.
2557 // OpenMP [2.8.1,simd Construct, Restrictions]
2558 // An ordered construct with the simd clause is the only OpenMP
2559 // construct that can appear in the simd region.
2560 // Allowing a SIMD construct nested in another SIMD construct is an
2561 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2563 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2564 ? diag::err_omp_prohibited_region_simd
2565 : diag::warn_omp_nesting_simd);
2566 return CurrentRegion != OMPD_simd;
2568 if (ParentRegion == OMPD_atomic) {
2569 // OpenMP [2.16, Nesting of Regions]
2570 // OpenMP constructs may not be nested inside an atomic region.
2571 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2574 if (CurrentRegion == OMPD_section) {
2575 // OpenMP [2.7.2, sections Construct, Restrictions]
2576 // Orphaned section directives are prohibited. That is, the section
2577 // directives must appear within the sections construct and must not be
2578 // encountered elsewhere in the sections region.
2579 if (ParentRegion != OMPD_sections &&
2580 ParentRegion != OMPD_parallel_sections) {
2581 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2582 << (ParentRegion != OMPD_unknown)
2583 << getOpenMPDirectiveName(ParentRegion);
2588 // Allow some constructs (except teams) to be orphaned (they could be
2589 // used in functions, called from OpenMP regions with the required
2591 if (ParentRegion == OMPD_unknown &&
2592 !isOpenMPNestingTeamsDirective(CurrentRegion))
2594 if (CurrentRegion == OMPD_cancellation_point ||
2595 CurrentRegion == OMPD_cancel) {
2596 // OpenMP [2.16, Nesting of Regions]
2597 // A cancellation point construct for which construct-type-clause is
2598 // taskgroup must be nested inside a task construct. A cancellation
2599 // point construct for which construct-type-clause is not taskgroup must
2600 // be closely nested inside an OpenMP construct that matches the type
2601 // specified in construct-type-clause.
2602 // A cancel construct for which construct-type-clause is taskgroup must be
2603 // nested inside a task construct. A cancel construct for which
2604 // construct-type-clause is not taskgroup must be closely nested inside an
2605 // OpenMP construct that matches the type specified in
2606 // construct-type-clause.
2608 !((CancelRegion == OMPD_parallel &&
2609 (ParentRegion == OMPD_parallel ||
2610 ParentRegion == OMPD_target_parallel)) ||
2611 (CancelRegion == OMPD_for &&
2612 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2613 ParentRegion == OMPD_target_parallel_for ||
2614 ParentRegion == OMPD_distribute_parallel_for ||
2615 ParentRegion == OMPD_teams_distribute_parallel_for ||
2616 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2617 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2618 (CancelRegion == OMPD_sections &&
2619 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2620 ParentRegion == OMPD_parallel_sections)));
2621 } else if (CurrentRegion == OMPD_master) {
2622 // OpenMP [2.16, Nesting of Regions]
2623 // A master region may not be closely nested inside a worksharing,
2624 // atomic, or explicit task region.
2625 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2626 isOpenMPTaskingDirective(ParentRegion);
2627 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2628 // OpenMP [2.16, Nesting of Regions]
2629 // A critical region may not be nested (closely or otherwise) inside a
2630 // critical region with the same name. Note that this restriction is not
2631 // sufficient to prevent deadlock.
2632 SourceLocation PreviousCriticalLoc;
2633 bool DeadLock = Stack->hasDirective(
2634 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2635 const DeclarationNameInfo &DNI,
2636 SourceLocation Loc) -> bool {
2637 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2638 PreviousCriticalLoc = Loc;
2643 false /* skip top directive */);
2645 SemaRef.Diag(StartLoc,
2646 diag::err_omp_prohibited_region_critical_same_name)
2647 << CurrentName.getName();
2648 if (PreviousCriticalLoc.isValid())
2649 SemaRef.Diag(PreviousCriticalLoc,
2650 diag::note_omp_previous_critical_region);
2653 } else if (CurrentRegion == OMPD_barrier) {
2654 // OpenMP [2.16, Nesting of Regions]
2655 // A barrier region may not be closely nested inside a worksharing,
2656 // explicit task, critical, ordered, atomic, or master region.
2657 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2658 isOpenMPTaskingDirective(ParentRegion) ||
2659 ParentRegion == OMPD_master ||
2660 ParentRegion == OMPD_critical ||
2661 ParentRegion == OMPD_ordered;
2662 } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2663 !isOpenMPParallelDirective(CurrentRegion) &&
2664 !isOpenMPTeamsDirective(CurrentRegion)) {
2665 // OpenMP [2.16, Nesting of Regions]
2666 // A worksharing region may not be closely nested inside a worksharing,
2667 // explicit task, critical, ordered, atomic, or master region.
2668 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2669 isOpenMPTaskingDirective(ParentRegion) ||
2670 ParentRegion == OMPD_master ||
2671 ParentRegion == OMPD_critical ||
2672 ParentRegion == OMPD_ordered;
2673 Recommend = ShouldBeInParallelRegion;
2674 } else if (CurrentRegion == OMPD_ordered) {
2675 // OpenMP [2.16, Nesting of Regions]
2676 // An ordered region may not be closely nested inside a critical,
2677 // atomic, or explicit task region.
2678 // An ordered region must be closely nested inside a loop region (or
2679 // parallel loop region) with an ordered clause.
2680 // OpenMP [2.8.1,simd Construct, Restrictions]
2681 // An ordered construct with the simd clause is the only OpenMP construct
2682 // that can appear in the simd region.
2683 NestingProhibited = ParentRegion == OMPD_critical ||
2684 isOpenMPTaskingDirective(ParentRegion) ||
2685 !(isOpenMPSimdDirective(ParentRegion) ||
2686 Stack->isParentOrderedRegion());
2687 Recommend = ShouldBeInOrderedRegion;
2688 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2689 // OpenMP [2.16, Nesting of Regions]
2690 // If specified, a teams construct must be contained within a target
2692 NestingProhibited = ParentRegion != OMPD_target;
2693 OrphanSeen = ParentRegion == OMPD_unknown;
2694 Recommend = ShouldBeInTargetRegion;
2696 if (!NestingProhibited &&
2697 !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2698 !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2699 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2700 // OpenMP [2.16, Nesting of Regions]
2701 // distribute, parallel, parallel sections, parallel workshare, and the
2702 // parallel loop and parallel loop SIMD constructs are the only OpenMP
2703 // constructs that can be closely nested in the teams region.
2704 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2705 !isOpenMPDistributeDirective(CurrentRegion);
2706 Recommend = ShouldBeInParallelRegion;
2708 if (!NestingProhibited &&
2709 isOpenMPNestingDistributeDirective(CurrentRegion)) {
2710 // OpenMP 4.5 [2.17 Nesting of Regions]
2711 // The region associated with the distribute construct must be strictly
2712 // nested inside a teams region
2714 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2715 Recommend = ShouldBeInTeamsRegion;
2717 if (!NestingProhibited &&
2718 (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2719 isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2720 // OpenMP 4.5 [2.17 Nesting of Regions]
2721 // If a target, target update, target data, target enter data, or
2722 // target exit data construct is encountered during execution of a
2723 // target region, the behavior is unspecified.
2724 NestingProhibited = Stack->hasDirective(
2725 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2726 SourceLocation) -> bool {
2727 if (isOpenMPTargetExecutionDirective(K)) {
2728 OffendingRegion = K;
2733 false /* don't skip top directive */);
2734 CloseNesting = false;
2736 if (NestingProhibited) {
2738 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2739 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2741 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2742 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2743 << Recommend << getOpenMPDirectiveName(CurrentRegion);
2751 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
2752 ArrayRef<OMPClause *> Clauses,
2753 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2754 bool ErrorFound = false;
2755 unsigned NamedModifiersNumber = 0;
2756 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers(
2758 SmallVector<SourceLocation, 4> NameModifierLoc;
2759 for (const auto *C : Clauses) {
2760 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2761 // At most one if clause without a directive-name-modifier can appear on
2763 OpenMPDirectiveKind CurNM = IC->getNameModifier();
2764 if (FoundNameModifiers[CurNM]) {
2765 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2766 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2767 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2769 } else if (CurNM != OMPD_unknown) {
2770 NameModifierLoc.push_back(IC->getNameModifierLoc());
2771 ++NamedModifiersNumber;
2773 FoundNameModifiers[CurNM] = IC;
2774 if (CurNM == OMPD_unknown)
2776 // Check if the specified name modifier is allowed for the current
2778 // At most one if clause with the particular directive-name-modifier can
2779 // appear on the directive.
2780 bool MatchFound = false;
2781 for (auto NM : AllowedNameModifiers) {
2788 S.Diag(IC->getNameModifierLoc(),
2789 diag::err_omp_wrong_if_directive_name_modifier)
2790 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
2795 // If any if clause on the directive includes a directive-name-modifier then
2796 // all if clauses on the directive must include a directive-name-modifier.
2797 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2798 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2799 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2800 diag::err_omp_no_more_if_clause);
2803 std::string Sep(", ");
2804 unsigned AllowedCnt = 0;
2805 unsigned TotalAllowedNum =
2806 AllowedNameModifiers.size() - NamedModifiersNumber;
2807 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2809 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2810 if (!FoundNameModifiers[NM]) {
2812 Values += getOpenMPDirectiveName(NM);
2814 if (AllowedCnt + 2 == TotalAllowedNum)
2816 else if (AllowedCnt + 1 != TotalAllowedNum)
2821 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2822 diag::err_omp_unnamed_if_clause)
2823 << (TotalAllowedNum > 1) << Values;
2825 for (auto Loc : NameModifierLoc) {
2826 S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2833 StmtResult Sema::ActOnOpenMPExecutableDirective(
2834 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
2835 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2836 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2837 StmtResult Res = StmtError();
2838 // First check CancelRegion which is then used in checkNestingOfRegions.
2839 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2840 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2844 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2845 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2846 bool ErrorFound = false;
2847 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2848 if (AStmt && !CurContext->isDependentContext()) {
2849 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2851 // Check default data sharing attributes for referenced variables.
2852 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2853 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2855 while (--ThisCaptureLevel >= 0)
2856 S = cast<CapturedStmt>(S)->getCapturedStmt();
2857 DSAChecker.Visit(S);
2858 if (DSAChecker.isErrorFound())
2860 // Generate list of implicitly defined firstprivate variables.
2861 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2863 SmallVector<Expr *, 4> ImplicitFirstprivates(
2864 DSAChecker.getImplicitFirstprivate().begin(),
2865 DSAChecker.getImplicitFirstprivate().end());
2866 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2867 DSAChecker.getImplicitMap().end());
2868 // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2869 for (auto *C : Clauses) {
2870 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2871 for (auto *E : IRC->taskgroup_descriptors())
2873 ImplicitFirstprivates.emplace_back(E);
2876 if (!ImplicitFirstprivates.empty()) {
2877 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2878 ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2879 SourceLocation())) {
2880 ClausesWithImplicit.push_back(Implicit);
2881 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2882 ImplicitFirstprivates.size();
2886 if (!ImplicitMaps.empty()) {
2887 if (OMPClause *Implicit = ActOnOpenMPMapClause(
2888 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2889 SourceLocation(), SourceLocation(), ImplicitMaps,
2890 SourceLocation(), SourceLocation(), SourceLocation())) {
2891 ClausesWithImplicit.emplace_back(Implicit);
2893 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2899 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2902 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2904 AllowedNameModifiers.push_back(OMPD_parallel);
2907 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2908 VarsWithInheritedDSA);
2911 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2912 VarsWithInheritedDSA);
2915 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2916 EndLoc, VarsWithInheritedDSA);
2919 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2923 assert(ClausesWithImplicit.empty() &&
2924 "No clauses are allowed for 'omp section' directive");
2925 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2928 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2932 assert(ClausesWithImplicit.empty() &&
2933 "No clauses are allowed for 'omp master' directive");
2934 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2937 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2940 case OMPD_parallel_for:
2941 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2942 EndLoc, VarsWithInheritedDSA);
2943 AllowedNameModifiers.push_back(OMPD_parallel);
2945 case OMPD_parallel_for_simd:
2946 Res = ActOnOpenMPParallelForSimdDirective(
2947 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2948 AllowedNameModifiers.push_back(OMPD_parallel);
2950 case OMPD_parallel_sections:
2951 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2953 AllowedNameModifiers.push_back(OMPD_parallel);
2957 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2958 AllowedNameModifiers.push_back(OMPD_task);
2960 case OMPD_taskyield:
2961 assert(ClausesWithImplicit.empty() &&
2962 "No clauses are allowed for 'omp taskyield' directive");
2963 assert(AStmt == nullptr &&
2964 "No associated statement allowed for 'omp taskyield' directive");
2965 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2968 assert(ClausesWithImplicit.empty() &&
2969 "No clauses are allowed for 'omp barrier' directive");
2970 assert(AStmt == nullptr &&
2971 "No associated statement allowed for 'omp barrier' directive");
2972 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2975 assert(ClausesWithImplicit.empty() &&
2976 "No clauses are allowed for 'omp taskwait' directive");
2977 assert(AStmt == nullptr &&
2978 "No associated statement allowed for 'omp taskwait' directive");
2979 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2981 case OMPD_taskgroup:
2982 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2986 assert(AStmt == nullptr &&
2987 "No associated statement allowed for 'omp flush' directive");
2988 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2991 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
2995 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3000 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3003 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3005 AllowedNameModifiers.push_back(OMPD_target);
3007 case OMPD_target_parallel:
3008 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3010 AllowedNameModifiers.push_back(OMPD_target);
3011 AllowedNameModifiers.push_back(OMPD_parallel);
3013 case OMPD_target_parallel_for:
3014 Res = ActOnOpenMPTargetParallelForDirective(
3015 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3016 AllowedNameModifiers.push_back(OMPD_target);
3017 AllowedNameModifiers.push_back(OMPD_parallel);
3019 case OMPD_cancellation_point:
3020 assert(ClausesWithImplicit.empty() &&
3021 "No clauses are allowed for 'omp cancellation point' directive");
3022 assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3023 "cancellation point' directive");
3024 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3027 assert(AStmt == nullptr &&
3028 "No associated statement allowed for 'omp cancel' directive");
3029 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3031 AllowedNameModifiers.push_back(OMPD_cancel);
3033 case OMPD_target_data:
3034 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3036 AllowedNameModifiers.push_back(OMPD_target_data);
3038 case OMPD_target_enter_data:
3039 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3041 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3043 case OMPD_target_exit_data:
3044 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3046 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3049 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3050 EndLoc, VarsWithInheritedDSA);
3051 AllowedNameModifiers.push_back(OMPD_taskloop);
3053 case OMPD_taskloop_simd:
3054 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3055 EndLoc, VarsWithInheritedDSA);
3056 AllowedNameModifiers.push_back(OMPD_taskloop);
3058 case OMPD_distribute:
3059 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3060 EndLoc, VarsWithInheritedDSA);
3062 case OMPD_target_update:
3063 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3065 AllowedNameModifiers.push_back(OMPD_target_update);
3067 case OMPD_distribute_parallel_for:
3068 Res = ActOnOpenMPDistributeParallelForDirective(
3069 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3070 AllowedNameModifiers.push_back(OMPD_parallel);
3072 case OMPD_distribute_parallel_for_simd:
3073 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3074 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3075 AllowedNameModifiers.push_back(OMPD_parallel);
3077 case OMPD_distribute_simd:
3078 Res = ActOnOpenMPDistributeSimdDirective(
3079 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3081 case OMPD_target_parallel_for_simd:
3082 Res = ActOnOpenMPTargetParallelForSimdDirective(
3083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084 AllowedNameModifiers.push_back(OMPD_target);
3085 AllowedNameModifiers.push_back(OMPD_parallel);
3087 case OMPD_target_simd:
3088 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3089 EndLoc, VarsWithInheritedDSA);
3090 AllowedNameModifiers.push_back(OMPD_target);
3092 case OMPD_teams_distribute:
3093 Res = ActOnOpenMPTeamsDistributeDirective(
3094 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3096 case OMPD_teams_distribute_simd:
3097 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3098 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3100 case OMPD_teams_distribute_parallel_for_simd:
3101 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3102 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3103 AllowedNameModifiers.push_back(OMPD_parallel);
3105 case OMPD_teams_distribute_parallel_for:
3106 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3107 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3108 AllowedNameModifiers.push_back(OMPD_parallel);
3110 case OMPD_target_teams:
3111 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3113 AllowedNameModifiers.push_back(OMPD_target);
3115 case OMPD_target_teams_distribute:
3116 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3117 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3118 AllowedNameModifiers.push_back(OMPD_target);
3120 case OMPD_target_teams_distribute_parallel_for:
3121 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3122 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3123 AllowedNameModifiers.push_back(OMPD_target);
3124 AllowedNameModifiers.push_back(OMPD_parallel);
3126 case OMPD_target_teams_distribute_parallel_for_simd:
3127 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3128 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3129 AllowedNameModifiers.push_back(OMPD_target);
3130 AllowedNameModifiers.push_back(OMPD_parallel);
3132 case OMPD_target_teams_distribute_simd:
3133 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3134 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3135 AllowedNameModifiers.push_back(OMPD_target);
3137 case OMPD_declare_target:
3138 case OMPD_end_declare_target:
3139 case OMPD_threadprivate:
3140 case OMPD_declare_reduction:
3141 case OMPD_declare_simd:
3142 llvm_unreachable("OpenMP Directive is not allowed");
3144 llvm_unreachable("Unknown OpenMP directive");
3147 for (auto P : VarsWithInheritedDSA) {
3148 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3149 << P.first << P.second->getSourceRange();
3151 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3153 if (!AllowedNameModifiers.empty())
3154 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3162 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
3163 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3164 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3165 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3166 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3167 assert(Aligneds.size() == Alignments.size());
3168 assert(Linears.size() == LinModifiers.size());
3169 assert(Linears.size() == Steps.size());
3170 if (!DG || DG.get().isNull())
3171 return DeclGroupPtrTy();
3173 if (!DG.get().isSingleDecl()) {
3174 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3177 auto *ADecl = DG.get().getSingleDecl();
3178 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3179 ADecl = FTD->getTemplatedDecl();
3181 auto *FD = dyn_cast<FunctionDecl>(ADecl);
3183 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3184 return DeclGroupPtrTy();
3187 // OpenMP [2.8.2, declare simd construct, Description]
3188 // The parameter of the simdlen clause must be a constant positive integer
3192 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3193 // OpenMP [2.8.2, declare simd construct, Description]
3194 // The special this pointer can be used as if was one of the arguments to the
3195 // function in any of the linear, aligned, or uniform clauses.
3196 // The uniform clause declares one or more arguments to have an invariant
3197 // value for all concurrent invocations of the function in the execution of a
3198 // single SIMD loop.
3199 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3200 Expr *UniformedLinearThis = nullptr;
3201 for (auto *E : Uniforms) {
3202 E = E->IgnoreParenImpCasts();
3203 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3204 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3205 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3206 FD->getParamDecl(PVD->getFunctionScopeIndex())
3207 ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3208 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3211 if (isa<CXXThisExpr>(E)) {
3212 UniformedLinearThis = E;
3215 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3216 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3218 // OpenMP [2.8.2, declare simd construct, Description]
3219 // The aligned clause declares that the object to which each list item points
3220 // is aligned to the number of bytes expressed in the optional parameter of
3221 // the aligned clause.
3222 // The special this pointer can be used as if was one of the arguments to the
3223 // function in any of the linear, aligned, or uniform clauses.
3224 // The type of list items appearing in the aligned clause must be array,
3225 // pointer, reference to array, or reference to pointer.
3226 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3227 Expr *AlignedThis = nullptr;
3228 for (auto *E : Aligneds) {
3229 E = E->IgnoreParenImpCasts();
3230 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3231 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3232 auto *CanonPVD = PVD->getCanonicalDecl();
3233 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3234 FD->getParamDecl(PVD->getFunctionScopeIndex())
3235 ->getCanonicalDecl() == CanonPVD) {
3236 // OpenMP [2.8.1, simd construct, Restrictions]
3237 // A list-item cannot appear in more than one aligned clause.
3238 if (AlignedArgs.count(CanonPVD) > 0) {
3239 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3240 << 1 << E->getSourceRange();
3241 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3242 diag::note_omp_explicit_dsa)
3243 << getOpenMPClauseName(OMPC_aligned);
3246 AlignedArgs[CanonPVD] = E;
3247 QualType QTy = PVD->getType()
3248 .getNonReferenceType()
3249 .getUnqualifiedType()
3250 .getCanonicalType();
3251 const Type *Ty = QTy.getTypePtrOrNull();
3252 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3253 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3254 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3255 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3260 if (isa<CXXThisExpr>(E)) {
3262 Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3263 << 2 << E->getSourceRange();
3264 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3265 << getOpenMPClauseName(OMPC_aligned);
3270 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3271 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3273 // The optional parameter of the aligned clause, alignment, must be a constant
3274 // positive integer expression. If no optional parameter is specified,
3275 // implementation-defined default alignments for SIMD instructions on the
3276 // target platforms are assumed.
3277 SmallVector<Expr *, 4> NewAligns;
3278 for (auto *E : Alignments) {
3281 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3282 NewAligns.push_back(Align.get());
3284 // OpenMP [2.8.2, declare simd construct, Description]
3285 // The linear clause declares one or more list items to be private to a SIMD
3286 // lane and to have a linear relationship with respect to the iteration space
3288 // The special this pointer can be used as if was one of the arguments to the
3289 // function in any of the linear, aligned, or uniform clauses.
3290 // When a linear-step expression is specified in a linear clause it must be
3291 // either a constant integer expression or an integer-typed parameter that is
3292 // specified in a uniform clause on the directive.
3293 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3294 const bool IsUniformedThis = UniformedLinearThis != nullptr;
3295 auto MI = LinModifiers.begin();
3296 for (auto *E : Linears) {
3297 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3299 E = E->IgnoreParenImpCasts();
3300 if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3301 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3302 auto *CanonPVD = PVD->getCanonicalDecl();
3303 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3304 FD->getParamDecl(PVD->getFunctionScopeIndex())
3305 ->getCanonicalDecl() == CanonPVD) {
3306 // OpenMP [2.15.3.7, linear Clause, Restrictions]
3307 // A list-item cannot appear in more than one linear clause.
3308 if (LinearArgs.count(CanonPVD) > 0) {
3309 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3310 << getOpenMPClauseName(OMPC_linear)
3311 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3312 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3313 diag::note_omp_explicit_dsa)
3314 << getOpenMPClauseName(OMPC_linear);
3317 // Each argument can appear in at most one uniform or linear clause.
3318 if (UniformedArgs.count(CanonPVD) > 0) {
3319 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3320 << getOpenMPClauseName(OMPC_linear)
3321 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
3322 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3323 diag::note_omp_explicit_dsa)
3324 << getOpenMPClauseName(OMPC_uniform);
3327 LinearArgs[CanonPVD] = E;
3328 if (E->isValueDependent() || E->isTypeDependent() ||
3329 E->isInstantiationDependent() ||
3330 E->containsUnexpandedParameterPack())
3332 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3333 PVD->getOriginalType());
3337 if (isa<CXXThisExpr>(E)) {
3338 if (UniformedLinearThis) {
3339 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3340 << getOpenMPClauseName(OMPC_linear)
3341 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3342 << E->getSourceRange();
3343 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3344 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3348 UniformedLinearThis = E;
3349 if (E->isValueDependent() || E->isTypeDependent() ||
3350 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
3352 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3356 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3357 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3359 Expr *Step = nullptr;
3360 Expr *NewStep = nullptr;
3361 SmallVector<Expr *, 4> NewSteps;
3362 for (auto *E : Steps) {
3363 // Skip the same step expression, it was checked already.
3364 if (Step == E || !E) {
3365 NewSteps.push_back(E ? NewStep : nullptr);
3369 if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3370 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3371 auto *CanonPVD = PVD->getCanonicalDecl();
3372 if (UniformedArgs.count(CanonPVD) == 0) {
3373 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3374 << Step->getSourceRange();
3375 } else if (E->isValueDependent() || E->isTypeDependent() ||
3376 E->isInstantiationDependent() ||
3377 E->containsUnexpandedParameterPack() ||
3378 CanonPVD->getType()->hasIntegerRepresentation())
3379 NewSteps.push_back(Step);
3381 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3382 << Step->getSourceRange();
3387 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3388 !Step->isInstantiationDependent() &&
3389 !Step->containsUnexpandedParameterPack()) {
3390 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3393 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3395 NewSteps.push_back(NewStep);
3397 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3398 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3399 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3400 const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3401 const_cast<Expr **>(Linears.data()), Linears.size(),
3402 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3403 NewSteps.data(), NewSteps.size(), SR);
3404 ADecl->addAttr(NewAttr);
3405 return ConvertDeclToDeclGroup(ADecl);
3408 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
3410 SourceLocation StartLoc,
3411 SourceLocation EndLoc) {
3415 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3416 // 1.2.2 OpenMP Language Terminology
3417 // Structured block - An executable statement with a single entry at the
3418 // top and a single exit at the bottom.
3419 // The point of exit cannot be a branch out of the structured block.
3420 // longjmp() and throw() must not violate the entry/exit criteria.
3421 CS->getCapturedDecl()->setNothrow();
3423 getCurFunction()->setHasBranchProtectedScope();
3425 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3426 DSAStack->isCancelRegion());
3430 /// \brief Helper class for checking canonical form of the OpenMP loops and
3431 /// extracting iteration space of each loop in the loop nest, that will be used
3432 /// for IR generation.
3433 class OpenMPIterationSpaceChecker {
3434 /// \brief Reference to Sema.
3436 /// \brief A location for diagnostics (when there is no some better location).
3437 SourceLocation DefaultLoc;
3438 /// \brief A location for diagnostics (when increment is not compatible).
3439 SourceLocation ConditionLoc;
3440 /// \brief A source location for referring to loop init later.
3441 SourceRange InitSrcRange;
3442 /// \brief A source location for referring to condition later.
3443 SourceRange ConditionSrcRange;
3444 /// \brief A source location for referring to increment later.
3445 SourceRange IncrementSrcRange;
3446 /// \brief Loop variable.
3447 ValueDecl *LCDecl = nullptr;
3448 /// \brief Reference to loop variable.
3449 Expr *LCRef = nullptr;
3450 /// \brief Lower bound (initializer for the var).
3452 /// \brief Upper bound.
3454 /// \brief Loop step (increment).
3455 Expr *Step = nullptr;
3456 /// \brief This flag is true when condition is one of:
3461 bool TestIsLessOp = false;
3462 /// \brief This flag is true when condition is strict ( < or > ).
3463 bool TestIsStrictOp = false;
3464 /// \brief This flag is true when step is subtracted on each iteration.
3465 bool SubtractStep = false;
3468 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3469 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3470 /// \brief Check init-expr for canonical loop form and save loop counter
3471 /// variable - #Var and its initialization value - #LB.
3472 bool CheckInit(Stmt *S, bool EmitDiags = true);
3473 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3474 /// for less/greater and for strict/non-strict comparison.
3475 bool CheckCond(Expr *S);
3476 /// \brief Check incr-expr for canonical loop form and return true if it
3477 /// does not conform, otherwise save loop step (#Step).
3478 bool CheckInc(Expr *S);
3479 /// \brief Return the loop counter variable.
3480 ValueDecl *GetLoopDecl() const { return LCDecl; }
3481 /// \brief Return the reference expression to loop counter variable.
3482 Expr *GetLoopDeclRefExpr() const { return LCRef; }
3483 /// \brief Source range of the loop init.
3484 SourceRange GetInitSrcRange() const { return InitSrcRange; }
3485 /// \brief Source range of the loop condition.
3486 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3487 /// \brief Source range of the loop increment.
3488 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3489 /// \brief True if the step should be subtracted.
3490 bool ShouldSubtractStep() const { return SubtractStep; }
3491 /// \brief Build the expression to calculate the number of iterations.
3493 BuildNumIterations(Scope *S, const bool LimitedType,
3494 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3495 /// \brief Build the precondition expression for the loops.
3496 Expr *BuildPreCond(Scope *S, Expr *Cond,
3497 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3498 /// \brief Build reference expression to the counter be used for codegen.
3499 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3500 DSAStackTy &DSA) const;
3501 /// \brief Build reference expression to the private counter be used for
3503 Expr *BuildPrivateCounterVar() const;
3504 /// \brief Build initialization of the counter be used for codegen.
3505 Expr *BuildCounterInit() const;
3506 /// \brief Build step of the counter be used for codegen.
3507 Expr *BuildCounterStep() const;
3508 /// \brief Return true if any expression is dependent.
3509 bool Dependent() const;
3512 /// \brief Check the right-hand side of an assignment in the increment
3514 bool CheckIncRHS(Expr *RHS);
3515 /// \brief Helper to set loop counter variable and its initializer.
3516 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3517 /// \brief Helper to set upper bound.
3518 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3520 /// \brief Helper to set loop increment.
3521 bool SetStep(Expr *NewStep, bool Subtract);
3524 bool OpenMPIterationSpaceChecker::Dependent() const {
3526 assert(!LB && !UB && !Step);
3529 return LCDecl->getType()->isDependentType() ||
3530 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3531 (Step && Step->isValueDependent());
3534 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3537 // State consistency checking to ensure correct usage.
3538 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3539 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3540 if (!NewLCDecl || !NewLB)
3542 LCDecl = getCanonicalDecl(NewLCDecl);
3543 LCRef = NewLCRefExpr;
3544 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3545 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3546 if ((Ctor->isCopyOrMoveConstructor() ||
3547 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3548 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3549 NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3554 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3555 SourceRange SR, SourceLocation SL) {
3556 // State consistency checking to ensure correct usage.
3557 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3558 Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3562 TestIsLessOp = LessOp;
3563 TestIsStrictOp = StrictOp;
3564 ConditionSrcRange = SR;
3569 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3570 // State consistency checking to ensure correct usage.
3571 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3574 if (!NewStep->isValueDependent()) {
3575 // Check that the step is integer expression.
3576 SourceLocation StepLoc = NewStep->getLocStart();
3577 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
3578 StepLoc, getExprAsWritten(NewStep));
3579 if (Val.isInvalid())
3581 NewStep = Val.get();
3583 // OpenMP [2.6, Canonical Loop Form, Restrictions]
3584 // If test-expr is of form var relational-op b and relational-op is < or
3585 // <= then incr-expr must cause var to increase on each iteration of the
3586 // loop. If test-expr is of form var relational-op b and relational-op is
3587 // > or >= then incr-expr must cause var to decrease on each iteration of
3589 // If test-expr is of form b relational-op var and relational-op is < or
3590 // <= then incr-expr must cause var to decrease on each iteration of the
3591 // loop. If test-expr is of form b relational-op var and relational-op is
3592 // > or >= then incr-expr must cause var to increase on each iteration of
3594 llvm::APSInt Result;
3595 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3596 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3598 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3600 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3601 bool IsConstZero = IsConstant && !Result.getBoolValue();
3602 if (UB && (IsConstZero ||
3603 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3604 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3605 SemaRef.Diag(NewStep->getExprLoc(),
3606 diag::err_omp_loop_incr_not_compatible)
3607 << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3608 SemaRef.Diag(ConditionLoc,
3609 diag::note_omp_loop_cond_requres_compatible_incr)
3610 << TestIsLessOp << ConditionSrcRange;
3613 if (TestIsLessOp == Subtract) {
3615 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3617 Subtract = !Subtract;
3622 SubtractStep = Subtract;
3626 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3627 // Check init-expr for canonical loop form and save loop counter
3628 // variable - #Var and its initialization value - #LB.
3629 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3631 // integer-type var = lb
3632 // random-access-iterator-type var = lb
3633 // pointer-type var = lb
3637 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3641 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3642 if (!ExprTemp->cleanupsHaveSideEffects())
3643 S = ExprTemp->getSubExpr();
3645 InitSrcRange = S->getSourceRange();
3646 if (Expr *E = dyn_cast<Expr>(S))
3647 S = E->IgnoreParens();
3648 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3649 if (BO->getOpcode() == BO_Assign) {
3650 auto *LHS = BO->getLHS()->IgnoreParens();
3651 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3652 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3653 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3654 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3655 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3657 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3658 if (ME->isArrow() &&
3659 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3660 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3663 } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3664 if (DS->isSingleDecl()) {
3665 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3666 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3667 // Accept non-canonical init form here but emit ext. warning.
3668 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3669 SemaRef.Diag(S->getLocStart(),
3670 diag::ext_omp_loop_not_canonical_init)
3671 << S->getSourceRange();
3672 return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3676 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3677 if (CE->getOperator() == OO_Equal) {
3678 auto *LHS = CE->getArg(0);
3679 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3680 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3681 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3682 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3683 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3685 if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3686 if (ME->isArrow() &&
3687 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3688 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3693 if (Dependent() || SemaRef.CurContext->isDependentContext())
3696 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3697 << S->getSourceRange();
3702 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3703 /// variable (which may be the loop variable) if possible.
3704 static const ValueDecl *GetInitLCDecl(Expr *E) {
3707 E = getExprAsWritten(E);
3708 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3709 if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3710 if ((Ctor->isCopyOrMoveConstructor() ||
3711 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3712 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3713 E = CE->getArg(0)->IgnoreParenImpCasts();
3714 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3715 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3716 return getCanonicalDecl(VD);
3718 if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3719 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3720 return getCanonicalDecl(ME->getMemberDecl());
3724 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3725 // Check test-expr for canonical form, save upper-bound UB, flags for
3726 // less/greater and for strict/non-strict comparison.
3727 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3728 // var relational-op b
3729 // b relational-op var
3732 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3735 S = getExprAsWritten(S);
3736 SourceLocation CondLoc = S->getLocStart();
3737 if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3738 if (BO->isRelationalOp()) {
3739 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3740 return SetUB(BO->getRHS(),
3741 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3742 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3743 BO->getSourceRange(), BO->getOperatorLoc());
3744 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3745 return SetUB(BO->getLHS(),
3746 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3747 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3748 BO->getSourceRange(), BO->getOperatorLoc());
3750 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3751 if (CE->getNumArgs() == 2) {
3752 auto Op = CE->getOperator();
3755 case OO_GreaterEqual:
3758 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3759 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3760 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3761 CE->getOperatorLoc());
3762 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3763 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3764 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3765 CE->getOperatorLoc());
3772 if (Dependent() || SemaRef.CurContext->isDependentContext())
3774 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3775 << S->getSourceRange() << LCDecl;
3779 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3780 // RHS of canonical loop form increment can be:
3785 RHS = RHS->IgnoreParenImpCasts();
3786 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3787 if (BO->isAdditiveOp()) {
3788 bool IsAdd = BO->getOpcode() == BO_Add;
3789 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3790 return SetStep(BO->getRHS(), !IsAdd);
3791 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3792 return SetStep(BO->getLHS(), false);
3794 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3795 bool IsAdd = CE->getOperator() == OO_Plus;
3796 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3797 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3798 return SetStep(CE->getArg(1), !IsAdd);
3799 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3800 return SetStep(CE->getArg(0), false);
3803 if (Dependent() || SemaRef.CurContext->isDependentContext())
3805 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3806 << RHS->getSourceRange() << LCDecl;
3810 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3811 // Check incr-expr for canonical loop form and return true if it
3812 // does not conform.
3813 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3825 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3828 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3829 if (!ExprTemp->cleanupsHaveSideEffects())
3830 S = ExprTemp->getSubExpr();
3832 IncrementSrcRange = S->getSourceRange();
3833 S = S->IgnoreParens();
3834 if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3835 if (UO->isIncrementDecrementOp() &&
3836 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3837 return SetStep(SemaRef
3838 .ActOnIntegerConstant(UO->getLocStart(),
3839 (UO->isDecrementOp() ? -1 : 1))
3842 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3843 switch (BO->getOpcode()) {
3846 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3847 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3850 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3851 return CheckIncRHS(BO->getRHS());
3856 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3857 switch (CE->getOperator()) {
3860 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3861 return SetStep(SemaRef
3862 .ActOnIntegerConstant(
3864 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3870 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3871 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3874 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3875 return CheckIncRHS(CE->getArg(1));
3881 if (Dependent() || SemaRef.CurContext->isDependentContext())
3883 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3884 << S->getSourceRange() << LCDecl;
3889 tryBuildCapture(Sema &SemaRef, Expr *Capture,
3890 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3891 if (SemaRef.CurContext->isDependentContext())
3892 return ExprResult(Capture);
3893 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
3894 return SemaRef.PerformImplicitConversion(
3895 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
3896 /*AllowExplicit=*/true);
3897 auto I = Captures.find(Capture);
3898 if (I != Captures.end())
3899 return buildCapture(SemaRef, Capture, I->second);
3900 DeclRefExpr *Ref = nullptr;
3901 ExprResult Res = buildCapture(SemaRef, Capture, Ref);
3902 Captures[Capture] = Ref;
3906 /// \brief Build the expression to calculate the number of iterations.
3907 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3908 Scope *S, const bool LimitedType,
3909 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
3911 auto VarType = LCDecl->getType().getNonReferenceType();
3912 if (VarType->isIntegerType() || VarType->isPointerType() ||
3913 SemaRef.getLangOpts().CPlusPlus) {
3915 auto *UBExpr = TestIsLessOp ? UB : LB;
3916 auto *LBExpr = TestIsLessOp ? LB : UB;
3917 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3918 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3919 if (!Upper || !Lower)
3922 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3924 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3925 // BuildBinOp already emitted error, this one is to point user to upper
3926 // and lower bound, and to tell what is passed to 'operator-'.
3927 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3928 << Upper->getSourceRange() << Lower->getSourceRange();
3933 if (!Diff.isUsable())
3936 // Upper - Lower [- 1]
3938 Diff = SemaRef.BuildBinOp(
3939 S, DefaultLoc, BO_Sub, Diff.get(),
3940 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3941 if (!Diff.isUsable())
3944 // Upper - Lower [- 1] + Step
3945 auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
3946 if (!NewStep.isUsable())
3948 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3949 if (!Diff.isUsable())
3952 // Parentheses (for dumping/debugging purposes only).
3953 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3954 if (!Diff.isUsable())
3957 // (Upper - Lower [- 1] + Step) / Step
3958 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3959 if (!Diff.isUsable())
3962 // OpenMP runtime requires 32-bit or 64-bit loop variables.
3963 QualType Type = Diff.get()->getType();
3964 auto &C = SemaRef.Context;
3965 bool UseVarType = VarType->hasIntegerRepresentation() &&
3966 C.getTypeSize(Type) > C.getTypeSize(VarType);
3967 if (!Type->isIntegerType() || UseVarType) {
3969 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3970 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3971 : Type->hasSignedIntegerRepresentation();
3972 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3973 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3974 Diff = SemaRef.PerformImplicitConversion(
3975 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3976 if (!Diff.isUsable())
3981 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3982 if (NewSize != C.getTypeSize(Type)) {
3983 if (NewSize < C.getTypeSize(Type)) {
3984 assert(NewSize == 64 && "incorrect loop var size");
3985 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3986 << InitSrcRange << ConditionSrcRange;
3988 QualType NewType = C.getIntTypeForBitwidth(
3989 NewSize, Type->hasSignedIntegerRepresentation() ||
3990 C.getTypeSize(Type) < NewSize);
3991 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
3992 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
3993 Sema::AA_Converting, true);
3994 if (!Diff.isUsable())
4003 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4004 Scope *S, Expr *Cond,
4005 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4006 // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4007 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4008 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4010 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4011 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4012 if (!NewLB.isUsable() || !NewUB.isUsable())
4015 auto CondExpr = SemaRef.BuildBinOp(
4016 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4017 : (TestIsStrictOp ? BO_GT : BO_GE),
4018 NewLB.get(), NewUB.get());
4019 if (CondExpr.isUsable()) {
4020 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4021 SemaRef.Context.BoolTy))
4022 CondExpr = SemaRef.PerformImplicitConversion(
4023 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4024 /*AllowExplicit=*/true);
4026 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4027 // Otherwise use original loop conditon and evaluate it in runtime.
4028 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4031 /// \brief Build reference expression to the counter be used for codegen.
4032 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4033 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4034 auto *VD = dyn_cast<VarDecl>(LCDecl);
4036 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4037 auto *Ref = buildDeclRefExpr(
4038 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4039 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4040 // If the loop control decl is explicitly marked as private, do not mark it
4041 // as captured again.
4042 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4043 Captures.insert(std::make_pair(LCRef, Ref));
4046 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4050 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4051 if (LCDecl && !LCDecl->isInvalidDecl()) {
4052 auto Type = LCDecl->getType().getNonReferenceType();
4054 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4055 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4056 if (PrivateVar->isInvalidDecl())
4058 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4063 /// \brief Build initialization of the counter to be used for codegen.
4064 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; }
4066 /// \brief Build step of the counter be used for codegen.
4067 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4069 /// \brief Iteration space of a single for loop.
4070 struct LoopIterationSpace final {
4071 /// \brief Condition of the loop.
4072 Expr *PreCond = nullptr;
4073 /// \brief This expression calculates the number of iterations in the loop.
4074 /// It is always possible to calculate it before starting the loop.
4075 Expr *NumIterations = nullptr;
4076 /// \brief The loop counter variable.
4077 Expr *CounterVar = nullptr;
4078 /// \brief Private loop counter variable.
4079 Expr *PrivateCounterVar = nullptr;
4080 /// \brief This is initializer for the initial value of #CounterVar.
4081 Expr *CounterInit = nullptr;
4082 /// \brief This is step for the #CounterVar used to generate its update:
4083 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4084 Expr *CounterStep = nullptr;
4085 /// \brief Should step be subtracted?
4086 bool Subtract = false;
4087 /// \brief Source range of the loop init.
4088 SourceRange InitSrcRange;
4089 /// \brief Source range of the loop condition.
4090 SourceRange CondSrcRange;
4091 /// \brief Source range of the loop increment.
4092 SourceRange IncSrcRange;
4097 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
4098 assert(getLangOpts().OpenMP && "OpenMP is not active.");
4099 assert(Init && "Expected loop in canonical form.");
4100 unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4101 if (AssociatedLoops > 0 &&
4102 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4103 OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4104 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4105 if (auto *D = ISC.GetLoopDecl()) {
4106 auto *VD = dyn_cast<VarDecl>(D);
4108 if (auto *Private = IsOpenMPCapturedDecl(D))
4111 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4112 /*WithInit=*/false);
4113 VD = cast<VarDecl>(Ref->getDecl());
4116 DSAStack->addLoopControlVariable(D, VD);
4119 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4123 /// \brief Called on a for stmt to check and extract its iteration space
4124 /// for further processing (such as collapsing).
4125 static bool CheckOpenMPIterationSpace(
4126 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4127 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4128 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4129 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4130 LoopIterationSpace &ResultIterSpace,
4131 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4132 // OpenMP [2.6, Canonical Loop Form]
4133 // for (init-expr; test-expr; incr-expr) structured-block
4134 auto *For = dyn_cast_or_null<ForStmt>(S);
4136 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4137 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4138 << getOpenMPDirectiveName(DKind) << NestedLoopCount
4139 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4140 if (NestedLoopCount > 1) {
4141 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4142 SemaRef.Diag(DSA.getConstructLoc(),
4143 diag::note_omp_collapse_ordered_expr)
4144 << 2 << CollapseLoopCountExpr->getSourceRange()
4145 << OrderedLoopCountExpr->getSourceRange();
4146 else if (CollapseLoopCountExpr)
4147 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4148 diag::note_omp_collapse_ordered_expr)
4149 << 0 << CollapseLoopCountExpr->getSourceRange();
4151 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4152 diag::note_omp_collapse_ordered_expr)
4153 << 1 << OrderedLoopCountExpr->getSourceRange();
4157 assert(For->getBody());
4159 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4162 auto Init = For->getInit();
4163 if (ISC.CheckInit(Init))
4166 bool HasErrors = false;
4168 // Check loop variable's type.
4169 if (auto *LCDecl = ISC.GetLoopDecl()) {
4170 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4172 // OpenMP [2.6, Canonical Loop Form]
4173 // Var is one of the following:
4174 // A variable of signed or unsigned integer type.
4175 // For C++, a variable of a random access iterator type.
4176 // For C, a variable of a pointer type.
4177 auto VarType = LCDecl->getType().getNonReferenceType();
4178 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4179 !VarType->isPointerType() &&
4180 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4181 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4182 << SemaRef.getLangOpts().CPlusPlus;
4186 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4188 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4189 // parallel for construct is (are) private.
4190 // The loop iteration variable in the associated for-loop of a simd
4191 // construct with just one associated for-loop is linear with a
4192 // constant-linear-step that is the increment of the associated for-loop.
4193 // Exclude loop var from the list of variables with implicitly defined data
4194 // sharing attributes.
4195 VarsWithImplicitDSA.erase(LCDecl);
4197 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4198 // in a Construct, C/C++].
4199 // The loop iteration variable in the associated for-loop of a simd
4200 // construct with just one associated for-loop may be listed in a linear
4201 // clause with a constant-linear-step that is the increment of the
4202 // associated for-loop.
4203 // The loop iteration variable(s) in the associated for-loop(s) of a for or
4204 // parallel for construct may be listed in a private or lastprivate clause.
4205 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4206 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4207 // declared in the loop and it is predetermined as a private.
4208 auto PredeterminedCKind =
4209 isOpenMPSimdDirective(DKind)
4210 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4212 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4213 DVar.CKind != PredeterminedCKind) ||
4214 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4215 isOpenMPDistributeDirective(DKind)) &&
4216 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4217 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4218 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4219 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4220 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4221 << getOpenMPClauseName(PredeterminedCKind);
4222 if (DVar.RefExpr == nullptr)
4223 DVar.CKind = PredeterminedCKind;
4224 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4226 } else if (LoopDeclRefExpr != nullptr) {
4227 // Make the loop iteration variable private (for worksharing constructs),
4228 // linear (for simd directives with the only one associated loop) or
4229 // lastprivate (for simd directives with several collapsed or ordered
4231 if (DVar.CKind == OMPC_unknown)
4232 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4233 [](OpenMPDirectiveKind) -> bool { return true; },
4234 /*FromParent=*/false);
4235 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4238 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4241 HasErrors |= ISC.CheckCond(For->getCond());
4244 HasErrors |= ISC.CheckInc(For->getInc());
4247 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4250 // Build the loop's iteration space representation.
4251 ResultIterSpace.PreCond =
4252 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4253 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4255 (isOpenMPWorksharingDirective(DKind) ||
4256 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)),
4258 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4259 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4260 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4261 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4262 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4263 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4264 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4265 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4267 HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4268 ResultIterSpace.NumIterations == nullptr ||
4269 ResultIterSpace.CounterVar == nullptr ||
4270 ResultIterSpace.PrivateCounterVar == nullptr ||
4271 ResultIterSpace.CounterInit == nullptr ||
4272 ResultIterSpace.CounterStep == nullptr);
4277 /// \brief Build 'VarRef = Start.
4279 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4281 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4282 // Build 'VarRef = Start.
4283 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4284 if (!NewStart.isUsable())
4286 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4287 VarRef.get()->getType())) {
4288 NewStart = SemaRef.PerformImplicitConversion(
4289 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4290 /*AllowExplicit=*/true);
4291 if (!NewStart.isUsable())
4296 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4300 /// \brief Build 'VarRef = Start + Iter * Step'.
4302 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc,
4303 ExprResult VarRef, ExprResult Start, ExprResult Iter,
4304 ExprResult Step, bool Subtract,
4305 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4306 // Add parentheses (for debugging purposes only).
4307 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4308 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4312 ExprResult NewStep = Step;
4314 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4315 if (NewStep.isInvalid())
4318 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4319 if (!Update.isUsable())
4322 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4323 // 'VarRef = Start (+|-) Iter * Step'.
4324 ExprResult NewStart = Start;
4326 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4327 if (NewStart.isInvalid())
4330 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4331 ExprResult SavedUpdate = Update;
4332 ExprResult UpdateVal;
4333 if (VarRef.get()->getType()->isOverloadableType() ||
4334 NewStart.get()->getType()->isOverloadableType() ||
4335 Update.get()->getType()->isOverloadableType()) {
4336 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4337 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4339 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4340 if (Update.isUsable()) {
4342 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4343 VarRef.get(), SavedUpdate.get());
4344 if (UpdateVal.isUsable()) {
4345 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4349 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4352 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4353 if (!Update.isUsable() || !UpdateVal.isUsable()) {
4354 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4355 NewStart.get(), SavedUpdate.get());
4356 if (!Update.isUsable())
4359 if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4360 VarRef.get()->getType())) {
4361 Update = SemaRef.PerformImplicitConversion(
4362 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4363 if (!Update.isUsable())
4367 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4372 /// \brief Convert integer expression \a E to make it have at least \a Bits
4374 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4377 auto &C = SemaRef.Context;
4378 QualType OldType = E->getType();
4379 unsigned HasBits = C.getTypeSize(OldType);
4380 if (HasBits >= Bits)
4381 return ExprResult(E);
4382 // OK to convert to signed, because new type has more bits than old.
4383 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4384 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4388 /// \brief Check if the given expression \a E is a constant integer that fits
4389 /// into \a Bits bits.
4390 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4393 llvm::APSInt Result;
4394 if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4395 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4399 /// Build preinits statement for the given declarations.
4400 static Stmt *buildPreInits(ASTContext &Context,
4401 MutableArrayRef<Decl *> PreInits) {
4402 if (!PreInits.empty()) {
4403 return new (Context) DeclStmt(
4404 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4405 SourceLocation(), SourceLocation());
4410 /// Build preinits statement for the given declarations.
4412 buildPreInits(ASTContext &Context,
4413 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4414 if (!Captures.empty()) {
4415 SmallVector<Decl *, 16> PreInits;
4416 for (auto &Pair : Captures)
4417 PreInits.push_back(Pair.second->getDecl());
4418 return buildPreInits(Context, PreInits);
4423 /// Build postupdate expression for the given list of postupdates expressions.
4424 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4425 Expr *PostUpdate = nullptr;
4426 if (!PostUpdates.empty()) {
4427 for (auto *E : PostUpdates) {
4428 Expr *ConvE = S.BuildCStyleCastExpr(
4430 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
4433 PostUpdate = PostUpdate
4434 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4443 /// \brief Called on a for stmt to check itself and nested loops (if any).
4444 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4445 /// number of collapsed loops otherwise.
4447 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4448 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4450 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4451 OMPLoopDirective::HelperExprs &Built) {
4452 unsigned NestedLoopCount = 1;
4453 if (CollapseLoopCountExpr) {
4454 // Found 'collapse' clause - calculate collapse number.
4455 llvm::APSInt Result;
4456 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4457 NestedLoopCount = Result.getLimitedValue();
4459 if (OrderedLoopCountExpr) {
4460 // Found 'ordered' clause - calculate collapse number.
4461 llvm::APSInt Result;
4462 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4463 if (Result.getLimitedValue() < NestedLoopCount) {
4464 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4465 diag::err_omp_wrong_ordered_loop_count)
4466 << OrderedLoopCountExpr->getSourceRange();
4467 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4468 diag::note_collapse_loop_count)
4469 << CollapseLoopCountExpr->getSourceRange();
4471 NestedLoopCount = Result.getLimitedValue();
4474 // This is helper routine for loop directives (e.g., 'for', 'simd',
4475 // 'for simd', etc.).
4476 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4477 SmallVector<LoopIterationSpace, 4> IterSpaces;
4478 IterSpaces.resize(NestedLoopCount);
4479 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4480 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4481 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4482 NestedLoopCount, CollapseLoopCountExpr,
4483 OrderedLoopCountExpr, VarsWithImplicitDSA,
4484 IterSpaces[Cnt], Captures))
4486 // Move on to the next nested for loop, or to the loop body.
4487 // OpenMP [2.8.1, simd construct, Restrictions]
4488 // All loops associated with the construct must be perfectly nested; that
4489 // is, there must be no intervening code nor any OpenMP directive between
4491 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4494 Built.clear(/* size */ NestedLoopCount);
4496 if (SemaRef.CurContext->isDependentContext())
4497 return NestedLoopCount;
4499 // An example of what is generated for the following code:
4501 // #pragma omp simd collapse(2) ordered(2)
4502 // for (i = 0; i < NI; ++i)
4503 // for (k = 0; k < NK; ++k)
4504 // for (j = J0; j < NJ; j+=2) {
4508 // We generate the code below.
4509 // Note: the loop body may be outlined in CodeGen.
4510 // Note: some counters may be C++ classes, operator- is used to find number of
4511 // iterations and operator+= to calculate counter value.
4512 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4513 // or i64 is currently supported).
4515 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4516 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4517 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4518 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4519 // // similar updates for vars in clauses (e.g. 'linear')
4520 // <loop body (using local i and j)>
4522 // i = NI; // assign final values of counters
4526 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4527 // the iteration counts of the collapsed for loops.
4528 // Precondition tests if there is at least one iteration (all conditions are
4530 auto PreCond = ExprResult(IterSpaces[0].PreCond);
4531 auto N0 = IterSpaces[0].NumIterations;
4532 ExprResult LastIteration32 = WidenIterationCount(
4533 32 /* Bits */, SemaRef
4534 .PerformImplicitConversion(
4535 N0->IgnoreImpCasts(), N0->getType(),
4536 Sema::AA_Converting, /*AllowExplicit=*/true)
4539 ExprResult LastIteration64 = WidenIterationCount(
4540 64 /* Bits */, SemaRef
4541 .PerformImplicitConversion(
4542 N0->IgnoreImpCasts(), N0->getType(),
4543 Sema::AA_Converting, /*AllowExplicit=*/true)
4547 if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4548 return NestedLoopCount;
4550 auto &C = SemaRef.Context;
4551 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4553 Scope *CurScope = DSA.getCurScope();
4554 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4555 if (PreCond.isUsable()) {
4557 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4558 PreCond.get(), IterSpaces[Cnt].PreCond);
4560 auto N = IterSpaces[Cnt].NumIterations;
4561 SourceLocation Loc = N->getExprLoc();
4562 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4563 if (LastIteration32.isUsable())
4564 LastIteration32 = SemaRef.BuildBinOp(
4565 CurScope, Loc, BO_Mul, LastIteration32.get(),
4567 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4568 Sema::AA_Converting,
4569 /*AllowExplicit=*/true)
4571 if (LastIteration64.isUsable())
4572 LastIteration64 = SemaRef.BuildBinOp(
4573 CurScope, Loc, BO_Mul, LastIteration64.get(),
4575 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4576 Sema::AA_Converting,
4577 /*AllowExplicit=*/true)
4581 // Choose either the 32-bit or 64-bit version.
4582 ExprResult LastIteration = LastIteration64;
4583 if (LastIteration32.isUsable() &&
4584 C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4585 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4588 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4589 LastIteration64.get(), SemaRef)))
4590 LastIteration = LastIteration32;
4591 QualType VType = LastIteration.get()->getType();
4592 QualType RealVType = VType;
4593 QualType StrideVType = VType;
4594 if (isOpenMPTaskLoopDirective(DKind)) {
4596 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4598 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4601 if (!LastIteration.isUsable())
4604 // Save the number of iterations.
4605 ExprResult NumIterations = LastIteration;
4607 LastIteration = SemaRef.BuildBinOp(
4608 CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4609 LastIteration.get(),
4610 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4611 if (!LastIteration.isUsable())
4615 // Calculate the last iteration number beforehand instead of doing this on
4616 // each iteration. Do not do this if the number of iterations may be kfold-ed.
4617 llvm::APSInt Result;
4619 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4620 ExprResult CalcLastIteration;
4622 ExprResult SaveRef =
4623 tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4624 LastIteration = SaveRef;
4626 // Prepare SaveRef + 1.
4627 NumIterations = SemaRef.BuildBinOp(
4628 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4629 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4630 if (!NumIterations.isUsable())
4634 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4636 // Build variables passed into runtime, necessary for worksharing directives.
4637 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4638 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4639 isOpenMPDistributeDirective(DKind)) {
4640 // Lower bound variable, initialized with zero.
4641 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4642 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4643 SemaRef.AddInitializerToDecl(LBDecl,
4644 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4645 /*DirectInit*/ false);
4647 // Upper bound variable, initialized with last iteration number.
4648 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4649 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4650 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4651 /*DirectInit*/ false);
4653 // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4654 // This will be used to implement clause 'lastprivate'.
4655 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4656 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4657 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4658 SemaRef.AddInitializerToDecl(ILDecl,
4659 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4660 /*DirectInit*/ false);
4662 // Stride variable returned by runtime (we initialize it to 1 by default).
4664 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4665 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4666 SemaRef.AddInitializerToDecl(STDecl,
4667 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4668 /*DirectInit*/ false);
4670 // Build expression: UB = min(UB, LastIteration)
4671 // It is necessary for CodeGen of directives with static scheduling.
4672 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4673 UB.get(), LastIteration.get());
4674 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4675 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4676 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4678 EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4680 // If we have a combined directive that combines 'distribute', 'for' or
4681 // 'simd' we need to be able to access the bounds of the schedule of the
4682 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4683 // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4684 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4686 // Lower bound variable, initialized with zero.
4687 VarDecl *CombLBDecl =
4688 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4689 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4690 SemaRef.AddInitializerToDecl(
4691 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4692 /*DirectInit*/ false);
4694 // Upper bound variable, initialized with last iteration number.
4695 VarDecl *CombUBDecl =
4696 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4697 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4698 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4699 /*DirectInit*/ false);
4701 ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4702 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4703 ExprResult CombCondOp =
4704 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4705 LastIteration.get(), CombUB.get());
4706 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4708 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4710 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4711 // We expect to have at least 2 more parameters than the 'parallel'
4712 // directive does - the lower and upper bounds of the previous schedule.
4713 assert(CD->getNumParams() >= 4 &&
4714 "Unexpected number of parameters in loop combined directive");
4716 // Set the proper type for the bounds given what we learned from the
4718 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4719 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4721 // Previous lower and upper bounds are obtained from the region
4724 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4726 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4730 // Build the iteration variable and its initialization before loop.
4732 ExprResult Init, CombInit;
4734 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4735 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4737 (isOpenMPWorksharingDirective(DKind) ||
4738 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4740 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4741 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4742 Init = SemaRef.ActOnFinishFullExpr(Init.get());
4744 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4746 (isOpenMPWorksharingDirective(DKind) ||
4747 isOpenMPTaskLoopDirective(DKind) ||
4748 isOpenMPDistributeDirective(DKind))
4750 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4752 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4753 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4757 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4758 SourceLocation CondLoc;
4760 (isOpenMPWorksharingDirective(DKind) ||
4761 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind))
4762 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4763 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4764 NumIterations.get());
4765 ExprResult CombCond;
4766 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4768 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4770 // Loop increment (IV = IV + 1)
4771 SourceLocation IncLoc;
4773 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4774 SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4775 if (!Inc.isUsable())
4777 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4778 Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4779 if (!Inc.isUsable())
4782 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4783 // Used for directives with static scheduling.
4784 // In combined construct, add combined version that use CombLB and CombUB
4785 // base variables for the update
4786 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4787 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
4788 isOpenMPDistributeDirective(DKind)) {
4790 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4791 if (!NextLB.isUsable())
4795 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4796 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4797 if (!NextLB.isUsable())
4800 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4801 if (!NextUB.isUsable())
4805 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4806 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4807 if (!NextUB.isUsable())
4809 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4811 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4812 if (!NextLB.isUsable())
4815 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4817 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4818 if (!CombNextLB.isUsable())
4822 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4823 if (!CombNextUB.isUsable())
4826 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4828 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4829 if (!CombNextUB.isUsable())
4834 // Create increment expression for distribute loop when combined in a same
4835 // directive with for as IV = IV + ST; ensure upper bound expression based
4836 // on PrevUB instead of NumIterations - used to implement 'for' when found
4837 // in combination with 'distribute', like in 'distribute parallel for'
4838 SourceLocation DistIncLoc;
4839 ExprResult DistCond, DistInc, PrevEUB;
4840 if (isOpenMPLoopBoundSharingDirective(DKind)) {
4841 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4842 assert(DistCond.isUsable() && "distribute cond expr was not built");
4845 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4846 assert(DistInc.isUsable() && "distribute inc expr was not built");
4847 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4849 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4850 assert(DistInc.isUsable() && "distribute inc expr was not built");
4852 // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4854 SourceLocation DistEUBLoc;
4855 ExprResult IsUBGreater =
4856 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4857 ExprResult CondOp = SemaRef.ActOnConditionalOp(
4858 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4859 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4861 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4864 // Build updates and final values of the loop counters.
4865 bool HasErrors = false;
4866 Built.Counters.resize(NestedLoopCount);
4867 Built.Inits.resize(NestedLoopCount);
4868 Built.Updates.resize(NestedLoopCount);
4869 Built.Finals.resize(NestedLoopCount);
4870 SmallVector<Expr *, 4> LoopMultipliers;
4873 // Go from inner nested loop to outer.
4874 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4875 LoopIterationSpace &IS = IterSpaces[Cnt];
4876 SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4877 // Build: Iter = (IV / Div) % IS.NumIters
4878 // where Div is product of previous iterations' IS.NumIters.
4880 if (Div.isUsable()) {
4882 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4885 assert((Cnt == (int)NestedLoopCount - 1) &&
4886 "unusable div expected on first iteration only");
4889 if (Cnt != 0 && Iter.isUsable())
4890 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4892 if (!Iter.isUsable()) {
4897 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4898 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4899 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
4900 IS.CounterVar->getExprLoc(),
4901 /*RefersToCapture=*/true);
4902 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4903 IS.CounterInit, Captures);
4904 if (!Init.isUsable()) {
4908 ExprResult Update = BuildCounterUpdate(
4909 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4910 IS.CounterStep, IS.Subtract, &Captures);
4911 if (!Update.isUsable()) {
4916 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4917 ExprResult Final = BuildCounterUpdate(
4918 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4919 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4920 if (!Final.isUsable()) {
4925 // Build Div for the next iteration: Div <- Div * IS.NumIters
4928 Div = IS.NumIterations;
4930 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4933 // Add parentheses (for debugging purposes only).
4935 Div = tryBuildCapture(SemaRef, Div.get(), Captures);
4936 if (!Div.isUsable()) {
4940 LoopMultipliers.push_back(Div.get());
4942 if (!Update.isUsable() || !Final.isUsable()) {
4947 Built.Counters[Cnt] = IS.CounterVar;
4948 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4949 Built.Inits[Cnt] = Init.get();
4950 Built.Updates[Cnt] = Update.get();
4951 Built.Finals[Cnt] = Final.get();
4959 Built.IterationVarRef = IV.get();
4960 Built.LastIteration = LastIteration.get();
4961 Built.NumIterations = NumIterations.get();
4962 Built.CalcLastIteration =
4963 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4964 Built.PreCond = PreCond.get();
4965 Built.PreInits = buildPreInits(C, Captures);
4966 Built.Cond = Cond.get();
4967 Built.Init = Init.get();
4968 Built.Inc = Inc.get();
4969 Built.LB = LB.get();
4970 Built.UB = UB.get();
4971 Built.IL = IL.get();
4972 Built.ST = ST.get();
4973 Built.EUB = EUB.get();
4974 Built.NLB = NextLB.get();
4975 Built.NUB = NextUB.get();
4976 Built.PrevLB = PrevLB.get();
4977 Built.PrevUB = PrevUB.get();
4978 Built.DistInc = DistInc.get();
4979 Built.PrevEUB = PrevEUB.get();
4980 Built.DistCombinedFields.LB = CombLB.get();
4981 Built.DistCombinedFields.UB = CombUB.get();
4982 Built.DistCombinedFields.EUB = CombEUB.get();
4983 Built.DistCombinedFields.Init = CombInit.get();
4984 Built.DistCombinedFields.Cond = CombCond.get();
4985 Built.DistCombinedFields.NLB = CombNextLB.get();
4986 Built.DistCombinedFields.NUB = CombNextUB.get();
4988 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
4989 // Fill data for doacross depend clauses.
4990 for (auto Pair : DSA.getDoacrossDependClauses()) {
4991 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4992 Pair.first->setCounterValue(CounterVal);
4994 if (NestedLoopCount != Pair.second.size() ||
4995 NestedLoopCount != LoopMultipliers.size() + 1) {
4996 // Erroneous case - clause has some problems.
4997 Pair.first->setCounterValue(CounterVal);
5000 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5001 auto I = Pair.second.rbegin();
5002 auto IS = IterSpaces.rbegin();
5003 auto ILM = LoopMultipliers.rbegin();
5004 Expr *UpCounterVal = CounterVal;
5005 Expr *Multiplier = nullptr;
5006 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5008 assert(IS->CounterStep);
5009 Expr *NormalizedOffset =
5011 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5012 I->first, IS->CounterStep)
5017 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5018 NormalizedOffset, Multiplier)
5021 assert(I->second == OO_Plus || I->second == OO_Minus);
5022 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5023 UpCounterVal = SemaRef
5024 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5025 UpCounterVal, NormalizedOffset)
5033 Pair.first->setCounterValue(UpCounterVal);
5037 return NestedLoopCount;
5040 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
5041 auto CollapseClauses =
5042 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5043 if (CollapseClauses.begin() != CollapseClauses.end())
5044 return (*CollapseClauses.begin())->getNumForLoops();
5048 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
5049 auto OrderedClauses =
5050 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5051 if (OrderedClauses.begin() != OrderedClauses.end())
5052 return (*OrderedClauses.begin())->getNumForLoops();
5056 static bool checkSimdlenSafelenSpecified(Sema &S,
5057 const ArrayRef<OMPClause *> Clauses) {
5058 OMPSafelenClause *Safelen = nullptr;
5059 OMPSimdlenClause *Simdlen = nullptr;
5061 for (auto *Clause : Clauses) {
5062 if (Clause->getClauseKind() == OMPC_safelen)
5063 Safelen = cast<OMPSafelenClause>(Clause);
5064 else if (Clause->getClauseKind() == OMPC_simdlen)
5065 Simdlen = cast<OMPSimdlenClause>(Clause);
5066 if (Safelen && Simdlen)
5070 if (Simdlen && Safelen) {
5071 llvm::APSInt SimdlenRes, SafelenRes;
5072 auto SimdlenLength = Simdlen->getSimdlen();
5073 auto SafelenLength = Safelen->getSafelen();
5074 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5075 SimdlenLength->isInstantiationDependent() ||
5076 SimdlenLength->containsUnexpandedParameterPack())
5078 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5079 SafelenLength->isInstantiationDependent() ||
5080 SafelenLength->containsUnexpandedParameterPack())
5082 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5083 SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5084 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5085 // If both simdlen and safelen clauses are specified, the value of the
5086 // simdlen parameter must be less than or equal to the value of the safelen
5088 if (SimdlenRes > SafelenRes) {
5089 S.Diag(SimdlenLength->getExprLoc(),
5090 diag::err_omp_wrong_simdlen_safelen_values)
5091 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5098 StmtResult Sema::ActOnOpenMPSimdDirective(
5099 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5100 SourceLocation EndLoc,
5101 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5105 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5106 OMPLoopDirective::HelperExprs B;
5107 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5108 // define the nested loops number.
5109 unsigned NestedLoopCount = CheckOpenMPLoop(
5110 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5111 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5112 if (NestedLoopCount == 0)
5115 assert((CurContext->isDependentContext() || B.builtAll()) &&
5116 "omp simd loop exprs were not built");
5118 if (!CurContext->isDependentContext()) {
5119 // Finalize the clauses that need pre-built expressions for CodeGen.
5120 for (auto C : Clauses) {
5121 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5122 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5123 B.NumIterations, *this, CurScope,
5129 if (checkSimdlenSafelenSpecified(*this, Clauses))
5132 getCurFunction()->setHasBranchProtectedScope();
5133 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5137 StmtResult Sema::ActOnOpenMPForDirective(
5138 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5139 SourceLocation EndLoc,
5140 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5144 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5145 OMPLoopDirective::HelperExprs B;
5146 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5147 // define the nested loops number.
5148 unsigned NestedLoopCount = CheckOpenMPLoop(
5149 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5150 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5151 if (NestedLoopCount == 0)
5154 assert((CurContext->isDependentContext() || B.builtAll()) &&
5155 "omp for loop exprs were not built");
5157 if (!CurContext->isDependentContext()) {
5158 // Finalize the clauses that need pre-built expressions for CodeGen.
5159 for (auto C : Clauses) {
5160 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5161 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5162 B.NumIterations, *this, CurScope,
5168 getCurFunction()->setHasBranchProtectedScope();
5169 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5170 Clauses, AStmt, B, DSAStack->isCancelRegion());
5173 StmtResult Sema::ActOnOpenMPForSimdDirective(
5174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5175 SourceLocation EndLoc,
5176 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5180 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5181 OMPLoopDirective::HelperExprs B;
5182 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5183 // define the nested loops number.
5184 unsigned NestedLoopCount =
5185 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5186 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5187 VarsWithImplicitDSA, B);
5188 if (NestedLoopCount == 0)
5191 assert((CurContext->isDependentContext() || B.builtAll()) &&
5192 "omp for simd loop exprs were not built");
5194 if (!CurContext->isDependentContext()) {
5195 // Finalize the clauses that need pre-built expressions for CodeGen.
5196 for (auto C : Clauses) {
5197 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5198 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5199 B.NumIterations, *this, CurScope,
5205 if (checkSimdlenSafelenSpecified(*this, Clauses))
5208 getCurFunction()->setHasBranchProtectedScope();
5209 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5213 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
5215 SourceLocation StartLoc,
5216 SourceLocation EndLoc) {
5220 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5221 auto BaseStmt = AStmt;
5222 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5223 BaseStmt = CS->getCapturedStmt();
5224 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5225 auto S = C->children();
5226 if (S.begin() == S.end())
5228 // All associated statements must be '#pragma omp section' except for
5230 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5231 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5233 Diag(SectionStmt->getLocStart(),
5234 diag::err_omp_sections_substmt_not_section);
5237 cast<OMPSectionDirective>(SectionStmt)
5238 ->setHasCancel(DSAStack->isCancelRegion());
5241 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5245 getCurFunction()->setHasBranchProtectedScope();
5247 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5248 DSAStack->isCancelRegion());
5251 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
5252 SourceLocation StartLoc,
5253 SourceLocation EndLoc) {
5257 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5259 getCurFunction()->setHasBranchProtectedScope();
5260 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5262 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5263 DSAStack->isCancelRegion());
5266 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
5268 SourceLocation StartLoc,
5269 SourceLocation EndLoc) {
5273 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5275 getCurFunction()->setHasBranchProtectedScope();
5277 // OpenMP [2.7.3, single Construct, Restrictions]
5278 // The copyprivate clause must not be used with the nowait clause.
5279 OMPClause *Nowait = nullptr;
5280 OMPClause *Copyprivate = nullptr;
5281 for (auto *Clause : Clauses) {
5282 if (Clause->getClauseKind() == OMPC_nowait)
5284 else if (Clause->getClauseKind() == OMPC_copyprivate)
5285 Copyprivate = Clause;
5286 if (Copyprivate && Nowait) {
5287 Diag(Copyprivate->getLocStart(),
5288 diag::err_omp_single_copyprivate_with_nowait);
5289 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5294 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5297 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
5298 SourceLocation StartLoc,
5299 SourceLocation EndLoc) {
5303 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5305 getCurFunction()->setHasBranchProtectedScope();
5307 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5310 StmtResult Sema::ActOnOpenMPCriticalDirective(
5311 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5312 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5316 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5318 bool ErrorFound = false;
5320 SourceLocation HintLoc;
5321 bool DependentHint = false;
5322 for (auto *C : Clauses) {
5323 if (C->getClauseKind() == OMPC_hint) {
5324 if (!DirName.getName()) {
5325 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5328 Expr *E = cast<OMPHintClause>(C)->getHint();
5329 if (E->isTypeDependent() || E->isValueDependent() ||
5330 E->isInstantiationDependent())
5331 DependentHint = true;
5333 Hint = E->EvaluateKnownConstInt(Context);
5334 HintLoc = C->getLocStart();
5340 auto Pair = DSAStack->getCriticalWithHint(DirName);
5341 if (Pair.first && DirName.getName() && !DependentHint) {
5342 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5343 Diag(StartLoc, diag::err_omp_critical_with_hint);
5344 if (HintLoc.isValid()) {
5345 Diag(HintLoc, diag::note_omp_critical_hint_here)
5346 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5348 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5349 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5350 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5352 << C->getHint()->EvaluateKnownConstInt(Context).toString(
5353 /*Radix=*/10, /*Signed=*/false);
5355 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5359 getCurFunction()->setHasBranchProtectedScope();
5361 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5363 if (!Pair.first && DirName.getName() && !DependentHint)
5364 DSAStack->addCriticalWithHint(Dir, Hint);
5368 StmtResult Sema::ActOnOpenMPParallelForDirective(
5369 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5370 SourceLocation EndLoc,
5371 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5375 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5376 // 1.2.2 OpenMP Language Terminology
5377 // Structured block - An executable statement with a single entry at the
5378 // top and a single exit at the bottom.
5379 // The point of exit cannot be a branch out of the structured block.
5380 // longjmp() and throw() must not violate the entry/exit criteria.
5381 CS->getCapturedDecl()->setNothrow();
5383 OMPLoopDirective::HelperExprs B;
5384 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5385 // define the nested loops number.
5386 unsigned NestedLoopCount =
5387 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5388 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5389 VarsWithImplicitDSA, B);
5390 if (NestedLoopCount == 0)
5393 assert((CurContext->isDependentContext() || B.builtAll()) &&
5394 "omp parallel for loop exprs were not built");
5396 if (!CurContext->isDependentContext()) {
5397 // Finalize the clauses that need pre-built expressions for CodeGen.
5398 for (auto C : Clauses) {
5399 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5400 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5401 B.NumIterations, *this, CurScope,
5407 getCurFunction()->setHasBranchProtectedScope();
5408 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5409 NestedLoopCount, Clauses, AStmt, B,
5410 DSAStack->isCancelRegion());
5413 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
5414 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5415 SourceLocation EndLoc,
5416 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5420 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5421 // 1.2.2 OpenMP Language Terminology
5422 // Structured block - An executable statement with a single entry at the
5423 // top and a single exit at the bottom.
5424 // The point of exit cannot be a branch out of the structured block.
5425 // longjmp() and throw() must not violate the entry/exit criteria.
5426 CS->getCapturedDecl()->setNothrow();
5428 OMPLoopDirective::HelperExprs B;
5429 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5430 // define the nested loops number.
5431 unsigned NestedLoopCount =
5432 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5433 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5434 VarsWithImplicitDSA, B);
5435 if (NestedLoopCount == 0)
5438 if (!CurContext->isDependentContext()) {
5439 // Finalize the clauses that need pre-built expressions for CodeGen.
5440 for (auto C : Clauses) {
5441 if (auto *LC = dyn_cast<OMPLinearClause>(C))
5442 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5443 B.NumIterations, *this, CurScope,
5449 if (checkSimdlenSafelenSpecified(*this, Clauses))
5452 getCurFunction()->setHasBranchProtectedScope();
5453 return OMPParallelForSimdDirective::Create(
5454 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5458 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
5459 Stmt *AStmt, SourceLocation StartLoc,
5460 SourceLocation EndLoc) {
5464 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5465 auto BaseStmt = AStmt;
5466 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5467 BaseStmt = CS->getCapturedStmt();
5468 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5469 auto S = C->children();
5470 if (S.begin() == S.end())
5472 // All associated statements must be '#pragma omp section' except for
5474 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5475 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5477 Diag(SectionStmt->getLocStart(),
5478 diag::err_omp_parallel_sections_substmt_not_section);
5481 cast<OMPSectionDirective>(SectionStmt)
5482 ->setHasCancel(DSAStack->isCancelRegion());
5485 Diag(AStmt->getLocStart(),
5486 diag::err_omp_parallel_sections_not_compound_stmt);
5490 getCurFunction()->setHasBranchProtectedScope();
5492 return OMPParallelSectionsDirective::Create(
5493 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5496 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
5497 Stmt *AStmt, SourceLocation StartLoc,
5498 SourceLocation EndLoc) {
5502 auto *CS = cast<CapturedStmt>(AStmt);
5503 // 1.2.2 OpenMP Language Terminology
5504 // Structured block - An executable statement with a single entry at the
5505 // top and a single exit at the bottom.
5506 // The point of exit cannot be a branch out of the structured block.
5507 // longjmp() and throw() must not violate the entry/exit criteria.
5508 CS->getCapturedDecl()->setNothrow();
5510 getCurFunction()->setHasBranchProtectedScope();
5512 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5513 DSAStack->isCancelRegion());
5516 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
5517 SourceLocation EndLoc) {
5518 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5521 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
5522 SourceLocation EndLoc) {
5523 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5526 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
5527 SourceLocation EndLoc) {
5528 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5531 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
5533 SourceLocation StartLoc,
5534 SourceLocation EndLoc) {
5538 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5540 getCurFunction()->setHasBranchProtectedScope();
5542 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5544 DSAStack->getTaskgroupReductionRef());
5547 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
5548 SourceLocation StartLoc,
5549 SourceLocation EndLoc) {
5550 assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5551 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5554 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
5556 SourceLocation StartLoc,
5557 SourceLocation EndLoc) {
5558 OMPClause *DependFound = nullptr;
5559 OMPClause *DependSourceClause = nullptr;
5560 OMPClause *DependSinkClause = nullptr;
5561 bool ErrorFound = false;
5562 OMPThreadsClause *TC = nullptr;
5563 OMPSIMDClause *SC = nullptr;
5564 for (auto *C : Clauses) {
5565 if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5567 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5568 if (DependSourceClause) {
5569 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5570 << getOpenMPDirectiveName(OMPD_ordered)
5571 << getOpenMPClauseName(OMPC_depend) << 2;
5574 DependSourceClause = C;
5575 if (DependSinkClause) {
5576 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5580 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5581 if (DependSourceClause) {
5582 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5586 DependSinkClause = C;
5588 } else if (C->getClauseKind() == OMPC_threads)
5589 TC = cast<OMPThreadsClause>(C);
5590 else if (C->getClauseKind() == OMPC_simd)
5591 SC = cast<OMPSIMDClause>(C);
5593 if (!ErrorFound && !SC &&
5594 isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5595 // OpenMP [2.8.1,simd Construct, Restrictions]
5596 // An ordered construct with the simd clause is the only OpenMP construct
5597 // that can appear in the simd region.
5598 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5600 } else if (DependFound && (TC || SC)) {
5601 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5602 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5604 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
5605 Diag(DependFound->getLocStart(),
5606 diag::err_omp_ordered_directive_without_param);
5608 } else if (TC || Clauses.empty()) {
5609 if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
5610 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5611 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5613 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5617 if ((!AStmt && !DependFound) || ErrorFound)
5621 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5623 getCurFunction()->setHasBranchProtectedScope();
5626 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5630 /// \brief Helper class for checking expression in 'omp atomic [update]'
5632 class OpenMPAtomicUpdateChecker {
5633 /// \brief Error results for atomic update expressions.
5634 enum ExprAnalysisErrorCode {
5635 /// \brief A statement is not an expression statement.
5637 /// \brief Expression is not builtin binary or unary operation.
5638 NotABinaryOrUnaryExpression,
5639 /// \brief Unary operation is not post-/pre- increment/decrement operation.
5640 NotAnUnaryIncDecExpression,
5641 /// \brief An expression is not of scalar type.
5643 /// \brief A binary operation is not an assignment operation.
5645 /// \brief RHS part of the binary operation is not a binary expression.
5646 NotABinaryExpression,
5647 /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5650 /// \brief RHS binary operation does not have reference to the updated LHS
5652 NotAnUpdateExpression,
5653 /// \brief No errors is found.
5656 /// \brief Reference to Sema.
5658 /// \brief A location for note diagnostics (when error is found).
5659 SourceLocation NoteLoc;
5660 /// \brief 'x' lvalue part of the source atomic expression.
5662 /// \brief 'expr' rvalue part of the source atomic expression.
5664 /// \brief Helper expression of the form
5665 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5666 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5668 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5669 /// important for non-associative operations.
5670 bool IsXLHSInRHSPart;
5671 BinaryOperatorKind Op;
5672 SourceLocation OpLoc;
5673 /// \brief true if the source expression is a postfix unary operation, false
5674 /// if it is a prefix unary operation.
5675 bool IsPostfixUpdate;
5678 OpenMPAtomicUpdateChecker(Sema &SemaRef)
5679 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5680 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5681 /// \brief Check specified statement that it is suitable for 'atomic update'
5682 /// constructs and extract 'x', 'expr' and Operation from the original
5683 /// expression. If DiagId and NoteId == 0, then only check is performed
5684 /// without error notification.
5685 /// \param DiagId Diagnostic which should be emitted if error is found.
5686 /// \param NoteId Diagnostic note for the main error message.
5687 /// \return true if statement is not an update expression, false otherwise.
5688 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5689 /// \brief Return the 'x' lvalue part of the source atomic expression.
5690 Expr *getX() const { return X; }
5691 /// \brief Return the 'expr' rvalue part of the source atomic expression.
5692 Expr *getExpr() const { return E; }
5693 /// \brief Return the update expression used in calculation of the updated
5694 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5695 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5696 Expr *getUpdateExpr() const { return UpdateExpr; }
5697 /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5698 /// false otherwise.
5699 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5701 /// \brief true if the source expression is a postfix unary operation, false
5702 /// if it is a prefix unary operation.
5703 bool isPostfixUpdate() const { return IsPostfixUpdate; }
5706 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5707 unsigned NoteId = 0);
5711 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5712 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5713 ExprAnalysisErrorCode ErrorFound = NoError;
5714 SourceLocation ErrorLoc, NoteLoc;
5715 SourceRange ErrorRange, NoteRange;
5716 // Allowed constructs are:
5717 // x = x binop expr;
5718 // x = expr binop x;
5719 if (AtomicBinOp->getOpcode() == BO_Assign) {
5720 X = AtomicBinOp->getLHS();
5721 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5722 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5723 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5724 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5725 AtomicInnerBinOp->isBitwiseOp()) {
5726 Op = AtomicInnerBinOp->getOpcode();
5727 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5728 auto *LHS = AtomicInnerBinOp->getLHS();
5729 auto *RHS = AtomicInnerBinOp->getRHS();
5730 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5731 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5732 /*Canonical=*/true);
5733 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5734 /*Canonical=*/true);
5735 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
5736 /*Canonical=*/true);
5739 IsXLHSInRHSPart = true;
5740 } else if (XId == RHSId) {
5742 IsXLHSInRHSPart = false;
5744 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5745 ErrorRange = AtomicInnerBinOp->getSourceRange();
5746 NoteLoc = X->getExprLoc();
5747 NoteRange = X->getSourceRange();
5748 ErrorFound = NotAnUpdateExpression;
5751 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5752 ErrorRange = AtomicInnerBinOp->getSourceRange();
5753 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5754 NoteRange = SourceRange(NoteLoc, NoteLoc);
5755 ErrorFound = NotABinaryOperator;
5758 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
5759 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
5760 ErrorFound = NotABinaryExpression;
5763 ErrorLoc = AtomicBinOp->getExprLoc();
5764 ErrorRange = AtomicBinOp->getSourceRange();
5765 NoteLoc = AtomicBinOp->getOperatorLoc();
5766 NoteRange = SourceRange(NoteLoc, NoteLoc);
5767 ErrorFound = NotAnAssignmentOp;
5769 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5770 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5771 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5773 } else if (SemaRef.CurContext->isDependentContext())
5774 E = X = UpdateExpr = nullptr;
5775 return ErrorFound != NoError;
5778 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
5780 ExprAnalysisErrorCode ErrorFound = NoError;
5781 SourceLocation ErrorLoc, NoteLoc;
5782 SourceRange ErrorRange, NoteRange;
5783 // Allowed constructs are:
5789 // x = x binop expr;
5790 // x = expr binop x;
5791 if (auto *AtomicBody = dyn_cast<Expr>(S)) {
5792 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5793 if (AtomicBody->getType()->isScalarType() ||
5794 AtomicBody->isInstantiationDependent()) {
5795 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5796 AtomicBody->IgnoreParenImpCasts())) {
5797 // Check for Compound Assignment Operation
5798 Op = BinaryOperator::getOpForCompoundAssignment(
5799 AtomicCompAssignOp->getOpcode());
5800 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5801 E = AtomicCompAssignOp->getRHS();
5802 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5803 IsXLHSInRHSPart = true;
5804 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5805 AtomicBody->IgnoreParenImpCasts())) {
5806 // Check for Binary Operation
5807 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5809 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5810 AtomicBody->IgnoreParenImpCasts())) {
5811 // Check for Unary Operation
5812 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5813 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5814 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5815 OpLoc = AtomicUnaryOp->getOperatorLoc();
5816 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5817 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
5818 IsXLHSInRHSPart = true;
5820 ErrorFound = NotAnUnaryIncDecExpression;
5821 ErrorLoc = AtomicUnaryOp->getExprLoc();
5822 ErrorRange = AtomicUnaryOp->getSourceRange();
5823 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5824 NoteRange = SourceRange(NoteLoc, NoteLoc);
5826 } else if (!AtomicBody->isInstantiationDependent()) {
5827 ErrorFound = NotABinaryOrUnaryExpression;
5828 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5829 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5832 ErrorFound = NotAScalarType;
5833 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5834 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5837 ErrorFound = NotAnExpression;
5838 NoteLoc = ErrorLoc = S->getLocStart();
5839 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5841 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5842 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5843 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5845 } else if (SemaRef.CurContext->isDependentContext())
5846 E = X = UpdateExpr = nullptr;
5847 if (ErrorFound == NoError && E && X) {
5848 // Build an update expression of form 'OpaqueValueExpr(x) binop
5849 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
5850 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
5851 auto *OVEX = new (SemaRef.getASTContext())
5852 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
5853 auto *OVEExpr = new (SemaRef.getASTContext())
5854 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
5856 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
5857 IsXLHSInRHSPart ? OVEExpr : OVEX);
5858 if (Update.isInvalid())
5860 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
5862 if (Update.isInvalid())
5864 UpdateExpr = Update.get();
5866 return ErrorFound != NoError;
5869 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
5871 SourceLocation StartLoc,
5872 SourceLocation EndLoc) {
5876 auto *CS = cast<CapturedStmt>(AStmt);
5877 // 1.2.2 OpenMP Language Terminology
5878 // Structured block - An executable statement with a single entry at the
5879 // top and a single exit at the bottom.
5880 // The point of exit cannot be a branch out of the structured block.
5881 // longjmp() and throw() must not violate the entry/exit criteria.
5882 OpenMPClauseKind AtomicKind = OMPC_unknown;
5883 SourceLocation AtomicKindLoc;
5884 for (auto *C : Clauses) {
5885 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5886 C->getClauseKind() == OMPC_update ||
5887 C->getClauseKind() == OMPC_capture) {
5888 if (AtomicKind != OMPC_unknown) {
5889 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5890 << SourceRange(C->getLocStart(), C->getLocEnd());
5891 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5892 << getOpenMPClauseName(AtomicKind);
5894 AtomicKind = C->getClauseKind();
5895 AtomicKindLoc = C->getLocStart();
5900 auto Body = CS->getCapturedStmt();
5901 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5902 Body = EWC->getSubExpr();
5908 bool IsXLHSInRHSPart = false;
5909 bool IsPostfixUpdate = false;
5910 // OpenMP [2.12.6, atomic Construct]
5911 // In the next expressions:
5912 // * x and v (as applicable) are both l-value expressions with scalar type.
5913 // * During the execution of an atomic region, multiple syntactic
5914 // occurrences of x must designate the same storage location.
5915 // * Neither of v and expr (as applicable) may access the storage location
5917 // * Neither of x and expr (as applicable) may access the storage location
5919 // * expr is an expression with scalar type.
5920 // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5921 // * binop, binop=, ++, and -- are not overloaded operators.
5922 // * The expression x binop expr must be numerically equivalent to x binop
5923 // (expr). This requirement is satisfied if the operators in expr have
5924 // precedence greater than binop, or by using parentheses around expr or
5925 // subexpressions of expr.
5926 // * The expression expr binop x must be numerically equivalent to (expr)
5927 // binop x. This requirement is satisfied if the operators in expr have
5928 // precedence equal to or greater than binop, or by using parentheses around
5929 // expr or subexpressions of expr.
5930 // * For forms that allow multiple occurrences of x, the number of times
5931 // that x is evaluated is unspecified.
5932 if (AtomicKind == OMPC_read) {
5939 } ErrorFound = NoError;
5940 SourceLocation ErrorLoc, NoteLoc;
5941 SourceRange ErrorRange, NoteRange;
5942 // If clause is read:
5944 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5946 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5947 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5948 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5949 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5950 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5951 (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5952 if (!X->isLValue() || !V->isLValue()) {
5953 auto NotLValueExpr = X->isLValue() ? V : X;
5954 ErrorFound = NotAnLValue;
5955 ErrorLoc = AtomicBinOp->getExprLoc();
5956 ErrorRange = AtomicBinOp->getSourceRange();
5957 NoteLoc = NotLValueExpr->getExprLoc();
5958 NoteRange = NotLValueExpr->getSourceRange();
5960 } else if (!X->isInstantiationDependent() ||
5961 !V->isInstantiationDependent()) {
5962 auto NotScalarExpr =
5963 (X->isInstantiationDependent() || X->getType()->isScalarType())
5966 ErrorFound = NotAScalarType;
5967 ErrorLoc = AtomicBinOp->getExprLoc();
5968 ErrorRange = AtomicBinOp->getSourceRange();
5969 NoteLoc = NotScalarExpr->getExprLoc();
5970 NoteRange = NotScalarExpr->getSourceRange();
5972 } else if (!AtomicBody->isInstantiationDependent()) {
5973 ErrorFound = NotAnAssignmentOp;
5974 ErrorLoc = AtomicBody->getExprLoc();
5975 ErrorRange = AtomicBody->getSourceRange();
5976 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5977 : AtomicBody->getExprLoc();
5978 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5979 : AtomicBody->getSourceRange();
5982 ErrorFound = NotAnExpression;
5983 NoteLoc = ErrorLoc = Body->getLocStart();
5984 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5986 if (ErrorFound != NoError) {
5987 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5989 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5992 } else if (CurContext->isDependentContext())
5994 } else if (AtomicKind == OMPC_write) {
6001 } ErrorFound = NoError;
6002 SourceLocation ErrorLoc, NoteLoc;
6003 SourceRange ErrorRange, NoteRange;
6004 // If clause is write:
6006 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6008 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6009 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6010 X = AtomicBinOp->getLHS();
6011 E = AtomicBinOp->getRHS();
6012 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6013 (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6014 if (!X->isLValue()) {
6015 ErrorFound = NotAnLValue;
6016 ErrorLoc = AtomicBinOp->getExprLoc();
6017 ErrorRange = AtomicBinOp->getSourceRange();
6018 NoteLoc = X->getExprLoc();
6019 NoteRange = X->getSourceRange();
6021 } else if (!X->isInstantiationDependent() ||
6022 !E->isInstantiationDependent()) {
6023 auto NotScalarExpr =
6024 (X->isInstantiationDependent() || X->getType()->isScalarType())
6027 ErrorFound = NotAScalarType;
6028 ErrorLoc = AtomicBinOp->getExprLoc();
6029 ErrorRange = AtomicBinOp->getSourceRange();
6030 NoteLoc = NotScalarExpr->getExprLoc();
6031 NoteRange = NotScalarExpr->getSourceRange();
6033 } else if (!AtomicBody->isInstantiationDependent()) {
6034 ErrorFound = NotAnAssignmentOp;
6035 ErrorLoc = AtomicBody->getExprLoc();
6036 ErrorRange = AtomicBody->getSourceRange();
6037 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6038 : AtomicBody->getExprLoc();
6039 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6040 : AtomicBody->getSourceRange();
6043 ErrorFound = NotAnExpression;
6044 NoteLoc = ErrorLoc = Body->getLocStart();
6045 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6047 if (ErrorFound != NoError) {
6048 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6050 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6053 } else if (CurContext->isDependentContext())
6055 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6056 // If clause is update:
6062 // x = x binop expr;
6063 // x = expr binop x;
6064 OpenMPAtomicUpdateChecker Checker(*this);
6065 if (Checker.checkStatement(
6066 Body, (AtomicKind == OMPC_update)
6067 ? diag::err_omp_atomic_update_not_expression_statement
6068 : diag::err_omp_atomic_not_expression_statement,
6069 diag::note_omp_atomic_update))
6071 if (!CurContext->isDependentContext()) {
6072 E = Checker.getExpr();
6074 UE = Checker.getUpdateExpr();
6075 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6077 } else if (AtomicKind == OMPC_capture) {
6080 NotACompoundStatement,
6081 NotTwoSubstatements,
6082 NotASpecificExpression,
6084 } ErrorFound = NoError;
6085 SourceLocation ErrorLoc, NoteLoc;
6086 SourceRange ErrorRange, NoteRange;
6087 if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6088 // If clause is a capture:
6093 // v = x binop= expr;
6094 // v = x = x binop expr;
6095 // v = x = expr binop x;
6097 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6098 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6099 V = AtomicBinOp->getLHS();
6100 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6101 OpenMPAtomicUpdateChecker Checker(*this);
6102 if (Checker.checkStatement(
6103 Body, diag::err_omp_atomic_capture_not_expression_statement,
6104 diag::note_omp_atomic_update))
6106 E = Checker.getExpr();
6108 UE = Checker.getUpdateExpr();
6109 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6110 IsPostfixUpdate = Checker.isPostfixUpdate();
6111 } else if (!AtomicBody->isInstantiationDependent()) {
6112 ErrorLoc = AtomicBody->getExprLoc();
6113 ErrorRange = AtomicBody->getSourceRange();
6114 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6115 : AtomicBody->getExprLoc();
6116 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6117 : AtomicBody->getSourceRange();
6118 ErrorFound = NotAnAssignmentOp;
6120 if (ErrorFound != NoError) {
6121 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6123 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6125 } else if (CurContext->isDependentContext()) {
6126 UE = V = E = X = nullptr;
6129 // If clause is a capture:
6130 // { v = x; x = expr; }
6135 // { v = x; x binop= expr; }
6136 // { v = x; x = x binop expr; }
6137 // { v = x; x = expr binop x; }
6142 // { x binop= expr; v = x; }
6143 // { x = x binop expr; v = x; }
6144 // { x = expr binop x; v = x; }
6145 if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6146 // Check that this is { expr1; expr2; }
6147 if (CS->size() == 2) {
6148 auto *First = CS->body_front();
6149 auto *Second = CS->body_back();
6150 if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6151 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6152 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6153 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6154 // Need to find what subexpression is 'v' and what is 'x'.
6155 OpenMPAtomicUpdateChecker Checker(*this);
6156 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6157 BinaryOperator *BinOp = nullptr;
6158 if (IsUpdateExprFound) {
6159 BinOp = dyn_cast<BinaryOperator>(First);
6160 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6162 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6167 // { v = x; x binop= expr; }
6168 // { v = x; x = x binop expr; }
6169 // { v = x; x = expr binop x; }
6170 // Check that the first expression has form v = x.
6171 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6172 llvm::FoldingSetNodeID XId, PossibleXId;
6173 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6174 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6175 IsUpdateExprFound = XId == PossibleXId;
6176 if (IsUpdateExprFound) {
6177 V = BinOp->getLHS();
6179 E = Checker.getExpr();
6180 UE = Checker.getUpdateExpr();
6181 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6182 IsPostfixUpdate = true;
6185 if (!IsUpdateExprFound) {
6186 IsUpdateExprFound = !Checker.checkStatement(First);
6188 if (IsUpdateExprFound) {
6189 BinOp = dyn_cast<BinaryOperator>(Second);
6190 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6192 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6197 // { x binop= expr; v = x; }
6198 // { x = x binop expr; v = x; }
6199 // { x = expr binop x; v = x; }
6200 // Check that the second expression has form v = x.
6201 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6202 llvm::FoldingSetNodeID XId, PossibleXId;
6203 Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6204 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6205 IsUpdateExprFound = XId == PossibleXId;
6206 if (IsUpdateExprFound) {
6207 V = BinOp->getLHS();
6209 E = Checker.getExpr();
6210 UE = Checker.getUpdateExpr();
6211 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6212 IsPostfixUpdate = false;
6216 if (!IsUpdateExprFound) {
6217 // { v = x; x = expr; }
6218 auto *FirstExpr = dyn_cast<Expr>(First);
6219 auto *SecondExpr = dyn_cast<Expr>(Second);
6220 if (!FirstExpr || !SecondExpr ||
6221 !(FirstExpr->isInstantiationDependent() ||
6222 SecondExpr->isInstantiationDependent())) {
6223 auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6224 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6225 ErrorFound = NotAnAssignmentOp;
6226 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6227 : First->getLocStart();
6228 NoteRange = ErrorRange = FirstBinOp
6229 ? FirstBinOp->getSourceRange()
6230 : SourceRange(ErrorLoc, ErrorLoc);
6232 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6233 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6234 ErrorFound = NotAnAssignmentOp;
6235 NoteLoc = ErrorLoc = SecondBinOp
6236 ? SecondBinOp->getOperatorLoc()
6237 : Second->getLocStart();
6238 NoteRange = ErrorRange =
6239 SecondBinOp ? SecondBinOp->getSourceRange()
6240 : SourceRange(ErrorLoc, ErrorLoc);
6242 auto *PossibleXRHSInFirst =
6243 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6244 auto *PossibleXLHSInSecond =
6245 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6246 llvm::FoldingSetNodeID X1Id, X2Id;
6247 PossibleXRHSInFirst->Profile(X1Id, Context,
6248 /*Canonical=*/true);
6249 PossibleXLHSInSecond->Profile(X2Id, Context,
6250 /*Canonical=*/true);
6251 IsUpdateExprFound = X1Id == X2Id;
6252 if (IsUpdateExprFound) {
6253 V = FirstBinOp->getLHS();
6254 X = SecondBinOp->getLHS();
6255 E = SecondBinOp->getRHS();
6257 IsXLHSInRHSPart = false;
6258 IsPostfixUpdate = true;
6260 ErrorFound = NotASpecificExpression;
6261 ErrorLoc = FirstBinOp->getExprLoc();
6262 ErrorRange = FirstBinOp->getSourceRange();
6263 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6264 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6271 NoteLoc = ErrorLoc = Body->getLocStart();
6272 NoteRange = ErrorRange =
6273 SourceRange(Body->getLocStart(), Body->getLocStart());
6274 ErrorFound = NotTwoSubstatements;
6277 NoteLoc = ErrorLoc = Body->getLocStart();
6278 NoteRange = ErrorRange =
6279 SourceRange(Body->getLocStart(), Body->getLocStart());
6280 ErrorFound = NotACompoundStatement;
6282 if (ErrorFound != NoError) {
6283 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6285 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6287 } else if (CurContext->isDependentContext()) {
6288 UE = V = E = X = nullptr;
6293 getCurFunction()->setHasBranchProtectedScope();
6295 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6296 X, V, E, UE, IsXLHSInRHSPart,
6300 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
6302 SourceLocation StartLoc,
6303 SourceLocation EndLoc) {
6307 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6308 // 1.2.2 OpenMP Language Terminology
6309 // Structured block - An executable statement with a single entry at the
6310 // top and a single exit at the bottom.
6311 // The point of exit cannot be a branch out of the structured block.
6312 // longjmp() and throw() must not violate the entry/exit criteria.
6313 CS->getCapturedDecl()->setNothrow();
6315 // OpenMP [2.16, Nesting of Regions]
6316 // If specified, a teams construct must be contained within a target
6317 // construct. That target construct must contain no statements or directives
6318 // outside of the teams construct.
6319 if (DSAStack->hasInnerTeamsRegion()) {
6320 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
6321 bool OMPTeamsFound = true;
6322 if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6323 auto I = CS->body_begin();
6324 while (I != CS->body_end()) {
6325 auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6326 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6327 OMPTeamsFound = false;
6332 assert(I != CS->body_end() && "Not found statement");
6335 auto *OED = dyn_cast<OMPExecutableDirective>(S);
6336 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6338 if (!OMPTeamsFound) {
6339 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6340 Diag(DSAStack->getInnerTeamsRegionLoc(),
6341 diag::note_omp_nested_teams_construct_here);
6342 Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6343 << isa<OMPExecutableDirective>(S);
6348 getCurFunction()->setHasBranchProtectedScope();
6350 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6354 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
6355 Stmt *AStmt, SourceLocation StartLoc,
6356 SourceLocation EndLoc) {
6360 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6361 // 1.2.2 OpenMP Language Terminology
6362 // Structured block - An executable statement with a single entry at the
6363 // top and a single exit at the bottom.
6364 // The point of exit cannot be a branch out of the structured block.
6365 // longjmp() and throw() must not violate the entry/exit criteria.
6366 CS->getCapturedDecl()->setNothrow();
6368 getCurFunction()->setHasBranchProtectedScope();
6370 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6374 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
6375 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6376 SourceLocation EndLoc,
6377 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6381 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6382 // 1.2.2 OpenMP Language Terminology
6383 // Structured block - An executable statement with a single entry at the
6384 // top and a single exit at the bottom.
6385 // The point of exit cannot be a branch out of the structured block.
6386 // longjmp() and throw() must not violate the entry/exit criteria.
6387 CS->getCapturedDecl()->setNothrow();
6388 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6389 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6390 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6399 OMPLoopDirective::HelperExprs B;
6400 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6401 // define the nested loops number.
6402 unsigned NestedLoopCount =
6403 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6404 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6405 VarsWithImplicitDSA, B);
6406 if (NestedLoopCount == 0)
6409 assert((CurContext->isDependentContext() || B.builtAll()) &&
6410 "omp target parallel for loop exprs were not built");
6412 if (!CurContext->isDependentContext()) {
6413 // Finalize the clauses that need pre-built expressions for CodeGen.
6414 for (auto C : Clauses) {
6415 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6416 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6417 B.NumIterations, *this, CurScope,
6423 getCurFunction()->setHasBranchProtectedScope();
6424 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6425 NestedLoopCount, Clauses, AStmt,
6426 B, DSAStack->isCancelRegion());
6429 /// Check for existence of a map clause in the list of clauses.
6430 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6431 const OpenMPClauseKind K) {
6432 return llvm::any_of(
6433 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6436 template <typename... Params>
6437 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
6438 const Params... ClauseTypes) {
6439 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6442 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
6444 SourceLocation StartLoc,
6445 SourceLocation EndLoc) {
6449 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6451 // OpenMP [2.10.1, Restrictions, p. 97]
6452 // At least one map clause must appear on the directive.
6453 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6454 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6455 << "'map' or 'use_device_ptr'"
6456 << getOpenMPDirectiveName(OMPD_target_data);
6460 getCurFunction()->setHasBranchProtectedScope();
6462 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6467 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
6468 SourceLocation StartLoc,
6469 SourceLocation EndLoc, Stmt *AStmt) {
6473 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6474 // 1.2.2 OpenMP Language Terminology
6475 // Structured block - An executable statement with a single entry at the
6476 // top and a single exit at the bottom.
6477 // The point of exit cannot be a branch out of the structured block.
6478 // longjmp() and throw() must not violate the entry/exit criteria.
6479 CS->getCapturedDecl()->setNothrow();
6480 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6481 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6482 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6491 // OpenMP [2.10.2, Restrictions, p. 99]
6492 // At least one map clause must appear on the directive.
6493 if (!hasClauses(Clauses, OMPC_map)) {
6494 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6495 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6499 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6504 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
6505 SourceLocation StartLoc,
6506 SourceLocation EndLoc, Stmt *AStmt) {
6510 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6511 // 1.2.2 OpenMP Language Terminology
6512 // Structured block - An executable statement with a single entry at the
6513 // top and a single exit at the bottom.
6514 // The point of exit cannot be a branch out of the structured block.
6515 // longjmp() and throw() must not violate the entry/exit criteria.
6516 CS->getCapturedDecl()->setNothrow();
6517 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6518 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6519 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6528 // OpenMP [2.10.3, Restrictions, p. 102]
6529 // At least one map clause must appear on the directive.
6530 if (!hasClauses(Clauses, OMPC_map)) {
6531 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6532 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6536 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6540 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
6541 SourceLocation StartLoc,
6542 SourceLocation EndLoc,
6547 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6548 // 1.2.2 OpenMP Language Terminology
6549 // Structured block - An executable statement with a single entry at the
6550 // top and a single exit at the bottom.
6551 // The point of exit cannot be a branch out of the structured block.
6552 // longjmp() and throw() must not violate the entry/exit criteria.
6553 CS->getCapturedDecl()->setNothrow();
6554 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6555 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6556 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6565 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6566 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6569 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6573 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
6574 Stmt *AStmt, SourceLocation StartLoc,
6575 SourceLocation EndLoc) {
6579 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6580 // 1.2.2 OpenMP Language Terminology
6581 // Structured block - An executable statement with a single entry at the
6582 // top and a single exit at the bottom.
6583 // The point of exit cannot be a branch out of the structured block.
6584 // longjmp() and throw() must not violate the entry/exit criteria.
6585 CS->getCapturedDecl()->setNothrow();
6587 getCurFunction()->setHasBranchProtectedScope();
6589 DSAStack->setParentTeamsRegionLoc(StartLoc);
6591 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6595 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
6596 SourceLocation EndLoc,
6597 OpenMPDirectiveKind CancelRegion) {
6598 if (DSAStack->isParentNowaitRegion()) {
6599 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6602 if (DSAStack->isParentOrderedRegion()) {
6603 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6606 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6610 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
6611 SourceLocation StartLoc,
6612 SourceLocation EndLoc,
6613 OpenMPDirectiveKind CancelRegion) {
6614 if (DSAStack->isParentNowaitRegion()) {
6615 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6618 if (DSAStack->isParentOrderedRegion()) {
6619 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6622 DSAStack->setParentCancelRegion(/*Cancel=*/true);
6623 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6627 static bool checkGrainsizeNumTasksClauses(Sema &S,
6628 ArrayRef<OMPClause *> Clauses) {
6629 OMPClause *PrevClause = nullptr;
6630 bool ErrorFound = false;
6631 for (auto *C : Clauses) {
6632 if (C->getClauseKind() == OMPC_grainsize ||
6633 C->getClauseKind() == OMPC_num_tasks) {
6636 else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6637 S.Diag(C->getLocStart(),
6638 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6639 << getOpenMPClauseName(C->getClauseKind())
6640 << getOpenMPClauseName(PrevClause->getClauseKind());
6641 S.Diag(PrevClause->getLocStart(),
6642 diag::note_omp_previous_grainsize_num_tasks)
6643 << getOpenMPClauseName(PrevClause->getClauseKind());
6651 static bool checkReductionClauseWithNogroup(Sema &S,
6652 ArrayRef<OMPClause *> Clauses) {
6653 OMPClause *ReductionClause = nullptr;
6654 OMPClause *NogroupClause = nullptr;
6655 for (auto *C : Clauses) {
6656 if (C->getClauseKind() == OMPC_reduction) {
6657 ReductionClause = C;
6662 if (C->getClauseKind() == OMPC_nogroup) {
6664 if (ReductionClause)
6669 if (ReductionClause && NogroupClause) {
6670 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
6671 << SourceRange(NogroupClause->getLocStart(),
6672 NogroupClause->getLocEnd());
6678 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
6679 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6680 SourceLocation EndLoc,
6681 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6685 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6686 OMPLoopDirective::HelperExprs B;
6687 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6688 // define the nested loops number.
6689 unsigned NestedLoopCount =
6690 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6691 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6692 VarsWithImplicitDSA, B);
6693 if (NestedLoopCount == 0)
6696 assert((CurContext->isDependentContext() || B.builtAll()) &&
6697 "omp for loop exprs were not built");
6699 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6700 // The grainsize clause and num_tasks clause are mutually exclusive and may
6701 // not appear on the same taskloop directive.
6702 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6704 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6705 // If a reduction clause is present on the taskloop directive, the nogroup
6706 // clause must not be specified.
6707 if (checkReductionClauseWithNogroup(*this, Clauses))
6710 getCurFunction()->setHasBranchProtectedScope();
6711 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6712 NestedLoopCount, Clauses, AStmt, B);
6715 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
6716 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6717 SourceLocation EndLoc,
6718 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6722 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6723 OMPLoopDirective::HelperExprs B;
6724 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6725 // define the nested loops number.
6726 unsigned NestedLoopCount =
6727 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
6728 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6729 VarsWithImplicitDSA, B);
6730 if (NestedLoopCount == 0)
6733 assert((CurContext->isDependentContext() || B.builtAll()) &&
6734 "omp for loop exprs were not built");
6736 if (!CurContext->isDependentContext()) {
6737 // Finalize the clauses that need pre-built expressions for CodeGen.
6738 for (auto C : Clauses) {
6739 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6740 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6741 B.NumIterations, *this, CurScope,
6747 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6748 // The grainsize clause and num_tasks clause are mutually exclusive and may
6749 // not appear on the same taskloop directive.
6750 if (checkGrainsizeNumTasksClauses(*this, Clauses))
6752 // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6753 // If a reduction clause is present on the taskloop directive, the nogroup
6754 // clause must not be specified.
6755 if (checkReductionClauseWithNogroup(*this, Clauses))
6757 if (checkSimdlenSafelenSpecified(*this, Clauses))
6760 getCurFunction()->setHasBranchProtectedScope();
6761 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
6762 NestedLoopCount, Clauses, AStmt, B);
6765 StmtResult Sema::ActOnOpenMPDistributeDirective(
6766 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6767 SourceLocation EndLoc,
6768 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6772 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6773 OMPLoopDirective::HelperExprs B;
6774 // In presence of clause 'collapse' with number of loops, it will
6775 // define the nested loops number.
6776 unsigned NestedLoopCount =
6777 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
6778 nullptr /*ordered not a clause on distribute*/, AStmt,
6779 *this, *DSAStack, VarsWithImplicitDSA, B);
6780 if (NestedLoopCount == 0)
6783 assert((CurContext->isDependentContext() || B.builtAll()) &&
6784 "omp for loop exprs were not built");
6786 getCurFunction()->setHasBranchProtectedScope();
6787 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
6788 NestedLoopCount, Clauses, AStmt, B);
6791 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
6792 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6793 SourceLocation EndLoc,
6794 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6798 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6799 // 1.2.2 OpenMP Language Terminology
6800 // Structured block - An executable statement with a single entry at the
6801 // top and a single exit at the bottom.
6802 // The point of exit cannot be a branch out of the structured block.
6803 // longjmp() and throw() must not violate the entry/exit criteria.
6804 CS->getCapturedDecl()->setNothrow();
6805 for (int ThisCaptureLevel =
6806 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6807 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6808 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6809 // 1.2.2 OpenMP Language Terminology
6810 // Structured block - An executable statement with a single entry at the
6811 // top and a single exit at the bottom.
6812 // The point of exit cannot be a branch out of the structured block.
6813 // longjmp() and throw() must not violate the entry/exit criteria.
6814 CS->getCapturedDecl()->setNothrow();
6817 OMPLoopDirective::HelperExprs B;
6818 // In presence of clause 'collapse' with number of loops, it will
6819 // define the nested loops number.
6820 unsigned NestedLoopCount = CheckOpenMPLoop(
6821 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
6822 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6823 VarsWithImplicitDSA, B);
6824 if (NestedLoopCount == 0)
6827 assert((CurContext->isDependentContext() || B.builtAll()) &&
6828 "omp for loop exprs were not built");
6830 getCurFunction()->setHasBranchProtectedScope();
6831 return OMPDistributeParallelForDirective::Create(
6832 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6833 DSAStack->isCancelRegion());
6836 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
6837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6838 SourceLocation EndLoc,
6839 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6843 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6844 // 1.2.2 OpenMP Language Terminology
6845 // Structured block - An executable statement with a single entry at the
6846 // top and a single exit at the bottom.
6847 // The point of exit cannot be a branch out of the structured block.
6848 // longjmp() and throw() must not violate the entry/exit criteria.
6849 CS->getCapturedDecl()->setNothrow();
6850 for (int ThisCaptureLevel =
6851 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6852 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6853 CS = cast<CapturedStmt>(CS->getCapturedStmt());
6854 // 1.2.2 OpenMP Language Terminology
6855 // Structured block - An executable statement with a single entry at the
6856 // top and a single exit at the bottom.
6857 // The point of exit cannot be a branch out of the structured block.
6858 // longjmp() and throw() must not violate the entry/exit criteria.
6859 CS->getCapturedDecl()->setNothrow();
6862 OMPLoopDirective::HelperExprs B;
6863 // In presence of clause 'collapse' with number of loops, it will
6864 // define the nested loops number.
6865 unsigned NestedLoopCount = CheckOpenMPLoop(
6866 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
6867 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6868 VarsWithImplicitDSA, B);
6869 if (NestedLoopCount == 0)
6872 assert((CurContext->isDependentContext() || B.builtAll()) &&
6873 "omp for loop exprs were not built");
6875 if (!CurContext->isDependentContext()) {
6876 // Finalize the clauses that need pre-built expressions for CodeGen.
6877 for (auto C : Clauses) {
6878 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6879 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6880 B.NumIterations, *this, CurScope,
6886 if (checkSimdlenSafelenSpecified(*this, Clauses))
6889 getCurFunction()->setHasBranchProtectedScope();
6890 return OMPDistributeParallelForSimdDirective::Create(
6891 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6894 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
6895 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6896 SourceLocation EndLoc,
6897 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6901 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6902 // 1.2.2 OpenMP Language Terminology
6903 // Structured block - An executable statement with a single entry at the
6904 // top and a single exit at the bottom.
6905 // The point of exit cannot be a branch out of the structured block.
6906 // longjmp() and throw() must not violate the entry/exit criteria.
6907 CS->getCapturedDecl()->setNothrow();
6908 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
6909 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6910 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6919 OMPLoopDirective::HelperExprs B;
6920 // In presence of clause 'collapse' with number of loops, it will
6921 // define the nested loops number.
6922 unsigned NestedLoopCount =
6923 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
6924 nullptr /*ordered not a clause on distribute*/, CS, *this,
6925 *DSAStack, VarsWithImplicitDSA, B);
6926 if (NestedLoopCount == 0)
6929 assert((CurContext->isDependentContext() || B.builtAll()) &&
6930 "omp for loop exprs were not built");
6932 if (!CurContext->isDependentContext()) {
6933 // Finalize the clauses that need pre-built expressions for CodeGen.
6934 for (auto C : Clauses) {
6935 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6936 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6937 B.NumIterations, *this, CurScope,
6943 if (checkSimdlenSafelenSpecified(*this, Clauses))
6946 getCurFunction()->setHasBranchProtectedScope();
6947 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
6948 NestedLoopCount, Clauses, AStmt, B);
6951 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
6952 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6953 SourceLocation EndLoc,
6954 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6958 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6959 // 1.2.2 OpenMP Language Terminology
6960 // Structured block - An executable statement with a single entry at the
6961 // top and a single exit at the bottom.
6962 // The point of exit cannot be a branch out of the structured block.
6963 // longjmp() and throw() must not violate the entry/exit criteria.
6964 CS->getCapturedDecl()->setNothrow();
6965 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6966 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6967 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
6976 OMPLoopDirective::HelperExprs B;
6977 // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6978 // define the nested loops number.
6979 unsigned NestedLoopCount = CheckOpenMPLoop(
6980 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
6981 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6982 VarsWithImplicitDSA, B);
6983 if (NestedLoopCount == 0)
6986 assert((CurContext->isDependentContext() || B.builtAll()) &&
6987 "omp target parallel for simd loop exprs were not built");
6989 if (!CurContext->isDependentContext()) {
6990 // Finalize the clauses that need pre-built expressions for CodeGen.
6991 for (auto C : Clauses) {
6992 if (auto *LC = dyn_cast<OMPLinearClause>(C))
6993 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6994 B.NumIterations, *this, CurScope,
6999 if (checkSimdlenSafelenSpecified(*this, Clauses))
7002 getCurFunction()->setHasBranchProtectedScope();
7003 return OMPTargetParallelForSimdDirective::Create(
7004 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7007 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
7008 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7009 SourceLocation EndLoc,
7010 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7014 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7015 // 1.2.2 OpenMP Language Terminology
7016 // Structured block - An executable statement with a single entry at the
7017 // top and a single exit at the bottom.
7018 // The point of exit cannot be a branch out of the structured block.
7019 // longjmp() and throw() must not violate the entry/exit criteria.
7020 CS->getCapturedDecl()->setNothrow();
7021 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7022 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7023 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
7032 OMPLoopDirective::HelperExprs B;
7033 // In presence of clause 'collapse' with number of loops, it will define the
7034 // nested loops number.
7035 unsigned NestedLoopCount =
7036 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7037 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7038 VarsWithImplicitDSA, B);
7039 if (NestedLoopCount == 0)
7042 assert((CurContext->isDependentContext() || B.builtAll()) &&
7043 "omp target simd loop exprs were not built");
7045 if (!CurContext->isDependentContext()) {
7046 // Finalize the clauses that need pre-built expressions for CodeGen.
7047 for (auto C : Clauses) {
7048 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7049 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7050 B.NumIterations, *this, CurScope,
7056 if (checkSimdlenSafelenSpecified(*this, Clauses))
7059 getCurFunction()->setHasBranchProtectedScope();
7060 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7061 NestedLoopCount, Clauses, AStmt, B);
7064 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
7065 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7066 SourceLocation EndLoc,
7067 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7071 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7072 // 1.2.2 OpenMP Language Terminology
7073 // Structured block - An executable statement with a single entry at the
7074 // top and a single exit at the bottom.
7075 // The point of exit cannot be a branch out of the structured block.
7076 // longjmp() and throw() must not violate the entry/exit criteria.
7077 CS->getCapturedDecl()->setNothrow();
7078 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7079 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7080 CS = cast<CapturedStmt>(CS->getCapturedStmt());
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();
7089 OMPLoopDirective::HelperExprs B;
7090 // In presence of clause 'collapse' with number of loops, it will
7091 // define the nested loops number.
7092 unsigned NestedLoopCount =
7093 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7094 nullptr /*ordered not a clause on distribute*/, CS, *this,
7095 *DSAStack, VarsWithImplicitDSA, B);
7096 if (NestedLoopCount == 0)
7099 assert((CurContext->isDependentContext() || B.builtAll()) &&
7100 "omp teams distribute loop exprs were not built");
7102 getCurFunction()->setHasBranchProtectedScope();
7104 DSAStack->setParentTeamsRegionLoc(StartLoc);
7106 return OMPTeamsDistributeDirective::Create(
7107 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7110 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
7111 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7112 SourceLocation EndLoc,
7113 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7117 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7118 // 1.2.2 OpenMP Language Terminology
7119 // Structured block - An executable statement with a single entry at the
7120 // top and a single exit at the bottom.
7121 // The point of exit cannot be a branch out of the structured block.
7122 // longjmp() and throw() must not violate the entry/exit criteria.
7123 CS->getCapturedDecl()->setNothrow();
7124 for (int ThisCaptureLevel =
7125 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7126 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7127 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7128 // 1.2.2 OpenMP Language Terminology
7129 // Structured block - An executable statement with a single entry at the
7130 // top and a single exit at the bottom.
7131 // The point of exit cannot be a branch out of the structured block.
7132 // longjmp() and throw() must not violate the entry/exit criteria.
7133 CS->getCapturedDecl()->setNothrow();
7137 OMPLoopDirective::HelperExprs B;
7138 // In presence of clause 'collapse' with number of loops, it will
7139 // define the nested loops number.
7140 unsigned NestedLoopCount = CheckOpenMPLoop(
7141 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7142 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7143 VarsWithImplicitDSA, B);
7145 if (NestedLoopCount == 0)
7148 assert((CurContext->isDependentContext() || B.builtAll()) &&
7149 "omp teams distribute simd loop exprs were not built");
7151 if (!CurContext->isDependentContext()) {
7152 // Finalize the clauses that need pre-built expressions for CodeGen.
7153 for (auto C : Clauses) {
7154 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7155 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7156 B.NumIterations, *this, CurScope,
7162 if (checkSimdlenSafelenSpecified(*this, Clauses))
7165 getCurFunction()->setHasBranchProtectedScope();
7167 DSAStack->setParentTeamsRegionLoc(StartLoc);
7169 return OMPTeamsDistributeSimdDirective::Create(
7170 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7173 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
7174 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7175 SourceLocation EndLoc,
7176 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7180 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7181 // 1.2.2 OpenMP Language Terminology
7182 // Structured block - An executable statement with a single entry at the
7183 // top and a single exit at the bottom.
7184 // The point of exit cannot be a branch out of the structured block.
7185 // longjmp() and throw() must not violate the entry/exit criteria.
7186 CS->getCapturedDecl()->setNothrow();
7188 for (int ThisCaptureLevel =
7189 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7190 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7191 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7192 // 1.2.2 OpenMP Language Terminology
7193 // Structured block - An executable statement with a single entry at the
7194 // top and a single exit at the bottom.
7195 // The point of exit cannot be a branch out of the structured block.
7196 // longjmp() and throw() must not violate the entry/exit criteria.
7197 CS->getCapturedDecl()->setNothrow();
7200 OMPLoopDirective::HelperExprs B;
7201 // In presence of clause 'collapse' with number of loops, it will
7202 // define the nested loops number.
7203 auto NestedLoopCount = CheckOpenMPLoop(
7204 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7205 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7206 VarsWithImplicitDSA, B);
7208 if (NestedLoopCount == 0)
7211 assert((CurContext->isDependentContext() || B.builtAll()) &&
7212 "omp for loop exprs were not built");
7214 if (!CurContext->isDependentContext()) {
7215 // Finalize the clauses that need pre-built expressions for CodeGen.
7216 for (auto C : Clauses) {
7217 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7218 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7219 B.NumIterations, *this, CurScope,
7225 if (checkSimdlenSafelenSpecified(*this, Clauses))
7228 getCurFunction()->setHasBranchProtectedScope();
7230 DSAStack->setParentTeamsRegionLoc(StartLoc);
7232 return OMPTeamsDistributeParallelForSimdDirective::Create(
7233 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7236 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
7237 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7238 SourceLocation EndLoc,
7239 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7243 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7244 // 1.2.2 OpenMP Language Terminology
7245 // Structured block - An executable statement with a single entry at the
7246 // top and a single exit at the bottom.
7247 // The point of exit cannot be a branch out of the structured block.
7248 // longjmp() and throw() must not violate the entry/exit criteria.
7249 CS->getCapturedDecl()->setNothrow();
7251 for (int ThisCaptureLevel =
7252 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7253 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7254 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7255 // 1.2.2 OpenMP Language Terminology
7256 // Structured block - An executable statement with a single entry at the
7257 // top and a single exit at the bottom.
7258 // The point of exit cannot be a branch out of the structured block.
7259 // longjmp() and throw() must not violate the entry/exit criteria.
7260 CS->getCapturedDecl()->setNothrow();
7263 OMPLoopDirective::HelperExprs B;
7264 // In presence of clause 'collapse' with number of loops, it will
7265 // define the nested loops number.
7266 unsigned NestedLoopCount = CheckOpenMPLoop(
7267 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7268 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7269 VarsWithImplicitDSA, B);
7271 if (NestedLoopCount == 0)
7274 assert((CurContext->isDependentContext() || B.builtAll()) &&
7275 "omp for loop exprs were not built");
7277 getCurFunction()->setHasBranchProtectedScope();
7279 DSAStack->setParentTeamsRegionLoc(StartLoc);
7281 return OMPTeamsDistributeParallelForDirective::Create(
7282 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7283 DSAStack->isCancelRegion());
7286 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
7288 SourceLocation StartLoc,
7289 SourceLocation EndLoc) {
7293 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7294 // 1.2.2 OpenMP Language Terminology
7295 // Structured block - An executable statement with a single entry at the
7296 // top and a single exit at the bottom.
7297 // The point of exit cannot be a branch out of the structured block.
7298 // longjmp() and throw() must not violate the entry/exit criteria.
7299 CS->getCapturedDecl()->setNothrow();
7301 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7302 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7303 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7304 // 1.2.2 OpenMP Language Terminology
7305 // Structured block - An executable statement with a single entry at the
7306 // top and a single exit at the bottom.
7307 // The point of exit cannot be a branch out of the structured block.
7308 // longjmp() and throw() must not violate the entry/exit criteria.
7309 CS->getCapturedDecl()->setNothrow();
7311 getCurFunction()->setHasBranchProtectedScope();
7313 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7317 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
7318 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7319 SourceLocation EndLoc,
7320 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7324 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7325 // 1.2.2 OpenMP Language Terminology
7326 // Structured block - An executable statement with a single entry at the
7327 // top and a single exit at the bottom.
7328 // The point of exit cannot be a branch out of the structured block.
7329 // longjmp() and throw() must not violate the entry/exit criteria.
7330 CS->getCapturedDecl()->setNothrow();
7331 for (int ThisCaptureLevel =
7332 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7333 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7334 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7335 // 1.2.2 OpenMP Language Terminology
7336 // Structured block - An executable statement with a single entry at the
7337 // top and a single exit at the bottom.
7338 // The point of exit cannot be a branch out of the structured block.
7339 // longjmp() and throw() must not violate the entry/exit criteria.
7340 CS->getCapturedDecl()->setNothrow();
7343 OMPLoopDirective::HelperExprs B;
7344 // In presence of clause 'collapse' with number of loops, it will
7345 // define the nested loops number.
7346 auto NestedLoopCount = CheckOpenMPLoop(
7347 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7348 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7349 VarsWithImplicitDSA, B);
7350 if (NestedLoopCount == 0)
7353 assert((CurContext->isDependentContext() || B.builtAll()) &&
7354 "omp target teams distribute loop exprs were not built");
7356 getCurFunction()->setHasBranchProtectedScope();
7357 return OMPTargetTeamsDistributeDirective::Create(
7358 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7361 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
7362 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7363 SourceLocation EndLoc,
7364 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7368 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7369 // 1.2.2 OpenMP Language Terminology
7370 // Structured block - An executable statement with a single entry at the
7371 // top and a single exit at the bottom.
7372 // The point of exit cannot be a branch out of the structured block.
7373 // longjmp() and throw() must not violate the entry/exit criteria.
7374 CS->getCapturedDecl()->setNothrow();
7376 OMPLoopDirective::HelperExprs B;
7377 // In presence of clause 'collapse' with number of loops, it will
7378 // define the nested loops number.
7379 auto NestedLoopCount = CheckOpenMPLoop(
7380 OMPD_target_teams_distribute_parallel_for,
7381 getCollapseNumberExpr(Clauses),
7382 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7383 VarsWithImplicitDSA, B);
7384 if (NestedLoopCount == 0)
7387 assert((CurContext->isDependentContext() || B.builtAll()) &&
7388 "omp target teams distribute parallel for loop exprs were not built");
7390 getCurFunction()->setHasBranchProtectedScope();
7391 return OMPTargetTeamsDistributeParallelForDirective::Create(
7392 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7393 DSAStack->isCancelRegion());
7396 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
7397 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7398 SourceLocation EndLoc,
7399 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7403 CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7404 // 1.2.2 OpenMP Language Terminology
7405 // Structured block - An executable statement with a single entry at the
7406 // top and a single exit at the bottom.
7407 // The point of exit cannot be a branch out of the structured block.
7408 // longjmp() and throw() must not violate the entry/exit criteria.
7409 CS->getCapturedDecl()->setNothrow();
7411 OMPLoopDirective::HelperExprs B;
7412 // In presence of clause 'collapse' with number of loops, it will
7413 // define the nested loops number.
7414 auto NestedLoopCount = CheckOpenMPLoop(
7415 OMPD_target_teams_distribute_parallel_for_simd,
7416 getCollapseNumberExpr(Clauses),
7417 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7418 VarsWithImplicitDSA, B);
7419 if (NestedLoopCount == 0)
7422 assert((CurContext->isDependentContext() || B.builtAll()) &&
7423 "omp target teams distribute parallel for simd loop exprs were not "
7426 if (!CurContext->isDependentContext()) {
7427 // Finalize the clauses that need pre-built expressions for CodeGen.
7428 for (auto C : Clauses) {
7429 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7430 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7431 B.NumIterations, *this, CurScope,
7437 if (checkSimdlenSafelenSpecified(*this, Clauses))
7440 getCurFunction()->setHasBranchProtectedScope();
7441 return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
7442 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7445 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
7446 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7447 SourceLocation EndLoc,
7448 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7452 auto *CS = cast<CapturedStmt>(AStmt);
7453 // 1.2.2 OpenMP Language Terminology
7454 // Structured block - An executable statement with a single entry at the
7455 // top and a single exit at the bottom.
7456 // The point of exit cannot be a branch out of the structured block.
7457 // longjmp() and throw() must not violate the entry/exit criteria.
7458 CS->getCapturedDecl()->setNothrow();
7459 for (int ThisCaptureLevel =
7460 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7461 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7462 CS = cast<CapturedStmt>(CS->getCapturedStmt());
7463 // 1.2.2 OpenMP Language Terminology
7464 // Structured block - An executable statement with a single entry at the
7465 // top and a single exit at the bottom.
7466 // The point of exit cannot be a branch out of the structured block.
7467 // longjmp() and throw() must not violate the entry/exit criteria.
7468 CS->getCapturedDecl()->setNothrow();
7471 OMPLoopDirective::HelperExprs B;
7472 // In presence of clause 'collapse' with number of loops, it will
7473 // define the nested loops number.
7474 auto NestedLoopCount = CheckOpenMPLoop(
7475 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7476 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7477 VarsWithImplicitDSA, B);
7478 if (NestedLoopCount == 0)
7481 assert((CurContext->isDependentContext() || B.builtAll()) &&
7482 "omp target teams distribute simd loop exprs were not built");
7484 if (!CurContext->isDependentContext()) {
7485 // Finalize the clauses that need pre-built expressions for CodeGen.
7486 for (auto C : Clauses) {
7487 if (auto *LC = dyn_cast<OMPLinearClause>(C))
7488 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7489 B.NumIterations, *this, CurScope,
7495 if (checkSimdlenSafelenSpecified(*this, Clauses))
7498 getCurFunction()->setHasBranchProtectedScope();
7499 return OMPTargetTeamsDistributeSimdDirective::Create(
7500 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7503 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
7504 SourceLocation StartLoc,
7505 SourceLocation LParenLoc,
7506 SourceLocation EndLoc) {
7507 OMPClause *Res = nullptr;
7510 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7512 case OMPC_num_threads:
7513 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7516 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7519 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7522 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7525 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7528 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7530 case OMPC_num_teams:
7531 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7533 case OMPC_thread_limit:
7534 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7537 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7539 case OMPC_grainsize:
7540 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7542 case OMPC_num_tasks:
7543 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7546 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7550 case OMPC_proc_bind:
7553 case OMPC_firstprivate:
7554 case OMPC_lastprivate:
7556 case OMPC_reduction:
7557 case OMPC_task_reduction:
7558 case OMPC_in_reduction:
7562 case OMPC_copyprivate:
7565 case OMPC_mergeable:
7566 case OMPC_threadprivate:
7578 case OMPC_dist_schedule:
7579 case OMPC_defaultmap:
7584 case OMPC_use_device_ptr:
7585 case OMPC_is_device_ptr:
7586 llvm_unreachable("Clause is not allowed.");
7591 // An OpenMP directive such as 'target parallel' has two captured regions:
7592 // for the 'target' and 'parallel' respectively. This function returns
7593 // the region in which to capture expressions associated with a clause.
7594 // A return value of OMPD_unknown signifies that the expression should not
7596 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
7597 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
7598 OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7599 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7603 case OMPD_target_parallel:
7604 case OMPD_target_parallel_for:
7605 case OMPD_target_parallel_for_simd:
7606 case OMPD_target_teams_distribute_parallel_for:
7607 case OMPD_target_teams_distribute_parallel_for_simd:
7608 // If this clause applies to the nested 'parallel' region, capture within
7609 // the 'target' region, otherwise do not capture.
7610 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7611 CaptureRegion = OMPD_target;
7613 case OMPD_teams_distribute_parallel_for:
7614 case OMPD_teams_distribute_parallel_for_simd:
7615 CaptureRegion = OMPD_teams;
7619 case OMPD_parallel_sections:
7620 case OMPD_parallel_for:
7621 case OMPD_parallel_for_simd:
7623 case OMPD_target_simd:
7624 case OMPD_target_teams:
7625 case OMPD_target_teams_distribute:
7626 case OMPD_target_teams_distribute_simd:
7627 case OMPD_distribute_parallel_for:
7628 case OMPD_distribute_parallel_for_simd:
7631 case OMPD_taskloop_simd:
7632 case OMPD_target_data:
7633 case OMPD_target_enter_data:
7634 case OMPD_target_exit_data:
7635 case OMPD_target_update:
7636 // Do not capture if-clause expressions.
7638 case OMPD_threadprivate:
7639 case OMPD_taskyield:
7642 case OMPD_cancellation_point:
7644 case OMPD_declare_reduction:
7645 case OMPD_declare_simd:
7646 case OMPD_declare_target:
7647 case OMPD_end_declare_target:
7657 case OMPD_taskgroup:
7658 case OMPD_distribute:
7661 case OMPD_distribute_simd:
7662 case OMPD_teams_distribute:
7663 case OMPD_teams_distribute_simd:
7664 llvm_unreachable("Unexpected OpenMP directive with if-clause");
7666 llvm_unreachable("Unknown OpenMP directive");
7669 case OMPC_num_threads:
7671 case OMPD_target_parallel:
7672 case OMPD_target_parallel_for:
7673 case OMPD_target_parallel_for_simd:
7674 case OMPD_target_teams_distribute_parallel_for:
7675 case OMPD_target_teams_distribute_parallel_for_simd:
7676 CaptureRegion = OMPD_target;
7678 case OMPD_teams_distribute_parallel_for:
7679 case OMPD_teams_distribute_parallel_for_simd:
7680 CaptureRegion = OMPD_teams;
7683 case OMPD_parallel_sections:
7684 case OMPD_parallel_for:
7685 case OMPD_parallel_for_simd:
7686 case OMPD_distribute_parallel_for:
7687 case OMPD_distribute_parallel_for_simd:
7688 // Do not capture num_threads-clause expressions.
7690 case OMPD_target_data:
7691 case OMPD_target_enter_data:
7692 case OMPD_target_exit_data:
7693 case OMPD_target_update:
7695 case OMPD_target_simd:
7696 case OMPD_target_teams:
7697 case OMPD_target_teams_distribute:
7698 case OMPD_target_teams_distribute_simd:
7702 case OMPD_taskloop_simd:
7703 case OMPD_threadprivate:
7704 case OMPD_taskyield:
7707 case OMPD_cancellation_point:
7709 case OMPD_declare_reduction:
7710 case OMPD_declare_simd:
7711 case OMPD_declare_target:
7712 case OMPD_end_declare_target:
7722 case OMPD_taskgroup:
7723 case OMPD_distribute:
7726 case OMPD_distribute_simd:
7727 case OMPD_teams_distribute:
7728 case OMPD_teams_distribute_simd:
7729 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
7731 llvm_unreachable("Unknown OpenMP directive");
7734 case OMPC_num_teams:
7736 case OMPD_target_teams:
7737 case OMPD_target_teams_distribute:
7738 case OMPD_target_teams_distribute_simd:
7739 case OMPD_target_teams_distribute_parallel_for:
7740 case OMPD_target_teams_distribute_parallel_for_simd:
7741 CaptureRegion = OMPD_target;
7743 case OMPD_teams_distribute_parallel_for:
7744 case OMPD_teams_distribute_parallel_for_simd:
7746 case OMPD_teams_distribute:
7747 case OMPD_teams_distribute_simd:
7748 // Do not capture num_teams-clause expressions.
7750 case OMPD_distribute_parallel_for:
7751 case OMPD_distribute_parallel_for_simd:
7754 case OMPD_taskloop_simd:
7755 case OMPD_target_data:
7756 case OMPD_target_enter_data:
7757 case OMPD_target_exit_data:
7758 case OMPD_target_update:
7761 case OMPD_parallel_sections:
7762 case OMPD_parallel_for:
7763 case OMPD_parallel_for_simd:
7765 case OMPD_target_simd:
7766 case OMPD_target_parallel:
7767 case OMPD_target_parallel_for:
7768 case OMPD_target_parallel_for_simd:
7769 case OMPD_threadprivate:
7770 case OMPD_taskyield:
7773 case OMPD_cancellation_point:
7775 case OMPD_declare_reduction:
7776 case OMPD_declare_simd:
7777 case OMPD_declare_target:
7778 case OMPD_end_declare_target:
7787 case OMPD_taskgroup:
7788 case OMPD_distribute:
7791 case OMPD_distribute_simd:
7792 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
7794 llvm_unreachable("Unknown OpenMP directive");
7797 case OMPC_thread_limit:
7799 case OMPD_target_teams:
7800 case OMPD_target_teams_distribute:
7801 case OMPD_target_teams_distribute_simd:
7802 case OMPD_target_teams_distribute_parallel_for:
7803 case OMPD_target_teams_distribute_parallel_for_simd:
7804 CaptureRegion = OMPD_target;
7806 case OMPD_teams_distribute_parallel_for:
7807 case OMPD_teams_distribute_parallel_for_simd:
7809 case OMPD_teams_distribute:
7810 case OMPD_teams_distribute_simd:
7811 // Do not capture thread_limit-clause expressions.
7813 case OMPD_distribute_parallel_for:
7814 case OMPD_distribute_parallel_for_simd:
7817 case OMPD_taskloop_simd:
7818 case OMPD_target_data:
7819 case OMPD_target_enter_data:
7820 case OMPD_target_exit_data:
7821 case OMPD_target_update:
7824 case OMPD_parallel_sections:
7825 case OMPD_parallel_for:
7826 case OMPD_parallel_for_simd:
7828 case OMPD_target_simd:
7829 case OMPD_target_parallel:
7830 case OMPD_target_parallel_for:
7831 case OMPD_target_parallel_for_simd:
7832 case OMPD_threadprivate:
7833 case OMPD_taskyield:
7836 case OMPD_cancellation_point:
7838 case OMPD_declare_reduction:
7839 case OMPD_declare_simd:
7840 case OMPD_declare_target:
7841 case OMPD_end_declare_target:
7850 case OMPD_taskgroup:
7851 case OMPD_distribute:
7854 case OMPD_distribute_simd:
7855 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
7857 llvm_unreachable("Unknown OpenMP directive");
7862 case OMPD_target_parallel_for:
7863 case OMPD_target_parallel_for_simd:
7864 case OMPD_target_teams_distribute_parallel_for:
7865 case OMPD_target_teams_distribute_parallel_for_simd:
7866 CaptureRegion = OMPD_target;
7868 case OMPD_teams_distribute_parallel_for:
7869 case OMPD_teams_distribute_parallel_for_simd:
7870 CaptureRegion = OMPD_teams;
7872 case OMPD_parallel_for:
7873 case OMPD_parallel_for_simd:
7874 case OMPD_distribute_parallel_for:
7875 case OMPD_distribute_parallel_for_simd:
7876 CaptureRegion = OMPD_parallel;
7880 // Do not capture schedule-clause expressions.
7884 case OMPD_taskloop_simd:
7885 case OMPD_target_data:
7886 case OMPD_target_enter_data:
7887 case OMPD_target_exit_data:
7888 case OMPD_target_update:
7890 case OMPD_teams_distribute:
7891 case OMPD_teams_distribute_simd:
7892 case OMPD_target_teams_distribute:
7893 case OMPD_target_teams_distribute_simd:
7895 case OMPD_target_simd:
7896 case OMPD_target_parallel:
7899 case OMPD_parallel_sections:
7900 case OMPD_threadprivate:
7901 case OMPD_taskyield:
7904 case OMPD_cancellation_point:
7906 case OMPD_declare_reduction:
7907 case OMPD_declare_simd:
7908 case OMPD_declare_target:
7909 case OMPD_end_declare_target:
7916 case OMPD_taskgroup:
7917 case OMPD_distribute:
7920 case OMPD_distribute_simd:
7921 case OMPD_target_teams:
7922 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
7924 llvm_unreachable("Unknown OpenMP directive");
7927 case OMPC_dist_schedule:
7929 case OMPD_teams_distribute_parallel_for:
7930 case OMPD_teams_distribute_parallel_for_simd:
7931 case OMPD_teams_distribute:
7932 case OMPD_teams_distribute_simd:
7933 CaptureRegion = OMPD_teams;
7935 case OMPD_target_teams_distribute_parallel_for:
7936 case OMPD_target_teams_distribute_parallel_for_simd:
7937 case OMPD_target_teams_distribute:
7938 case OMPD_target_teams_distribute_simd:
7939 CaptureRegion = OMPD_target;
7941 case OMPD_distribute_parallel_for:
7942 case OMPD_distribute_parallel_for_simd:
7943 CaptureRegion = OMPD_parallel;
7945 case OMPD_distribute:
7946 case OMPD_distribute_simd:
7947 // Do not capture thread_limit-clause expressions.
7949 case OMPD_parallel_for:
7950 case OMPD_parallel_for_simd:
7951 case OMPD_target_parallel_for_simd:
7952 case OMPD_target_parallel_for:
7955 case OMPD_taskloop_simd:
7956 case OMPD_target_data:
7957 case OMPD_target_enter_data:
7958 case OMPD_target_exit_data:
7959 case OMPD_target_update:
7962 case OMPD_target_simd:
7963 case OMPD_target_parallel:
7966 case OMPD_parallel_sections:
7967 case OMPD_threadprivate:
7968 case OMPD_taskyield:
7971 case OMPD_cancellation_point:
7973 case OMPD_declare_reduction:
7974 case OMPD_declare_simd:
7975 case OMPD_declare_target:
7976 case OMPD_end_declare_target:
7985 case OMPD_taskgroup:
7988 case OMPD_target_teams:
7989 llvm_unreachable("Unexpected OpenMP directive with schedule clause");
7991 llvm_unreachable("Unknown OpenMP directive");
7996 case OMPD_target_teams:
7997 case OMPD_target_teams_distribute:
7998 case OMPD_target_teams_distribute_simd:
7999 case OMPD_target_teams_distribute_parallel_for:
8000 case OMPD_target_teams_distribute_parallel_for_simd:
8001 case OMPD_target_data:
8002 case OMPD_target_enter_data:
8003 case OMPD_target_exit_data:
8004 case OMPD_target_update:
8006 case OMPD_target_simd:
8007 case OMPD_target_parallel:
8008 case OMPD_target_parallel_for:
8009 case OMPD_target_parallel_for_simd:
8010 // Do not capture device-clause expressions.
8012 case OMPD_teams_distribute_parallel_for:
8013 case OMPD_teams_distribute_parallel_for_simd:
8015 case OMPD_teams_distribute:
8016 case OMPD_teams_distribute_simd:
8017 case OMPD_distribute_parallel_for:
8018 case OMPD_distribute_parallel_for_simd:
8021 case OMPD_taskloop_simd:
8024 case OMPD_parallel_sections:
8025 case OMPD_parallel_for:
8026 case OMPD_parallel_for_simd:
8027 case OMPD_threadprivate:
8028 case OMPD_taskyield:
8031 case OMPD_cancellation_point:
8033 case OMPD_declare_reduction:
8034 case OMPD_declare_simd:
8035 case OMPD_declare_target:
8036 case OMPD_end_declare_target:
8045 case OMPD_taskgroup:
8046 case OMPD_distribute:
8049 case OMPD_distribute_simd:
8050 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8052 llvm_unreachable("Unknown OpenMP directive");
8055 case OMPC_firstprivate:
8056 case OMPC_lastprivate:
8057 case OMPC_reduction:
8058 case OMPC_task_reduction:
8059 case OMPC_in_reduction:
8062 case OMPC_proc_bind:
8071 case OMPC_copyprivate:
8075 case OMPC_mergeable:
8076 case OMPC_threadprivate:
8088 case OMPC_grainsize:
8090 case OMPC_num_tasks:
8092 case OMPC_defaultmap:
8097 case OMPC_use_device_ptr:
8098 case OMPC_is_device_ptr:
8099 llvm_unreachable("Unexpected OpenMP clause.");
8101 return CaptureRegion;
8104 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
8105 Expr *Condition, SourceLocation StartLoc,
8106 SourceLocation LParenLoc,
8107 SourceLocation NameModifierLoc,
8108 SourceLocation ColonLoc,
8109 SourceLocation EndLoc) {
8110 Expr *ValExpr = Condition;
8111 Stmt *HelperValStmt = nullptr;
8112 OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8113 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8114 !Condition->isInstantiationDependent() &&
8115 !Condition->containsUnexpandedParameterPack()) {
8116 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8117 if (Val.isInvalid())
8120 ValExpr = MakeFullExpr(Val.get()).get();
8122 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8124 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8125 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8126 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8127 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8128 HelperValStmt = buildPreInits(Context, Captures);
8132 return new (Context)
8133 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8134 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8137 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
8138 SourceLocation StartLoc,
8139 SourceLocation LParenLoc,
8140 SourceLocation EndLoc) {
8141 Expr *ValExpr = Condition;
8142 if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8143 !Condition->isInstantiationDependent() &&
8144 !Condition->containsUnexpandedParameterPack()) {
8145 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8146 if (Val.isInvalid())
8149 ValExpr = MakeFullExpr(Val.get()).get();
8152 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8154 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
8159 class IntConvertDiagnoser : public ICEConvertDiagnoser {
8161 IntConvertDiagnoser()
8162 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8163 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8164 QualType T) override {
8165 return S.Diag(Loc, diag::err_omp_not_integral) << T;
8167 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8168 QualType T) override {
8169 return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8171 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8173 QualType ConvTy) override {
8174 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8176 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8177 QualType ConvTy) override {
8178 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8179 << ConvTy->isEnumeralType() << ConvTy;
8181 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8182 QualType T) override {
8183 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8185 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8186 QualType ConvTy) override {
8187 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8188 << ConvTy->isEnumeralType() << ConvTy;
8190 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8191 QualType) override {
8192 llvm_unreachable("conversion functions are permitted");
8195 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8198 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8199 OpenMPClauseKind CKind,
8200 bool StrictlyPositive) {
8201 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8202 !ValExpr->isInstantiationDependent()) {
8203 SourceLocation Loc = ValExpr->getExprLoc();
8205 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8206 if (Value.isInvalid())
8209 ValExpr = Value.get();
8210 // The expression must evaluate to a non-negative integer value.
8211 llvm::APSInt Result;
8212 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8213 Result.isSigned() &&
8214 !((!StrictlyPositive && Result.isNonNegative()) ||
8215 (StrictlyPositive && Result.isStrictlyPositive()))) {
8216 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8217 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8218 << ValExpr->getSourceRange();
8225 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
8226 SourceLocation StartLoc,
8227 SourceLocation LParenLoc,
8228 SourceLocation EndLoc) {
8229 Expr *ValExpr = NumThreads;
8230 Stmt *HelperValStmt = nullptr;
8232 // OpenMP [2.5, Restrictions]
8233 // The num_threads expression must evaluate to a positive integer value.
8234 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8235 /*StrictlyPositive=*/true))
8238 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8239 OpenMPDirectiveKind CaptureRegion =
8240 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8241 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8242 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8243 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8244 HelperValStmt = buildPreInits(Context, Captures);
8247 return new (Context) OMPNumThreadsClause(
8248 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8251 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8252 OpenMPClauseKind CKind,
8253 bool StrictlyPositive) {
8256 if (E->isValueDependent() || E->isTypeDependent() ||
8257 E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
8259 llvm::APSInt Result;
8260 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8261 if (ICE.isInvalid())
8263 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8264 (!StrictlyPositive && !Result.isNonNegative())) {
8265 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8266 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8267 << E->getSourceRange();
8270 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8271 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8272 << E->getSourceRange();
8275 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
8276 DSAStack->setAssociatedLoops(Result.getExtValue());
8277 else if (CKind == OMPC_ordered)
8278 DSAStack->setAssociatedLoops(Result.getExtValue());
8282 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
8283 SourceLocation LParenLoc,
8284 SourceLocation EndLoc) {
8285 // OpenMP [2.8.1, simd construct, Description]
8286 // The parameter of the safelen clause must be a constant
8287 // positive integer expression.
8288 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8289 if (Safelen.isInvalid())
8291 return new (Context)
8292 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8295 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
8296 SourceLocation LParenLoc,
8297 SourceLocation EndLoc) {
8298 // OpenMP [2.8.1, simd construct, Description]
8299 // The parameter of the simdlen clause must be a constant
8300 // positive integer expression.
8301 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8302 if (Simdlen.isInvalid())
8304 return new (Context)
8305 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8308 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
8309 SourceLocation StartLoc,
8310 SourceLocation LParenLoc,
8311 SourceLocation EndLoc) {
8312 // OpenMP [2.7.1, loop construct, Description]
8313 // OpenMP [2.8.1, simd construct, Description]
8314 // OpenMP [2.9.6, distribute construct, Description]
8315 // The parameter of the collapse clause must be a constant
8316 // positive integer expression.
8317 ExprResult NumForLoopsResult =
8318 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8319 if (NumForLoopsResult.isInvalid())
8321 return new (Context)
8322 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8325 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
8326 SourceLocation EndLoc,
8327 SourceLocation LParenLoc,
8328 Expr *NumForLoops) {
8329 // OpenMP [2.7.1, loop construct, Description]
8330 // OpenMP [2.8.1, simd construct, Description]
8331 // OpenMP [2.9.6, distribute construct, Description]
8332 // The parameter of the ordered clause must be a constant
8333 // positive integer expression if any.
8334 if (NumForLoops && LParenLoc.isValid()) {
8335 ExprResult NumForLoopsResult =
8336 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8337 if (NumForLoopsResult.isInvalid())
8339 NumForLoops = NumForLoopsResult.get();
8341 NumForLoops = nullptr;
8342 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
8343 return new (Context)
8344 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
8347 OMPClause *Sema::ActOnOpenMPSimpleClause(
8348 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8349 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8350 OMPClause *Res = nullptr;
8354 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8355 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8357 case OMPC_proc_bind:
8358 Res = ActOnOpenMPProcBindClause(
8359 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8364 case OMPC_num_threads:
8370 case OMPC_firstprivate:
8371 case OMPC_lastprivate:
8373 case OMPC_reduction:
8374 case OMPC_task_reduction:
8375 case OMPC_in_reduction:
8379 case OMPC_copyprivate:
8383 case OMPC_mergeable:
8384 case OMPC_threadprivate:
8396 case OMPC_num_teams:
8397 case OMPC_thread_limit:
8399 case OMPC_grainsize:
8401 case OMPC_num_tasks:
8403 case OMPC_dist_schedule:
8404 case OMPC_defaultmap:
8409 case OMPC_use_device_ptr:
8410 case OMPC_is_device_ptr:
8411 llvm_unreachable("Clause is not allowed.");
8417 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
8418 ArrayRef<unsigned> Exclude = llvm::None) {
8420 unsigned Bound = Last >= 2 ? Last - 2 : 0;
8421 unsigned Skipped = Exclude.size();
8422 auto S = Exclude.begin(), E = Exclude.end();
8423 for (unsigned i = First; i < Last; ++i) {
8424 if (std::find(S, E, i) != E) {
8429 Values += getOpenMPSimpleClauseTypeName(K, i);
8431 if (i == Bound - Skipped)
8433 else if (i != Bound + 1 - Skipped)
8439 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
8440 SourceLocation KindKwLoc,
8441 SourceLocation StartLoc,
8442 SourceLocation LParenLoc,
8443 SourceLocation EndLoc) {
8444 if (Kind == OMPC_DEFAULT_unknown) {
8445 static_assert(OMPC_DEFAULT_unknown > 0,
8446 "OMPC_DEFAULT_unknown not greater than 0");
8447 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8448 << getListOfPossibleValues(OMPC_default, /*First=*/0,
8449 /*Last=*/OMPC_DEFAULT_unknown)
8450 << getOpenMPClauseName(OMPC_default);
8454 case OMPC_DEFAULT_none:
8455 DSAStack->setDefaultDSANone(KindKwLoc);
8457 case OMPC_DEFAULT_shared:
8458 DSAStack->setDefaultDSAShared(KindKwLoc);
8460 case OMPC_DEFAULT_unknown:
8461 llvm_unreachable("Clause kind is not allowed.");
8464 return new (Context)
8465 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8468 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind,
8469 SourceLocation KindKwLoc,
8470 SourceLocation StartLoc,
8471 SourceLocation LParenLoc,
8472 SourceLocation EndLoc) {
8473 if (Kind == OMPC_PROC_BIND_unknown) {
8474 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8475 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8476 /*Last=*/OMPC_PROC_BIND_unknown)
8477 << getOpenMPClauseName(OMPC_proc_bind);
8480 return new (Context)
8481 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8484 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
8485 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
8486 SourceLocation StartLoc, SourceLocation LParenLoc,
8487 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8488 SourceLocation EndLoc) {
8489 OMPClause *Res = nullptr;
8492 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8493 assert(Argument.size() == NumberOfElements &&
8494 ArgumentLoc.size() == NumberOfElements);
8495 Res = ActOnOpenMPScheduleClause(
8496 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8497 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8498 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8499 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8500 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8503 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8504 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8505 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8508 case OMPC_dist_schedule:
8509 Res = ActOnOpenMPDistScheduleClause(
8510 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8511 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8513 case OMPC_defaultmap:
8514 enum { Modifier, DefaultmapKind };
8515 Res = ActOnOpenMPDefaultmapClause(
8516 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8517 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8518 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8522 case OMPC_num_threads:
8527 case OMPC_proc_bind:
8529 case OMPC_firstprivate:
8530 case OMPC_lastprivate:
8532 case OMPC_reduction:
8533 case OMPC_task_reduction:
8534 case OMPC_in_reduction:
8538 case OMPC_copyprivate:
8542 case OMPC_mergeable:
8543 case OMPC_threadprivate:
8555 case OMPC_num_teams:
8556 case OMPC_thread_limit:
8558 case OMPC_grainsize:
8560 case OMPC_num_tasks:
8566 case OMPC_use_device_ptr:
8567 case OMPC_is_device_ptr:
8568 llvm_unreachable("Clause is not allowed.");
8573 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
8574 OpenMPScheduleClauseModifier M2,
8575 SourceLocation M1Loc, SourceLocation M2Loc) {
8576 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8577 SmallVector<unsigned, 2> Excluded;
8578 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
8579 Excluded.push_back(M2);
8580 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8581 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8582 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8583 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8584 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8585 << getListOfPossibleValues(OMPC_schedule,
8586 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8587 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8589 << getOpenMPClauseName(OMPC_schedule);
8595 OMPClause *Sema::ActOnOpenMPScheduleClause(
8596 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
8597 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8598 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8599 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8600 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8601 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8603 // OpenMP, 2.7.1, Loop Construct, Restrictions
8604 // Either the monotonic modifier or the nonmonotonic modifier can be specified
8606 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8607 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8608 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8609 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8610 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8611 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8612 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8613 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8616 if (Kind == OMPC_SCHEDULE_unknown) {
8618 if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8619 unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8620 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8621 /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8624 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8625 /*Last=*/OMPC_SCHEDULE_unknown);
8627 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8628 << Values << getOpenMPClauseName(OMPC_schedule);
8631 // OpenMP, 2.7.1, Loop Construct, Restrictions
8632 // The nonmonotonic modifier can only be specified with schedule(dynamic) or
8633 // schedule(guided).
8634 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
8635 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
8636 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
8637 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
8638 diag::err_omp_schedule_nonmonotonic_static);
8641 Expr *ValExpr = ChunkSize;
8642 Stmt *HelperValStmt = nullptr;
8644 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
8645 !ChunkSize->isInstantiationDependent() &&
8646 !ChunkSize->containsUnexpandedParameterPack()) {
8647 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
8649 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
8650 if (Val.isInvalid())
8653 ValExpr = Val.get();
8655 // OpenMP [2.7.1, Restrictions]
8656 // chunk_size must be a loop invariant integer expression with a positive
8658 llvm::APSInt Result;
8659 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
8660 if (Result.isSigned() && !Result.isStrictlyPositive()) {
8661 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
8662 << "schedule" << 1 << ChunkSize->getSourceRange();
8665 } else if (getOpenMPCaptureRegionForClause(
8666 DSAStack->getCurrentDirective(), OMPC_schedule) !=
8668 !CurContext->isDependentContext()) {
8669 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8670 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8671 HelperValStmt = buildPreInits(Context, Captures);
8676 return new (Context)
8677 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
8678 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
8681 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
8682 SourceLocation StartLoc,
8683 SourceLocation EndLoc) {
8684 OMPClause *Res = nullptr;
8687 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
8690 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
8693 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
8695 case OMPC_mergeable:
8696 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
8699 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
8702 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
8705 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
8708 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
8711 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
8714 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
8717 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
8720 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
8724 case OMPC_num_threads:
8730 case OMPC_firstprivate:
8731 case OMPC_lastprivate:
8733 case OMPC_reduction:
8734 case OMPC_task_reduction:
8735 case OMPC_in_reduction:
8739 case OMPC_copyprivate:
8741 case OMPC_proc_bind:
8742 case OMPC_threadprivate:
8747 case OMPC_num_teams:
8748 case OMPC_thread_limit:
8750 case OMPC_grainsize:
8751 case OMPC_num_tasks:
8753 case OMPC_dist_schedule:
8754 case OMPC_defaultmap:
8759 case OMPC_use_device_ptr:
8760 case OMPC_is_device_ptr:
8761 llvm_unreachable("Clause is not allowed.");
8766 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
8767 SourceLocation EndLoc) {
8768 DSAStack->setNowaitRegion();
8769 return new (Context) OMPNowaitClause(StartLoc, EndLoc);
8772 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
8773 SourceLocation EndLoc) {
8774 return new (Context) OMPUntiedClause(StartLoc, EndLoc);
8777 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
8778 SourceLocation EndLoc) {
8779 return new (Context) OMPMergeableClause(StartLoc, EndLoc);
8782 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
8783 SourceLocation EndLoc) {
8784 return new (Context) OMPReadClause(StartLoc, EndLoc);
8787 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
8788 SourceLocation EndLoc) {
8789 return new (Context) OMPWriteClause(StartLoc, EndLoc);
8792 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
8793 SourceLocation EndLoc) {
8794 return new (Context) OMPUpdateClause(StartLoc, EndLoc);
8797 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
8798 SourceLocation EndLoc) {
8799 return new (Context) OMPCaptureClause(StartLoc, EndLoc);
8802 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
8803 SourceLocation EndLoc) {
8804 return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
8807 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
8808 SourceLocation EndLoc) {
8809 return new (Context) OMPThreadsClause(StartLoc, EndLoc);
8812 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
8813 SourceLocation EndLoc) {
8814 return new (Context) OMPSIMDClause(StartLoc, EndLoc);
8817 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
8818 SourceLocation EndLoc) {
8819 return new (Context) OMPNogroupClause(StartLoc, EndLoc);
8822 OMPClause *Sema::ActOnOpenMPVarListClause(
8823 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
8824 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
8825 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
8826 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
8827 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
8828 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
8829 SourceLocation DepLinMapLoc) {
8830 OMPClause *Res = nullptr;
8833 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8835 case OMPC_firstprivate:
8836 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8838 case OMPC_lastprivate:
8839 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8842 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
8844 case OMPC_reduction:
8845 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8846 EndLoc, ReductionIdScopeSpec, ReductionId);
8848 case OMPC_task_reduction:
8849 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8850 EndLoc, ReductionIdScopeSpec,
8853 case OMPC_in_reduction:
8855 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8856 EndLoc, ReductionIdScopeSpec, ReductionId);
8859 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
8860 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8863 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
8867 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
8869 case OMPC_copyprivate:
8870 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8873 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
8876 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
8877 StartLoc, LParenLoc, EndLoc);
8880 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
8881 DepLinMapLoc, ColonLoc, VarList, StartLoc,
8885 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
8888 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
8890 case OMPC_use_device_ptr:
8891 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8893 case OMPC_is_device_ptr:
8894 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8898 case OMPC_num_threads:
8903 case OMPC_proc_bind:
8908 case OMPC_mergeable:
8909 case OMPC_threadprivate:
8918 case OMPC_num_teams:
8919 case OMPC_thread_limit:
8921 case OMPC_grainsize:
8923 case OMPC_num_tasks:
8925 case OMPC_dist_schedule:
8926 case OMPC_defaultmap:
8929 llvm_unreachable("Clause is not allowed.");
8934 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
8935 ExprObjectKind OK, SourceLocation Loc) {
8936 ExprResult Res = BuildDeclRefExpr(
8937 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
8938 if (!Res.isUsable())
8940 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
8941 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
8942 if (!Res.isUsable())
8945 if (VK != VK_LValue && Res.get()->isGLValue()) {
8946 Res = DefaultLvalueConversion(Res.get());
8947 if (!Res.isUsable())
8953 static std::pair<ValueDecl *, bool>
8954 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
8955 SourceRange &ERange, bool AllowArraySection = false) {
8956 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
8957 RefExpr->containsUnexpandedParameterPack())
8958 return std::make_pair(nullptr, true);
8960 // OpenMP [3.1, C/C++]
8961 // A list item is a variable name.
8962 // OpenMP [2.9.3.3, Restrictions, p.1]
8963 // A variable that is part of another variable (as an array or
8964 // structure element) cannot appear in a private clause.
8965 RefExpr = RefExpr->IgnoreParens();
8970 } IsArrayExpr = NoArrayExpr;
8971 if (AllowArraySection) {
8972 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8973 auto *Base = ASE->getBase()->IgnoreParenImpCasts();
8974 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8975 Base = TempASE->getBase()->IgnoreParenImpCasts();
8977 IsArrayExpr = ArraySubscript;
8978 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8979 auto *Base = OASE->getBase()->IgnoreParenImpCasts();
8980 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
8981 Base = TempOASE->getBase()->IgnoreParenImpCasts();
8982 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8983 Base = TempASE->getBase()->IgnoreParenImpCasts();
8985 IsArrayExpr = OMPArraySection;
8988 ELoc = RefExpr->getExprLoc();
8989 ERange = RefExpr->getSourceRange();
8990 RefExpr = RefExpr->IgnoreParenImpCasts();
8991 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
8992 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
8993 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
8994 (S.getCurrentThisType().isNull() || !ME ||
8995 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
8996 !isa<FieldDecl>(ME->getMemberDecl()))) {
8997 if (IsArrayExpr != NoArrayExpr)
8998 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9003 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9004 : diag::err_omp_expected_var_name_member_expr)
9005 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9007 return std::make_pair(nullptr, false);
9009 return std::make_pair(
9010 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9013 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
9014 SourceLocation StartLoc,
9015 SourceLocation LParenLoc,
9016 SourceLocation EndLoc) {
9017 SmallVector<Expr *, 8> Vars;
9018 SmallVector<Expr *, 8> PrivateCopies;
9019 for (auto &RefExpr : VarList) {
9020 assert(RefExpr && "NULL expr in OpenMP private clause.");
9021 SourceLocation ELoc;
9023 Expr *SimpleRefExpr = RefExpr;
9024 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9026 // It will be analyzed later.
9027 Vars.push_back(RefExpr);
9028 PrivateCopies.push_back(nullptr);
9030 ValueDecl *D = Res.first;
9034 QualType Type = D->getType();
9035 auto *VD = dyn_cast<VarDecl>(D);
9037 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9038 // A variable that appears in a private clause must not have an incomplete
9039 // type or a reference type.
9040 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9042 Type = Type.getNonReferenceType();
9044 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9046 // Variables with the predetermined data-sharing attributes may not be
9047 // listed in data-sharing attributes clauses, except for the cases
9048 // listed below. For these exceptions only, listing a predetermined
9049 // variable in a data-sharing attribute clause is allowed and overrides
9050 // the variable's predetermined data-sharing attributes.
9051 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9052 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9053 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9054 << getOpenMPClauseName(OMPC_private);
9055 ReportOriginalDSA(*this, DSAStack, D, DVar);
9059 auto CurrDir = DSAStack->getCurrentDirective();
9060 // Variably modified types are not supported for tasks.
9061 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9062 isOpenMPTaskingDirective(CurrDir)) {
9063 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9064 << getOpenMPClauseName(OMPC_private) << Type
9065 << getOpenMPDirectiveName(CurrDir);
9068 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9069 Diag(D->getLocation(),
9070 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9075 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9076 // A list item cannot appear in both a map clause and a data-sharing
9077 // attribute clause on the same construct
9078 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
9079 CurrDir == OMPD_target_teams ||
9080 CurrDir == OMPD_target_teams_distribute ||
9081 CurrDir == OMPD_target_teams_distribute_parallel_for ||
9082 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
9083 CurrDir == OMPD_target_teams_distribute_simd ||
9084 CurrDir == OMPD_target_parallel_for_simd ||
9085 CurrDir == OMPD_target_parallel_for) {
9086 OpenMPClauseKind ConflictKind;
9087 if (DSAStack->checkMappableExprComponentListsForDecl(
9088 VD, /*CurrentRegionOnly=*/true,
9089 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9090 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9091 ConflictKind = WhereFoundClauseKind;
9094 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9095 << getOpenMPClauseName(OMPC_private)
9096 << getOpenMPClauseName(ConflictKind)
9097 << getOpenMPDirectiveName(CurrDir);
9098 ReportOriginalDSA(*this, DSAStack, D, DVar);
9103 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9104 // A variable of class type (or array thereof) that appears in a private
9105 // clause requires an accessible, unambiguous default constructor for the
9107 // Generate helper private variable and initialize it with the default
9108 // value. The address of the original variable is replaced by the address of
9109 // the new private variable in CodeGen. This new variable is not added to
9110 // IdResolver, so the code in the OpenMP region uses original variable for
9111 // proper diagnostics.
9112 Type = Type.getUnqualifiedType();
9113 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9114 D->hasAttrs() ? &D->getAttrs() : nullptr);
9115 ActOnUninitializedDecl(VDPrivate);
9116 if (VDPrivate->isInvalidDecl())
9118 auto VDPrivateRefExpr = buildDeclRefExpr(
9119 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9121 DeclRefExpr *Ref = nullptr;
9122 if (!VD && !CurContext->isDependentContext())
9123 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9124 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9125 Vars.push_back((VD || CurContext->isDependentContext())
9126 ? RefExpr->IgnoreParens()
9128 PrivateCopies.push_back(VDPrivateRefExpr);
9134 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9139 class DiagsUninitializedSeveretyRAII {
9141 DiagnosticsEngine &Diags;
9142 SourceLocation SavedLoc;
9146 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9148 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9150 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9151 /*Map*/ diag::Severity::Ignored, Loc);
9154 ~DiagsUninitializedSeveretyRAII() {
9156 Diags.popMappings(SavedLoc);
9161 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
9162 SourceLocation StartLoc,
9163 SourceLocation LParenLoc,
9164 SourceLocation EndLoc) {
9165 SmallVector<Expr *, 8> Vars;
9166 SmallVector<Expr *, 8> PrivateCopies;
9167 SmallVector<Expr *, 8> Inits;
9168 SmallVector<Decl *, 4> ExprCaptures;
9169 bool IsImplicitClause =
9170 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9171 auto ImplicitClauseLoc = DSAStack->getConstructLoc();
9173 for (auto &RefExpr : VarList) {
9174 assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9175 SourceLocation ELoc;
9177 Expr *SimpleRefExpr = RefExpr;
9178 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9180 // It will be analyzed later.
9181 Vars.push_back(RefExpr);
9182 PrivateCopies.push_back(nullptr);
9183 Inits.push_back(nullptr);
9185 ValueDecl *D = Res.first;
9189 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9190 QualType Type = D->getType();
9191 auto *VD = dyn_cast<VarDecl>(D);
9193 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9194 // A variable that appears in a private clause must not have an incomplete
9195 // type or a reference type.
9196 if (RequireCompleteType(ELoc, Type,
9197 diag::err_omp_firstprivate_incomplete_type))
9199 Type = Type.getNonReferenceType();
9201 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9202 // A variable of class type (or array thereof) that appears in a private
9203 // clause requires an accessible, unambiguous copy constructor for the
9205 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9207 // If an implicit firstprivate variable found it was checked already.
9208 DSAStackTy::DSAVarData TopDVar;
9209 if (!IsImplicitClause) {
9210 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9212 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9213 bool IsConstant = ElemType.isConstant(Context);
9214 // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9215 // A list item that specifies a given variable may not appear in more
9216 // than one clause on the same directive, except that a variable may be
9217 // specified in both firstprivate and lastprivate clauses.
9218 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9219 // A list item may appear in a firstprivate or lastprivate clause but not
9221 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9222 (isOpenMPDistributeDirective(CurrDir) ||
9223 DVar.CKind != OMPC_lastprivate) &&
9225 Diag(ELoc, diag::err_omp_wrong_dsa)
9226 << getOpenMPClauseName(DVar.CKind)
9227 << getOpenMPClauseName(OMPC_firstprivate);
9228 ReportOriginalDSA(*this, DSAStack, D, DVar);
9232 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9234 // Variables with the predetermined data-sharing attributes may not be
9235 // listed in data-sharing attributes clauses, except for the cases
9236 // listed below. For these exceptions only, listing a predetermined
9237 // variable in a data-sharing attribute clause is allowed and overrides
9238 // the variable's predetermined data-sharing attributes.
9239 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9240 // in a Construct, C/C++, p.2]
9241 // Variables with const-qualified type having no mutable member may be
9242 // listed in a firstprivate clause, even if they are static data members.
9243 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9244 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9245 Diag(ELoc, diag::err_omp_wrong_dsa)
9246 << getOpenMPClauseName(DVar.CKind)
9247 << getOpenMPClauseName(OMPC_firstprivate);
9248 ReportOriginalDSA(*this, DSAStack, D, DVar);
9252 // OpenMP [2.9.3.4, Restrictions, p.2]
9253 // A list item that is private within a parallel region must not appear
9254 // in a firstprivate clause on a worksharing construct if any of the
9255 // worksharing regions arising from the worksharing construct ever bind
9256 // to any of the parallel regions arising from the parallel construct.
9257 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9258 // A list item that is private within a teams region must not appear in a
9259 // firstprivate clause on a distribute construct if any of the distribute
9260 // regions arising from the distribute construct ever bind to any of the
9261 // teams regions arising from the teams construct.
9262 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9263 // A list item that appears in a reduction clause of a teams construct
9264 // must not appear in a firstprivate clause on a distribute construct if
9265 // any of the distribute regions arising from the distribute construct
9266 // ever bind to any of the teams regions arising from the teams construct.
9267 if ((isOpenMPWorksharingDirective(CurrDir) ||
9268 isOpenMPDistributeDirective(CurrDir)) &&
9269 !isOpenMPParallelDirective(CurrDir) &&
9270 !isOpenMPTeamsDirective(CurrDir)) {
9271 DVar = DSAStack->getImplicitDSA(D, true);
9272 if (DVar.CKind != OMPC_shared &&
9273 (isOpenMPParallelDirective(DVar.DKind) ||
9274 isOpenMPTeamsDirective(DVar.DKind) ||
9275 DVar.DKind == OMPD_unknown)) {
9276 Diag(ELoc, diag::err_omp_required_access)
9277 << getOpenMPClauseName(OMPC_firstprivate)
9278 << getOpenMPClauseName(OMPC_shared);
9279 ReportOriginalDSA(*this, DSAStack, D, DVar);
9283 // OpenMP [2.9.3.4, Restrictions, p.3]
9284 // A list item that appears in a reduction clause of a parallel construct
9285 // must not appear in a firstprivate clause on a worksharing or task
9286 // construct if any of the worksharing or task regions arising from the
9287 // worksharing or task construct ever bind to any of the parallel regions
9288 // arising from the parallel construct.
9289 // OpenMP [2.9.3.4, Restrictions, p.4]
9290 // A list item that appears in a reduction clause in worksharing
9291 // construct must not appear in a firstprivate clause in a task construct
9292 // encountered during execution of any of the worksharing regions arising
9293 // from the worksharing construct.
9294 if (isOpenMPTaskingDirective(CurrDir)) {
9295 DVar = DSAStack->hasInnermostDSA(
9296 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
9297 [](OpenMPDirectiveKind K) -> bool {
9298 return isOpenMPParallelDirective(K) ||
9299 isOpenMPWorksharingDirective(K) ||
9300 isOpenMPTeamsDirective(K);
9302 /*FromParent=*/true);
9303 if (DVar.CKind == OMPC_reduction &&
9304 (isOpenMPParallelDirective(DVar.DKind) ||
9305 isOpenMPWorksharingDirective(DVar.DKind) ||
9306 isOpenMPTeamsDirective(DVar.DKind))) {
9307 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9308 << getOpenMPDirectiveName(DVar.DKind);
9309 ReportOriginalDSA(*this, DSAStack, D, DVar);
9314 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9315 // A list item cannot appear in both a map clause and a data-sharing
9316 // attribute clause on the same construct
9317 if (isOpenMPTargetExecutionDirective(CurrDir)) {
9318 OpenMPClauseKind ConflictKind;
9319 if (DSAStack->checkMappableExprComponentListsForDecl(
9320 VD, /*CurrentRegionOnly=*/true,
9321 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
9322 OpenMPClauseKind WhereFoundClauseKind) -> bool {
9323 ConflictKind = WhereFoundClauseKind;
9326 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9327 << getOpenMPClauseName(OMPC_firstprivate)
9328 << getOpenMPClauseName(ConflictKind)
9329 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9330 ReportOriginalDSA(*this, DSAStack, D, DVar);
9336 // Variably modified types are not supported for tasks.
9337 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9338 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
9339 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9340 << getOpenMPClauseName(OMPC_firstprivate) << Type
9341 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9344 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9345 Diag(D->getLocation(),
9346 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9351 Type = Type.getUnqualifiedType();
9352 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9353 D->hasAttrs() ? &D->getAttrs() : nullptr);
9354 // Generate helper private variable and initialize it with the value of the
9355 // original variable. The address of the original variable is replaced by
9356 // the address of the new private variable in the CodeGen. This new variable
9357 // is not added to IdResolver, so the code in the OpenMP region uses
9358 // original variable for proper diagnostics and variable capturing.
9359 Expr *VDInitRefExpr = nullptr;
9360 // For arrays generate initializer for single element and replace it by the
9361 // original array element in CodeGen.
9362 if (Type->isArrayType()) {
9364 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9365 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9366 auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
9367 ElemType = ElemType.getUnqualifiedType();
9368 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9369 ".firstprivate.temp");
9370 InitializedEntity Entity =
9371 InitializedEntity::InitializeVariable(VDInitTemp);
9372 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
9374 InitializationSequence InitSeq(*this, Entity, Kind, Init);
9375 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9376 if (Result.isInvalid())
9377 VDPrivate->setInvalidDecl();
9379 VDPrivate->setInit(Result.getAs<Expr>());
9380 // Remove temp variable declaration.
9381 Context.Deallocate(VDInitTemp);
9383 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9384 ".firstprivate.temp");
9385 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9386 RefExpr->getExprLoc());
9387 AddInitializerToDecl(VDPrivate,
9388 DefaultLvalueConversion(VDInitRefExpr).get(),
9389 /*DirectInit=*/false);
9391 if (VDPrivate->isInvalidDecl()) {
9392 if (IsImplicitClause) {
9393 Diag(RefExpr->getExprLoc(),
9394 diag::note_omp_task_predetermined_firstprivate_here);
9398 CurContext->addDecl(VDPrivate);
9399 auto VDPrivateRefExpr = buildDeclRefExpr(
9400 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9401 RefExpr->getExprLoc());
9402 DeclRefExpr *Ref = nullptr;
9403 if (!VD && !CurContext->isDependentContext()) {
9404 if (TopDVar.CKind == OMPC_lastprivate)
9405 Ref = TopDVar.PrivateCopy;
9407 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9408 if (!IsOpenMPCapturedDecl(D))
9409 ExprCaptures.push_back(Ref->getDecl());
9412 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9413 Vars.push_back((VD || CurContext->isDependentContext())
9414 ? RefExpr->IgnoreParens()
9416 PrivateCopies.push_back(VDPrivateRefExpr);
9417 Inits.push_back(VDInitRefExpr);
9423 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9424 Vars, PrivateCopies, Inits,
9425 buildPreInits(Context, ExprCaptures));
9428 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
9429 SourceLocation StartLoc,
9430 SourceLocation LParenLoc,
9431 SourceLocation EndLoc) {
9432 SmallVector<Expr *, 8> Vars;
9433 SmallVector<Expr *, 8> SrcExprs;
9434 SmallVector<Expr *, 8> DstExprs;
9435 SmallVector<Expr *, 8> AssignmentOps;
9436 SmallVector<Decl *, 4> ExprCaptures;
9437 SmallVector<Expr *, 4> ExprPostUpdates;
9438 for (auto &RefExpr : VarList) {
9439 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9440 SourceLocation ELoc;
9442 Expr *SimpleRefExpr = RefExpr;
9443 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9445 // It will be analyzed later.
9446 Vars.push_back(RefExpr);
9447 SrcExprs.push_back(nullptr);
9448 DstExprs.push_back(nullptr);
9449 AssignmentOps.push_back(nullptr);
9451 ValueDecl *D = Res.first;
9455 QualType Type = D->getType();
9456 auto *VD = dyn_cast<VarDecl>(D);
9458 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9459 // A variable that appears in a lastprivate clause must not have an
9460 // incomplete type or a reference type.
9461 if (RequireCompleteType(ELoc, Type,
9462 diag::err_omp_lastprivate_incomplete_type))
9464 Type = Type.getNonReferenceType();
9466 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9467 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9469 // Variables with the predetermined data-sharing attributes may not be
9470 // listed in data-sharing attributes clauses, except for the cases
9472 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9473 // A list item may appear in a firstprivate or lastprivate clause but not
9475 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9476 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9477 (isOpenMPDistributeDirective(CurrDir) ||
9478 DVar.CKind != OMPC_firstprivate) &&
9479 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9480 Diag(ELoc, diag::err_omp_wrong_dsa)
9481 << getOpenMPClauseName(DVar.CKind)
9482 << getOpenMPClauseName(OMPC_lastprivate);
9483 ReportOriginalDSA(*this, DSAStack, D, DVar);
9487 // OpenMP [2.14.3.5, Restrictions, p.2]
9488 // A list item that is private within a parallel region, or that appears in
9489 // the reduction clause of a parallel construct, must not appear in a
9490 // lastprivate clause on a worksharing construct if any of the corresponding
9491 // worksharing regions ever binds to any of the corresponding parallel
9493 DSAStackTy::DSAVarData TopDVar = DVar;
9494 if (isOpenMPWorksharingDirective(CurrDir) &&
9495 !isOpenMPParallelDirective(CurrDir) &&
9496 !isOpenMPTeamsDirective(CurrDir)) {
9497 DVar = DSAStack->getImplicitDSA(D, true);
9498 if (DVar.CKind != OMPC_shared) {
9499 Diag(ELoc, diag::err_omp_required_access)
9500 << getOpenMPClauseName(OMPC_lastprivate)
9501 << getOpenMPClauseName(OMPC_shared);
9502 ReportOriginalDSA(*this, DSAStack, D, DVar);
9507 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9508 // A variable of class type (or array thereof) that appears in a
9509 // lastprivate clause requires an accessible, unambiguous default
9510 // constructor for the class type, unless the list item is also specified
9511 // in a firstprivate clause.
9512 // A variable of class type (or array thereof) that appears in a
9513 // lastprivate clause requires an accessible, unambiguous copy assignment
9514 // operator for the class type.
9515 Type = Context.getBaseElementType(Type).getNonReferenceType();
9516 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9517 Type.getUnqualifiedType(), ".lastprivate.src",
9518 D->hasAttrs() ? &D->getAttrs() : nullptr);
9519 auto *PseudoSrcExpr =
9520 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9522 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9523 D->hasAttrs() ? &D->getAttrs() : nullptr);
9524 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9525 // For arrays generate assignment operation for single element and replace
9526 // it by the original array element in CodeGen.
9527 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9528 PseudoDstExpr, PseudoSrcExpr);
9529 if (AssignmentOp.isInvalid())
9531 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9532 /*DiscardedValue=*/true);
9533 if (AssignmentOp.isInvalid())
9536 DeclRefExpr *Ref = nullptr;
9537 if (!VD && !CurContext->isDependentContext()) {
9538 if (TopDVar.CKind == OMPC_firstprivate)
9539 Ref = TopDVar.PrivateCopy;
9541 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9542 if (!IsOpenMPCapturedDecl(D))
9543 ExprCaptures.push_back(Ref->getDecl());
9545 if (TopDVar.CKind == OMPC_firstprivate ||
9546 (!IsOpenMPCapturedDecl(D) &&
9547 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9548 ExprResult RefRes = DefaultLvalueConversion(Ref);
9549 if (!RefRes.isUsable())
9551 ExprResult PostUpdateRes =
9552 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9554 if (!PostUpdateRes.isUsable())
9556 ExprPostUpdates.push_back(
9557 IgnoredValueConversions(PostUpdateRes.get()).get());
9560 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9561 Vars.push_back((VD || CurContext->isDependentContext())
9562 ? RefExpr->IgnoreParens()
9564 SrcExprs.push_back(PseudoSrcExpr);
9565 DstExprs.push_back(PseudoDstExpr);
9566 AssignmentOps.push_back(AssignmentOp.get());
9572 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9573 Vars, SrcExprs, DstExprs, AssignmentOps,
9574 buildPreInits(Context, ExprCaptures),
9575 buildPostUpdate(*this, ExprPostUpdates));
9578 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
9579 SourceLocation StartLoc,
9580 SourceLocation LParenLoc,
9581 SourceLocation EndLoc) {
9582 SmallVector<Expr *, 8> Vars;
9583 for (auto &RefExpr : VarList) {
9584 assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9585 SourceLocation ELoc;
9587 Expr *SimpleRefExpr = RefExpr;
9588 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9590 // It will be analyzed later.
9591 Vars.push_back(RefExpr);
9593 ValueDecl *D = Res.first;
9597 auto *VD = dyn_cast<VarDecl>(D);
9598 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9600 // Variables with the predetermined data-sharing attributes may not be
9601 // listed in data-sharing attributes clauses, except for the cases
9602 // listed below. For these exceptions only, listing a predetermined
9603 // variable in a data-sharing attribute clause is allowed and overrides
9604 // the variable's predetermined data-sharing attributes.
9605 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9606 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9608 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9609 << getOpenMPClauseName(OMPC_shared);
9610 ReportOriginalDSA(*this, DSAStack, D, DVar);
9614 DeclRefExpr *Ref = nullptr;
9615 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9616 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9617 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9618 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9619 ? RefExpr->IgnoreParens()
9626 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9630 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9634 bool VisitDeclRefExpr(DeclRefExpr *E) {
9635 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
9636 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
9637 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
9639 if (DVar.CKind != OMPC_unknown)
9641 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
9642 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
9643 /*FromParent=*/true);
9644 if (DVarPrivate.CKind != OMPC_unknown)
9650 bool VisitStmt(Stmt *S) {
9651 for (auto Child : S->children()) {
9652 if (Child && Visit(Child))
9657 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
9662 // Transform MemberExpression for specified FieldDecl of current class to
9663 // DeclRefExpr to specified OMPCapturedExprDecl.
9664 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
9665 typedef TreeTransform<TransformExprToCaptures> BaseTransform;
9667 DeclRefExpr *CapturedExpr;
9670 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
9671 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
9673 ExprResult TransformMemberExpr(MemberExpr *E) {
9674 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
9675 E->getMemberDecl() == Field) {
9676 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
9677 return CapturedExpr;
9679 return BaseTransform::TransformMemberExpr(E);
9681 DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
9685 template <typename T>
9686 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups,
9687 const llvm::function_ref<T(ValueDecl *)> &Gen) {
9688 for (auto &Set : Lookups) {
9689 for (auto *D : Set) {
9690 if (auto Res = Gen(cast<ValueDecl>(D)))
9698 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
9699 Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
9700 const DeclarationNameInfo &ReductionId, QualType Ty,
9701 CXXCastPath &BasePath, Expr *UnresolvedReduction) {
9702 if (ReductionIdScopeSpec.isInvalid())
9704 SmallVector<UnresolvedSet<8>, 4> Lookups;
9706 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
9707 Lookup.suppressDiagnostics();
9708 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
9709 auto *D = Lookup.getRepresentativeDecl();
9712 } while (S && !S->isDeclScope(D));
9715 Lookups.push_back(UnresolvedSet<8>());
9716 Lookups.back().append(Lookup.begin(), Lookup.end());
9719 } else if (auto *ULE =
9720 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
9721 Lookups.push_back(UnresolvedSet<8>());
9722 Decl *PrevD = nullptr;
9723 for (auto *D : ULE->decls()) {
9725 Lookups.push_back(UnresolvedSet<8>());
9726 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
9727 Lookups.back().addDecl(DRD);
9731 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
9732 Ty->isInstantiationDependentType() ||
9733 Ty->containsUnexpandedParameterPack() ||
9734 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
9735 return !D->isInvalidDecl() &&
9736 (D->getType()->isDependentType() ||
9737 D->getType()->isInstantiationDependentType() ||
9738 D->getType()->containsUnexpandedParameterPack());
9740 UnresolvedSet<8> ResSet;
9741 for (auto &Set : Lookups) {
9742 ResSet.append(Set.begin(), Set.end());
9743 // The last item marks the end of all declarations at the specified scope.
9744 ResSet.addDecl(Set[Set.size() - 1]);
9746 return UnresolvedLookupExpr::Create(
9747 SemaRef.Context, /*NamingClass=*/nullptr,
9748 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
9749 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
9751 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9752 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
9753 if (!D->isInvalidDecl() &&
9754 SemaRef.Context.hasSameType(D->getType(), Ty))
9758 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9759 if (auto *VD = filterLookupForUDR<ValueDecl *>(
9760 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
9761 if (!D->isInvalidDecl() &&
9762 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
9763 !Ty.isMoreQualifiedThan(D->getType()))
9767 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
9768 /*DetectVirtual=*/false);
9769 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
9770 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
9771 VD->getType().getUnqualifiedType()))) {
9772 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
9774 Sema::AR_inaccessible) {
9775 SemaRef.BuildBasePathArray(Paths, BasePath);
9776 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9781 if (ReductionIdScopeSpec.isSet()) {
9782 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
9789 /// Data for the reduction-based clauses.
9790 struct ReductionData {
9791 /// List of original reduction items.
9792 SmallVector<Expr *, 8> Vars;
9793 /// List of private copies of the reduction items.
9794 SmallVector<Expr *, 8> Privates;
9795 /// LHS expressions for the reduction_op expressions.
9796 SmallVector<Expr *, 8> LHSs;
9797 /// RHS expressions for the reduction_op expressions.
9798 SmallVector<Expr *, 8> RHSs;
9799 /// Reduction operation expression.
9800 SmallVector<Expr *, 8> ReductionOps;
9801 /// Taskgroup descriptors for the corresponding reduction items in
9802 /// in_reduction clauses.
9803 SmallVector<Expr *, 8> TaskgroupDescriptors;
9804 /// List of captures for clause.
9805 SmallVector<Decl *, 4> ExprCaptures;
9806 /// List of postupdate expressions.
9807 SmallVector<Expr *, 4> ExprPostUpdates;
9808 ReductionData() = delete;
9809 /// Reserves required memory for the reduction data.
9810 ReductionData(unsigned Size) {
9812 Privates.reserve(Size);
9815 ReductionOps.reserve(Size);
9816 TaskgroupDescriptors.reserve(Size);
9817 ExprCaptures.reserve(Size);
9818 ExprPostUpdates.reserve(Size);
9820 /// Stores reduction item and reduction operation only (required for dependent
9821 /// reduction item).
9822 void push(Expr *Item, Expr *ReductionOp) {
9823 Vars.emplace_back(Item);
9824 Privates.emplace_back(nullptr);
9825 LHSs.emplace_back(nullptr);
9826 RHSs.emplace_back(nullptr);
9827 ReductionOps.emplace_back(ReductionOp);
9828 TaskgroupDescriptors.emplace_back(nullptr);
9830 /// Stores reduction data.
9831 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
9832 Expr *TaskgroupDescriptor) {
9833 Vars.emplace_back(Item);
9834 Privates.emplace_back(Private);
9835 LHSs.emplace_back(LHS);
9836 RHSs.emplace_back(RHS);
9837 ReductionOps.emplace_back(ReductionOp);
9838 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
9843 static bool CheckOMPArraySectionConstantForReduction(
9844 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
9845 SmallVectorImpl<llvm::APSInt> &ArraySizes) {
9846 const Expr *Length = OASE->getLength();
9847 if (Length == nullptr) {
9848 // For array sections of the form [1:] or [:], we would need to analyze
9849 // the lower bound...
9850 if (OASE->getColonLoc().isValid())
9853 // This is an array subscript which has implicit length 1!
9854 SingleElement = true;
9855 ArraySizes.push_back(llvm::APSInt::get(1));
9857 llvm::APSInt ConstantLengthValue;
9858 if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
9861 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
9862 ArraySizes.push_back(ConstantLengthValue);
9865 // Get the base of this array section and walk up from there.
9866 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9868 // We require length = 1 for all array sections except the right-most to
9869 // guarantee that the memory region is contiguous and has no holes in it.
9870 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
9871 Length = TempOASE->getLength();
9872 if (Length == nullptr) {
9873 // For array sections of the form [1:] or [:], we would need to analyze
9874 // the lower bound...
9875 if (OASE->getColonLoc().isValid())
9878 // This is an array subscript which has implicit length 1!
9879 ArraySizes.push_back(llvm::APSInt::get(1));
9881 llvm::APSInt ConstantLengthValue;
9882 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
9883 ConstantLengthValue.getSExtValue() != 1)
9886 ArraySizes.push_back(ConstantLengthValue);
9888 Base = TempOASE->getBase()->IgnoreParenImpCasts();
9891 // If we have a single element, we don't need to add the implicit lengths.
9892 if (!SingleElement) {
9893 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
9894 // Has implicit length 1!
9895 ArraySizes.push_back(llvm::APSInt::get(1));
9896 Base = TempASE->getBase()->IgnoreParenImpCasts();
9900 // This array section can be privatized as a single value or as a constant
9905 static bool ActOnOMPReductionKindClause(
9906 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
9907 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
9908 SourceLocation ColonLoc, SourceLocation EndLoc,
9909 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
9910 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
9911 auto DN = ReductionId.getName();
9912 auto OOK = DN.getCXXOverloadedOperator();
9913 BinaryOperatorKind BOK = BO_Comma;
9915 ASTContext &Context = S.Context;
9916 // OpenMP [2.14.3.6, reduction clause]
9918 // reduction-identifier is either an identifier or one of the following
9919 // operators: +, -, *, &, |, ^, && and ||
9921 // reduction-identifier is either an id-expression or one of the following
9922 // operators: +, -, *, &, |, ^, && and ||
9949 case OO_Array_Delete:
9958 case OO_GreaterEqual:
9963 case OO_PercentEqual:
9968 case OO_GreaterGreater:
9969 case OO_LessLessEqual:
9970 case OO_GreaterGreaterEqual:
9972 case OO_ExclaimEqual:
9981 case OO_Conditional:
9983 case NUM_OVERLOADED_OPERATORS:
9984 llvm_unreachable("Unexpected reduction identifier");
9986 if (auto *II = DN.getAsIdentifierInfo()) {
9987 if (II->isStr("max"))
9989 else if (II->isStr("min"))
9994 SourceRange ReductionIdRange;
9995 if (ReductionIdScopeSpec.isValid())
9996 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
9998 ReductionIdRange.setBegin(ReductionId.getBeginLoc());
9999 ReductionIdRange.setEnd(ReductionId.getEndLoc());
10001 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10002 bool FirstIter = true;
10003 for (auto RefExpr : VarList) {
10004 assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10005 // OpenMP [2.1, C/C++]
10006 // A list item is a variable or array section, subject to the restrictions
10007 // specified in Section 2.4 on page 42 and in each of the sections
10008 // describing clauses and directives for which a list appears.
10009 // OpenMP [2.14.3.3, Restrictions, p.1]
10010 // A variable that is part of another variable (as an array or
10011 // structure element) cannot appear in a private clause.
10012 if (!FirstIter && IR != ER)
10015 SourceLocation ELoc;
10016 SourceRange ERange;
10017 Expr *SimpleRefExpr = RefExpr;
10018 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10019 /*AllowArraySection=*/true);
10021 // Try to find 'declare reduction' corresponding construct before using
10022 // builtin/overloaded operators.
10023 QualType Type = Context.DependentTy;
10024 CXXCastPath BasePath;
10025 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10026 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10027 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10028 Expr *ReductionOp = nullptr;
10029 if (S.CurContext->isDependentContext() &&
10030 (DeclareReductionRef.isUnset() ||
10031 isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10032 ReductionOp = DeclareReductionRef.get();
10033 // It will be analyzed later.
10034 RD.push(RefExpr, ReductionOp);
10036 ValueDecl *D = Res.first;
10040 Expr *TaskgroupDescriptor = nullptr;
10042 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10043 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10045 Type = ASE->getType().getNonReferenceType();
10047 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10048 if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
10049 Type = ATy->getElementType();
10051 Type = BaseType->getPointeeType();
10052 Type = Type.getNonReferenceType();
10054 Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10055 auto *VD = dyn_cast<VarDecl>(D);
10057 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10058 // A variable that appears in a private clause must not have an incomplete
10059 // type or a reference type.
10060 if (S.RequireCompleteType(ELoc, Type,
10061 diag::err_omp_reduction_incomplete_type))
10063 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10064 // A list item that appears in a reduction clause must not be
10065 // const-qualified.
10066 if (Type.getNonReferenceType().isConstant(Context)) {
10067 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10068 if (!ASE && !OASE) {
10069 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10070 VarDecl::DeclarationOnly;
10071 S.Diag(D->getLocation(),
10072 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10077 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10078 // If a list-item is a reference type then it must bind to the same object
10079 // for all threads of the team.
10080 if (!ASE && !OASE && VD) {
10081 VarDecl *VDDef = VD->getDefinition();
10082 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10083 DSARefChecker Check(Stack);
10084 if (Check.Visit(VDDef->getInit())) {
10085 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10086 << getOpenMPClauseName(ClauseKind) << ERange;
10087 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10093 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10095 // Variables with the predetermined data-sharing attributes may not be
10096 // listed in data-sharing attributes clauses, except for the cases
10097 // listed below. For these exceptions only, listing a predetermined
10098 // variable in a data-sharing attribute clause is allowed and overrides
10099 // the variable's predetermined data-sharing attributes.
10100 // OpenMP [2.14.3.6, Restrictions, p.3]
10101 // Any number of reduction clauses can be specified on the directive,
10102 // but a list item can appear only once in the reduction clauses for that
10104 DSAStackTy::DSAVarData DVar;
10105 DVar = Stack->getTopDSA(D, false);
10106 if (DVar.CKind == OMPC_reduction) {
10107 S.Diag(ELoc, diag::err_omp_once_referenced)
10108 << getOpenMPClauseName(ClauseKind);
10110 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10112 } else if (DVar.CKind != OMPC_unknown) {
10113 S.Diag(ELoc, diag::err_omp_wrong_dsa)
10114 << getOpenMPClauseName(DVar.CKind)
10115 << getOpenMPClauseName(OMPC_reduction);
10116 ReportOriginalDSA(S, Stack, D, DVar);
10120 // OpenMP [2.14.3.6, Restrictions, p.1]
10121 // A list item that appears in a reduction clause of a worksharing
10122 // construct must be shared in the parallel regions to which any of the
10123 // worksharing regions arising from the worksharing construct bind.
10124 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10125 if (isOpenMPWorksharingDirective(CurrDir) &&
10126 !isOpenMPParallelDirective(CurrDir) &&
10127 !isOpenMPTeamsDirective(CurrDir)) {
10128 DVar = Stack->getImplicitDSA(D, true);
10129 if (DVar.CKind != OMPC_shared) {
10130 S.Diag(ELoc, diag::err_omp_required_access)
10131 << getOpenMPClauseName(OMPC_reduction)
10132 << getOpenMPClauseName(OMPC_shared);
10133 ReportOriginalDSA(S, Stack, D, DVar);
10138 // Try to find 'declare reduction' corresponding construct before using
10139 // builtin/overloaded operators.
10140 CXXCastPath BasePath;
10141 ExprResult DeclareReductionRef = buildDeclareReductionRef(
10142 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10143 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10144 if (DeclareReductionRef.isInvalid())
10146 if (S.CurContext->isDependentContext() &&
10147 (DeclareReductionRef.isUnset() ||
10148 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10149 RD.push(RefExpr, DeclareReductionRef.get());
10152 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
10153 // Not allowed reduction identifier is found.
10154 S.Diag(ReductionId.getLocStart(),
10155 diag::err_omp_unknown_reduction_identifier)
10156 << Type << ReductionIdRange;
10160 // OpenMP [2.14.3.6, reduction clause, Restrictions]
10161 // The type of a list item that appears in a reduction clause must be valid
10162 // for the reduction-identifier. For a max or min reduction in C, the type
10163 // of the list item must be an allowed arithmetic data type: char, int,
10164 // float, double, or _Bool, possibly modified with long, short, signed, or
10165 // unsigned. For a max or min reduction in C++, the type of the list item
10166 // must be an allowed arithmetic data type: char, wchar_t, int, float,
10167 // double, or bool, possibly modified with long, short, signed, or unsigned.
10168 if (DeclareReductionRef.isUnset()) {
10169 if ((BOK == BO_GT || BOK == BO_LT) &&
10170 !(Type->isScalarType() ||
10171 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10172 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10173 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10174 if (!ASE && !OASE) {
10175 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10176 VarDecl::DeclarationOnly;
10177 S.Diag(D->getLocation(),
10178 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10183 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10184 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10185 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10186 << getOpenMPClauseName(ClauseKind);
10187 if (!ASE && !OASE) {
10188 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10189 VarDecl::DeclarationOnly;
10190 S.Diag(D->getLocation(),
10191 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10198 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10199 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10200 D->hasAttrs() ? &D->getAttrs() : nullptr);
10201 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10202 D->hasAttrs() ? &D->getAttrs() : nullptr);
10203 auto PrivateTy = Type;
10205 // Try if we can determine constant lengths for all array sections and avoid
10207 bool ConstantLengthOASE = false;
10209 bool SingleElement;
10210 llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
10211 ConstantLengthOASE = CheckOMPArraySectionConstantForReduction(
10212 Context, OASE, SingleElement, ArraySizes);
10214 // If we don't have a single element, we must emit a constant array type.
10215 if (ConstantLengthOASE && !SingleElement) {
10216 for (auto &Size : ArraySizes) {
10217 PrivateTy = Context.getConstantArrayType(
10218 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10223 if ((OASE && !ConstantLengthOASE) ||
10225 D->getType().getNonReferenceType()->isVariablyModifiedType())) {
10226 if (!Context.getTargetInfo().isVLASupported() &&
10227 S.shouldDiagnoseTargetSupportFromOpenMP()) {
10228 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10229 S.Diag(ELoc, diag::note_vla_unsupported);
10232 // For arrays/array sections only:
10233 // Create pseudo array type for private copy. The size for this array will
10234 // be generated during codegen.
10235 // For array subscripts or single variables Private Ty is the same as Type
10236 // (type of the variable or single array element).
10237 PrivateTy = Context.getVariableArrayType(
10239 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10240 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10241 } else if (!ASE && !OASE &&
10242 Context.getAsArrayType(D->getType().getNonReferenceType()))
10243 PrivateTy = D->getType().getNonReferenceType();
10245 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10246 D->hasAttrs() ? &D->getAttrs() : nullptr);
10247 // Add initializer for private variable.
10248 Expr *Init = nullptr;
10249 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10250 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10251 if (DeclareReductionRef.isUsable()) {
10252 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10253 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10254 if (DRD->getInitializer()) {
10256 RHSVD->setInit(DRDRef);
10257 RHSVD->setInitStyle(VarDecl::CallInit);
10265 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10266 if (Type->isScalarType() || Type->isAnyComplexType())
10267 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10271 if (Type->isScalarType() || Type->isAnyComplexType()) {
10272 // '*' and '&&' reduction ops - initializer is '1'.
10273 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10277 // '&' reduction op - initializer is '~0'.
10278 QualType OrigType = Type;
10279 if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10280 Type = ComplexTy->getElementType();
10281 if (Type->isRealFloatingType()) {
10282 llvm::APFloat InitValue =
10283 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10285 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10287 } else if (Type->isScalarType()) {
10288 auto Size = Context.getTypeSize(Type);
10289 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10290 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10291 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10293 if (Init && OrigType->isAnyComplexType()) {
10294 // Init = 0xFFFF + 0xFFFFi;
10295 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10296 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10303 // 'min' reduction op - initializer is 'Largest representable number in
10304 // the reduction list item type'.
10305 // 'max' reduction op - initializer is 'Least representable number in
10306 // the reduction list item type'.
10307 if (Type->isIntegerType() || Type->isPointerType()) {
10308 bool IsSigned = Type->hasSignedIntegerRepresentation();
10309 auto Size = Context.getTypeSize(Type);
10311 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10312 llvm::APInt InitValue =
10313 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10314 : llvm::APInt::getMinValue(Size)
10315 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10316 : llvm::APInt::getMaxValue(Size);
10317 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10318 if (Type->isPointerType()) {
10319 // Cast to pointer type.
10320 auto CastExpr = S.BuildCStyleCastExpr(
10321 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10322 if (CastExpr.isInvalid())
10324 Init = CastExpr.get();
10326 } else if (Type->isRealFloatingType()) {
10327 llvm::APFloat InitValue = llvm::APFloat::getLargest(
10328 Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10329 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10358 llvm_unreachable("Unexpected reduction operation");
10361 if (Init && DeclareReductionRef.isUnset())
10362 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10364 S.ActOnUninitializedDecl(RHSVD);
10365 if (RHSVD->isInvalidDecl())
10367 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
10368 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10369 << Type << ReductionIdRange;
10370 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10371 VarDecl::DeclarationOnly;
10372 S.Diag(D->getLocation(),
10373 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10377 // Store initializer for single element in private copy. Will be used during
10379 PrivateVD->setInit(RHSVD->getInit());
10380 PrivateVD->setInitStyle(RHSVD->getInitStyle());
10381 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10382 ExprResult ReductionOp;
10383 if (DeclareReductionRef.isUsable()) {
10384 QualType RedTy = DeclareReductionRef.get()->getType();
10385 QualType PtrRedTy = Context.getPointerType(RedTy);
10386 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10387 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10388 if (!BasePath.empty()) {
10389 LHS = S.DefaultLvalueConversion(LHS.get());
10390 RHS = S.DefaultLvalueConversion(RHS.get());
10391 LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10392 CK_UncheckedDerivedToBase, LHS.get(),
10393 &BasePath, LHS.get()->getValueKind());
10394 RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10395 CK_UncheckedDerivedToBase, RHS.get(),
10396 &BasePath, RHS.get()->getValueKind());
10398 FunctionProtoType::ExtProtoInfo EPI;
10399 QualType Params[] = {PtrRedTy, PtrRedTy};
10400 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10401 auto *OVE = new (Context) OpaqueValueExpr(
10402 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10403 S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10404 Expr *Args[] = {LHS.get(), RHS.get()};
10405 ReductionOp = new (Context)
10406 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10408 ReductionOp = S.BuildBinOp(
10409 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10410 if (ReductionOp.isUsable()) {
10411 if (BOK != BO_LT && BOK != BO_GT) {
10413 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10414 BO_Assign, LHSDRE, ReductionOp.get());
10416 auto *ConditionalOp = new (Context)
10417 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10418 Type, VK_LValue, OK_Ordinary);
10420 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10421 BO_Assign, LHSDRE, ConditionalOp);
10423 if (ReductionOp.isUsable())
10424 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10426 if (!ReductionOp.isUsable())
10430 // OpenMP [2.15.4.6, Restrictions, p.2]
10431 // A list item that appears in an in_reduction clause of a task construct
10432 // must appear in a task_reduction clause of a construct associated with a
10433 // taskgroup region that includes the participating task in its taskgroup
10434 // set. The construct associated with the innermost region that meets this
10435 // condition must specify the same reduction-identifier as the in_reduction
10437 if (ClauseKind == OMPC_in_reduction) {
10438 SourceRange ParentSR;
10439 BinaryOperatorKind ParentBOK;
10440 const Expr *ParentReductionOp;
10441 Expr *ParentBOKTD, *ParentReductionOpTD;
10442 DSAStackTy::DSAVarData ParentBOKDSA =
10443 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10445 DSAStackTy::DSAVarData ParentReductionOpDSA =
10446 Stack->getTopMostTaskgroupReductionData(
10447 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10448 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10449 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10450 if (!IsParentBOK && !IsParentReductionOp) {
10451 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10454 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10455 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10456 IsParentReductionOp) {
10457 bool EmitError = true;
10458 if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10459 llvm::FoldingSetNodeID RedId, ParentRedId;
10460 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10461 DeclareReductionRef.get()->Profile(RedId, Context,
10462 /*Canonical=*/true);
10463 EmitError = RedId != ParentRedId;
10466 S.Diag(ReductionId.getLocStart(),
10467 diag::err_omp_reduction_identifier_mismatch)
10468 << ReductionIdRange << RefExpr->getSourceRange();
10469 S.Diag(ParentSR.getBegin(),
10470 diag::note_omp_previous_reduction_identifier)
10472 << (IsParentBOK ? ParentBOKDSA.RefExpr
10473 : ParentReductionOpDSA.RefExpr)
10474 ->getSourceRange();
10478 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10479 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
10482 DeclRefExpr *Ref = nullptr;
10483 Expr *VarsExpr = RefExpr->IgnoreParens();
10484 if (!VD && !S.CurContext->isDependentContext()) {
10486 TransformExprToCaptures RebuildToCapture(S, D);
10488 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10489 Ref = RebuildToCapture.getCapturedExpr();
10491 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
10493 if (!S.IsOpenMPCapturedDecl(D)) {
10494 RD.ExprCaptures.emplace_back(Ref->getDecl());
10495 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10496 ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10497 if (!RefRes.isUsable())
10499 ExprResult PostUpdateRes =
10500 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10502 if (!PostUpdateRes.isUsable())
10504 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10505 Stack->getCurrentDirective() == OMPD_taskgroup) {
10506 S.Diag(RefExpr->getExprLoc(),
10507 diag::err_omp_reduction_non_addressable_expression)
10508 << RefExpr->getSourceRange();
10511 RD.ExprPostUpdates.emplace_back(
10512 S.IgnoredValueConversions(PostUpdateRes.get()).get());
10516 // All reduction items are still marked as reduction (to do not increase
10517 // code base size).
10518 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10519 if (CurrDir == OMPD_taskgroup) {
10520 if (DeclareReductionRef.isUsable())
10521 Stack->addTaskgroupReductionData(D, ReductionIdRange,
10522 DeclareReductionRef.get());
10524 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10526 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10527 TaskgroupDescriptor);
10529 return RD.Vars.empty();
10532 OMPClause *Sema::ActOnOpenMPReductionClause(
10533 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10534 SourceLocation ColonLoc, SourceLocation EndLoc,
10535 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10536 ArrayRef<Expr *> UnresolvedReductions) {
10537 ReductionData RD(VarList.size());
10539 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
10540 StartLoc, LParenLoc, ColonLoc, EndLoc,
10541 ReductionIdScopeSpec, ReductionId,
10542 UnresolvedReductions, RD))
10545 return OMPReductionClause::Create(
10546 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10547 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10548 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10549 buildPreInits(Context, RD.ExprCaptures),
10550 buildPostUpdate(*this, RD.ExprPostUpdates));
10553 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
10554 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10555 SourceLocation ColonLoc, SourceLocation EndLoc,
10556 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10557 ArrayRef<Expr *> UnresolvedReductions) {
10558 ReductionData RD(VarList.size());
10560 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction,
10561 VarList, StartLoc, LParenLoc, ColonLoc,
10562 EndLoc, ReductionIdScopeSpec, ReductionId,
10563 UnresolvedReductions, RD))
10566 return OMPTaskReductionClause::Create(
10567 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10568 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10569 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10570 buildPreInits(Context, RD.ExprCaptures),
10571 buildPostUpdate(*this, RD.ExprPostUpdates));
10574 OMPClause *Sema::ActOnOpenMPInReductionClause(
10575 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10576 SourceLocation ColonLoc, SourceLocation EndLoc,
10577 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10578 ArrayRef<Expr *> UnresolvedReductions) {
10579 ReductionData RD(VarList.size());
10581 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
10582 StartLoc, LParenLoc, ColonLoc, EndLoc,
10583 ReductionIdScopeSpec, ReductionId,
10584 UnresolvedReductions, RD))
10587 return OMPInReductionClause::Create(
10588 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10589 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10590 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10591 buildPreInits(Context, RD.ExprCaptures),
10592 buildPostUpdate(*this, RD.ExprPostUpdates));
10595 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
10596 SourceLocation LinLoc) {
10597 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10598 LinKind == OMPC_LINEAR_unknown) {
10599 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10605 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc,
10606 OpenMPLinearClauseKind LinKind,
10608 auto *VD = dyn_cast_or_null<VarDecl>(D);
10609 // A variable must not have an incomplete type or a reference type.
10610 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10612 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10613 !Type->isReferenceType()) {
10614 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10615 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10618 Type = Type.getNonReferenceType();
10620 // A list item must not be const-qualified.
10621 if (Type.isConstant(Context)) {
10622 Diag(ELoc, diag::err_omp_const_variable)
10623 << getOpenMPClauseName(OMPC_linear);
10627 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10628 Diag(D->getLocation(),
10629 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10635 // A list item must be of integral or pointer type.
10636 Type = Type.getUnqualifiedType().getCanonicalType();
10637 const auto *Ty = Type.getTypePtrOrNull();
10638 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
10639 !Ty->isPointerType())) {
10640 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
10644 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10645 Diag(D->getLocation(),
10646 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10654 OMPClause *Sema::ActOnOpenMPLinearClause(
10655 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
10656 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
10657 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
10658 SmallVector<Expr *, 8> Vars;
10659 SmallVector<Expr *, 8> Privates;
10660 SmallVector<Expr *, 8> Inits;
10661 SmallVector<Decl *, 4> ExprCaptures;
10662 SmallVector<Expr *, 4> ExprPostUpdates;
10663 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
10664 LinKind = OMPC_LINEAR_val;
10665 for (auto &RefExpr : VarList) {
10666 assert(RefExpr && "NULL expr in OpenMP linear clause.");
10667 SourceLocation ELoc;
10668 SourceRange ERange;
10669 Expr *SimpleRefExpr = RefExpr;
10670 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10671 /*AllowArraySection=*/false);
10673 // It will be analyzed later.
10674 Vars.push_back(RefExpr);
10675 Privates.push_back(nullptr);
10676 Inits.push_back(nullptr);
10678 ValueDecl *D = Res.first;
10682 QualType Type = D->getType();
10683 auto *VD = dyn_cast<VarDecl>(D);
10685 // OpenMP [2.14.3.7, linear clause]
10686 // A list-item cannot appear in more than one linear clause.
10687 // A list-item that appears in a linear clause cannot appear in any
10688 // other data-sharing attribute clause.
10689 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
10690 if (DVar.RefExpr) {
10691 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10692 << getOpenMPClauseName(OMPC_linear);
10693 ReportOriginalDSA(*this, DSAStack, D, DVar);
10697 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
10699 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
10701 // Build private copy of original var.
10702 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(),
10703 D->hasAttrs() ? &D->getAttrs() : nullptr);
10704 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
10705 // Build var to save initial value.
10706 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
10708 DeclRefExpr *Ref = nullptr;
10709 if (!VD && !CurContext->isDependentContext()) {
10710 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10711 if (!IsOpenMPCapturedDecl(D)) {
10712 ExprCaptures.push_back(Ref->getDecl());
10713 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10714 ExprResult RefRes = DefaultLvalueConversion(Ref);
10715 if (!RefRes.isUsable())
10717 ExprResult PostUpdateRes =
10718 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
10719 SimpleRefExpr, RefRes.get());
10720 if (!PostUpdateRes.isUsable())
10722 ExprPostUpdates.push_back(
10723 IgnoredValueConversions(PostUpdateRes.get()).get());
10727 if (LinKind == OMPC_LINEAR_uval)
10728 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
10730 InitExpr = VD ? SimpleRefExpr : Ref;
10731 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
10732 /*DirectInit=*/false);
10733 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
10735 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
10736 Vars.push_back((VD || CurContext->isDependentContext())
10737 ? RefExpr->IgnoreParens()
10739 Privates.push_back(PrivateRef);
10740 Inits.push_back(InitRef);
10746 Expr *StepExpr = Step;
10747 Expr *CalcStepExpr = nullptr;
10748 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
10749 !Step->isInstantiationDependent() &&
10750 !Step->containsUnexpandedParameterPack()) {
10751 SourceLocation StepLoc = Step->getLocStart();
10752 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
10753 if (Val.isInvalid())
10755 StepExpr = Val.get();
10757 // Build var to save the step value.
10759 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
10760 ExprResult SaveRef =
10761 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
10762 ExprResult CalcStep =
10763 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
10764 CalcStep = ActOnFinishFullExpr(CalcStep.get());
10766 // Warn about zero linear step (it would be probably better specified as
10767 // making corresponding variables 'const').
10768 llvm::APSInt Result;
10769 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
10770 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
10771 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
10772 << (Vars.size() > 1);
10773 if (!IsConstant && CalcStep.isUsable()) {
10774 // Calculate the step beforehand instead of doing this on each iteration.
10775 // (This is not used if the number of iterations may be kfold-ed).
10776 CalcStepExpr = CalcStep.get();
10780 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
10781 ColonLoc, EndLoc, Vars, Privates, Inits,
10782 StepExpr, CalcStepExpr,
10783 buildPreInits(Context, ExprCaptures),
10784 buildPostUpdate(*this, ExprPostUpdates));
10787 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
10788 Expr *NumIterations, Sema &SemaRef,
10789 Scope *S, DSAStackTy *Stack) {
10790 // Walk the vars and build update/final expressions for the CodeGen.
10791 SmallVector<Expr *, 8> Updates;
10792 SmallVector<Expr *, 8> Finals;
10793 Expr *Step = Clause.getStep();
10794 Expr *CalcStep = Clause.getCalcStep();
10795 // OpenMP [2.14.3.7, linear clause]
10796 // If linear-step is not specified it is assumed to be 1.
10797 if (Step == nullptr)
10798 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10799 else if (CalcStep) {
10800 Step = cast<BinaryOperator>(CalcStep)->getLHS();
10802 bool HasErrors = false;
10803 auto CurInit = Clause.inits().begin();
10804 auto CurPrivate = Clause.privates().begin();
10805 auto LinKind = Clause.getModifier();
10806 for (auto &RefExpr : Clause.varlists()) {
10807 SourceLocation ELoc;
10808 SourceRange ERange;
10809 Expr *SimpleRefExpr = RefExpr;
10810 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
10811 /*AllowArraySection=*/false);
10812 ValueDecl *D = Res.first;
10813 if (Res.second || !D) {
10814 Updates.push_back(nullptr);
10815 Finals.push_back(nullptr);
10819 auto &&Info = Stack->isLoopControlVariable(D);
10820 // OpenMP [2.15.11, distribute simd Construct]
10821 // A list item may not appear in a linear clause, unless it is the loop
10822 // iteration variable.
10823 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
10824 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
10826 diag::err_omp_linear_distribute_var_non_loop_iteration);
10827 Updates.push_back(nullptr);
10828 Finals.push_back(nullptr);
10832 Expr *InitExpr = *CurInit;
10834 // Build privatized reference to the current linear var.
10835 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
10837 if (LinKind == OMPC_LINEAR_uval)
10838 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
10841 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
10842 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
10843 /*RefersToCapture=*/true);
10845 // Build update: Var = InitExpr + IV * Step
10849 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
10850 InitExpr, IV, Step, /* Subtract */ false);
10852 Update = *CurPrivate;
10853 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
10854 /*DiscardedValue=*/true);
10856 // Build final: Var = InitExpr + NumIterations * Step
10859 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
10860 InitExpr, NumIterations, Step,
10861 /* Subtract */ false);
10863 Final = *CurPrivate;
10864 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
10865 /*DiscardedValue=*/true);
10867 if (!Update.isUsable() || !Final.isUsable()) {
10868 Updates.push_back(nullptr);
10869 Finals.push_back(nullptr);
10872 Updates.push_back(Update.get());
10873 Finals.push_back(Final.get());
10878 Clause.setUpdates(Updates);
10879 Clause.setFinals(Finals);
10883 OMPClause *Sema::ActOnOpenMPAlignedClause(
10884 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
10885 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
10887 SmallVector<Expr *, 8> Vars;
10888 for (auto &RefExpr : VarList) {
10889 assert(RefExpr && "NULL expr in OpenMP linear clause.");
10890 SourceLocation ELoc;
10891 SourceRange ERange;
10892 Expr *SimpleRefExpr = RefExpr;
10893 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10894 /*AllowArraySection=*/false);
10896 // It will be analyzed later.
10897 Vars.push_back(RefExpr);
10899 ValueDecl *D = Res.first;
10903 QualType QType = D->getType();
10904 auto *VD = dyn_cast<VarDecl>(D);
10906 // OpenMP [2.8.1, simd construct, Restrictions]
10907 // The type of list items appearing in the aligned clause must be
10908 // array, pointer, reference to array, or reference to pointer.
10909 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
10910 const Type *Ty = QType.getTypePtrOrNull();
10911 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
10912 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
10913 << QType << getLangOpts().CPlusPlus << ERange;
10916 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10917 Diag(D->getLocation(),
10918 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10923 // OpenMP [2.8.1, simd construct, Restrictions]
10924 // A list-item cannot appear in more than one aligned clause.
10925 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
10926 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
10927 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
10928 << getOpenMPClauseName(OMPC_aligned);
10932 DeclRefExpr *Ref = nullptr;
10933 if (!VD && IsOpenMPCapturedDecl(D))
10934 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10935 Vars.push_back(DefaultFunctionArrayConversion(
10936 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
10940 // OpenMP [2.8.1, simd construct, Description]
10941 // The parameter of the aligned clause, alignment, must be a constant
10942 // positive integer expression.
10943 // If no optional parameter is specified, implementation-defined default
10944 // alignments for SIMD instructions on the target platforms are assumed.
10945 if (Alignment != nullptr) {
10946 ExprResult AlignResult =
10947 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
10948 if (AlignResult.isInvalid())
10950 Alignment = AlignResult.get();
10955 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
10956 EndLoc, Vars, Alignment);
10959 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
10960 SourceLocation StartLoc,
10961 SourceLocation LParenLoc,
10962 SourceLocation EndLoc) {
10963 SmallVector<Expr *, 8> Vars;
10964 SmallVector<Expr *, 8> SrcExprs;
10965 SmallVector<Expr *, 8> DstExprs;
10966 SmallVector<Expr *, 8> AssignmentOps;
10967 for (auto &RefExpr : VarList) {
10968 assert(RefExpr && "NULL expr in OpenMP copyin clause.");
10969 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10970 // It will be analyzed later.
10971 Vars.push_back(RefExpr);
10972 SrcExprs.push_back(nullptr);
10973 DstExprs.push_back(nullptr);
10974 AssignmentOps.push_back(nullptr);
10978 SourceLocation ELoc = RefExpr->getExprLoc();
10979 // OpenMP [2.1, C/C++]
10980 // A list item is a variable name.
10981 // OpenMP [2.14.4.1, Restrictions, p.1]
10982 // A list item that appears in a copyin clause must be threadprivate.
10983 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
10984 if (!DE || !isa<VarDecl>(DE->getDecl())) {
10985 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
10986 << 0 << RefExpr->getSourceRange();
10990 Decl *D = DE->getDecl();
10991 VarDecl *VD = cast<VarDecl>(D);
10993 QualType Type = VD->getType();
10994 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
10995 // It will be analyzed later.
10996 Vars.push_back(DE);
10997 SrcExprs.push_back(nullptr);
10998 DstExprs.push_back(nullptr);
10999 AssignmentOps.push_back(nullptr);
11003 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11004 // A list item that appears in a copyin clause must be threadprivate.
11005 if (!DSAStack->isThreadPrivate(VD)) {
11006 Diag(ELoc, diag::err_omp_required_access)
11007 << getOpenMPClauseName(OMPC_copyin)
11008 << getOpenMPDirectiveName(OMPD_threadprivate);
11012 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11013 // A variable of class type (or array thereof) that appears in a
11014 // copyin clause requires an accessible, unambiguous copy assignment
11015 // operator for the class type.
11016 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11018 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11019 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11020 auto *PseudoSrcExpr = buildDeclRefExpr(
11021 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11023 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11024 VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11025 auto *PseudoDstExpr =
11026 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11027 // For arrays generate assignment operation for single element and replace
11028 // it by the original array element in CodeGen.
11029 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
11030 PseudoDstExpr, PseudoSrcExpr);
11031 if (AssignmentOp.isInvalid())
11033 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11034 /*DiscardedValue=*/true);
11035 if (AssignmentOp.isInvalid())
11038 DSAStack->addDSA(VD, DE, OMPC_copyin);
11039 Vars.push_back(DE);
11040 SrcExprs.push_back(PseudoSrcExpr);
11041 DstExprs.push_back(PseudoDstExpr);
11042 AssignmentOps.push_back(AssignmentOp.get());
11048 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11049 SrcExprs, DstExprs, AssignmentOps);
11052 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
11053 SourceLocation StartLoc,
11054 SourceLocation LParenLoc,
11055 SourceLocation EndLoc) {
11056 SmallVector<Expr *, 8> Vars;
11057 SmallVector<Expr *, 8> SrcExprs;
11058 SmallVector<Expr *, 8> DstExprs;
11059 SmallVector<Expr *, 8> AssignmentOps;
11060 for (auto &RefExpr : VarList) {
11061 assert(RefExpr && "NULL expr in OpenMP linear clause.");
11062 SourceLocation ELoc;
11063 SourceRange ERange;
11064 Expr *SimpleRefExpr = RefExpr;
11065 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11066 /*AllowArraySection=*/false);
11068 // It will be analyzed later.
11069 Vars.push_back(RefExpr);
11070 SrcExprs.push_back(nullptr);
11071 DstExprs.push_back(nullptr);
11072 AssignmentOps.push_back(nullptr);
11074 ValueDecl *D = Res.first;
11078 QualType Type = D->getType();
11079 auto *VD = dyn_cast<VarDecl>(D);
11081 // OpenMP [2.14.4.2, Restrictions, p.2]
11082 // A list item that appears in a copyprivate clause may not appear in a
11083 // private or firstprivate clause on the single construct.
11084 if (!VD || !DSAStack->isThreadPrivate(VD)) {
11085 auto DVar = DSAStack->getTopDSA(D, false);
11086 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11088 Diag(ELoc, diag::err_omp_wrong_dsa)
11089 << getOpenMPClauseName(DVar.CKind)
11090 << getOpenMPClauseName(OMPC_copyprivate);
11091 ReportOriginalDSA(*this, DSAStack, D, DVar);
11095 // OpenMP [2.11.4.2, Restrictions, p.1]
11096 // All list items that appear in a copyprivate clause must be either
11097 // threadprivate or private in the enclosing context.
11098 if (DVar.CKind == OMPC_unknown) {
11099 DVar = DSAStack->getImplicitDSA(D, false);
11100 if (DVar.CKind == OMPC_shared) {
11101 Diag(ELoc, diag::err_omp_required_access)
11102 << getOpenMPClauseName(OMPC_copyprivate)
11103 << "threadprivate or private in the enclosing context";
11104 ReportOriginalDSA(*this, DSAStack, D, DVar);
11110 // Variably modified types are not supported.
11111 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11112 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11113 << getOpenMPClauseName(OMPC_copyprivate) << Type
11114 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11117 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11118 Diag(D->getLocation(),
11119 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11124 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11125 // A variable of class type (or array thereof) that appears in a
11126 // copyin clause requires an accessible, unambiguous copy assignment
11127 // operator for the class type.
11128 Type = Context.getBaseElementType(Type.getNonReferenceType())
11129 .getUnqualifiedType();
11131 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11132 D->hasAttrs() ? &D->getAttrs() : nullptr);
11133 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11135 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11136 D->hasAttrs() ? &D->getAttrs() : nullptr);
11137 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11138 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11139 PseudoDstExpr, PseudoSrcExpr);
11140 if (AssignmentOp.isInvalid())
11142 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11143 /*DiscardedValue=*/true);
11144 if (AssignmentOp.isInvalid())
11147 // No need to mark vars as copyprivate, they are already threadprivate or
11148 // implicitly private.
11149 assert(VD || IsOpenMPCapturedDecl(D));
11151 VD ? RefExpr->IgnoreParens()
11152 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11153 SrcExprs.push_back(PseudoSrcExpr);
11154 DstExprs.push_back(PseudoDstExpr);
11155 AssignmentOps.push_back(AssignmentOp.get());
11161 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11162 Vars, SrcExprs, DstExprs, AssignmentOps);
11165 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
11166 SourceLocation StartLoc,
11167 SourceLocation LParenLoc,
11168 SourceLocation EndLoc) {
11169 if (VarList.empty())
11172 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11176 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind,
11177 SourceLocation DepLoc, SourceLocation ColonLoc,
11178 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11179 SourceLocation LParenLoc, SourceLocation EndLoc) {
11180 if (DSAStack->getCurrentDirective() == OMPD_ordered &&
11181 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11182 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11183 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11186 if (DSAStack->getCurrentDirective() != OMPD_ordered &&
11187 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11188 DepKind == OMPC_DEPEND_sink)) {
11189 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11190 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11191 << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11192 /*Last=*/OMPC_DEPEND_unknown, Except)
11193 << getOpenMPClauseName(OMPC_depend);
11196 SmallVector<Expr *, 8> Vars;
11197 DSAStackTy::OperatorOffsetTy OpsOffs;
11198 llvm::APSInt DepCounter(/*BitWidth=*/32);
11199 llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11200 if (DepKind == OMPC_DEPEND_sink) {
11201 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
11202 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11203 TotalDepCount.setIsUnsigned(/*Val=*/true);
11206 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
11207 DSAStack->getParentOrderedRegionParam()) {
11208 for (auto &RefExpr : VarList) {
11209 assert(RefExpr && "NULL expr in OpenMP shared clause.");
11210 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11211 // It will be analyzed later.
11212 Vars.push_back(RefExpr);
11216 SourceLocation ELoc = RefExpr->getExprLoc();
11217 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
11218 if (DepKind == OMPC_DEPEND_sink) {
11219 if (DepCounter >= TotalDepCount) {
11220 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11224 // OpenMP [2.13.9, Summary]
11225 // depend(dependence-type : vec), where dependence-type is:
11226 // 'sink' and where vec is the iteration vector, which has the form:
11227 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11228 // where n is the value specified by the ordered clause in the loop
11229 // directive, xi denotes the loop iteration variable of the i-th nested
11230 // loop associated with the loop directive, and di is a constant
11231 // non-negative integer.
11232 if (CurContext->isDependentContext()) {
11233 // It will be analyzed later.
11234 Vars.push_back(RefExpr);
11237 SimpleExpr = SimpleExpr->IgnoreImplicit();
11238 OverloadedOperatorKind OOK = OO_None;
11239 SourceLocation OOLoc;
11240 Expr *LHS = SimpleExpr;
11241 Expr *RHS = nullptr;
11242 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11243 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11244 OOLoc = BO->getOperatorLoc();
11245 LHS = BO->getLHS()->IgnoreParenImpCasts();
11246 RHS = BO->getRHS()->IgnoreParenImpCasts();
11247 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11248 OOK = OCE->getOperator();
11249 OOLoc = OCE->getOperatorLoc();
11250 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11251 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11252 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11253 OOK = MCE->getMethodDecl()
11256 .getCXXOverloadedOperator();
11257 OOLoc = MCE->getCallee()->getExprLoc();
11258 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11259 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11261 SourceLocation ELoc;
11262 SourceRange ERange;
11263 auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11264 /*AllowArraySection=*/false);
11266 // It will be analyzed later.
11267 Vars.push_back(RefExpr);
11269 ValueDecl *D = Res.first;
11273 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11274 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11278 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11279 RHS, OMPC_depend, /*StrictlyPositive=*/false);
11280 if (RHSRes.isInvalid())
11283 if (!CurContext->isDependentContext() &&
11284 DSAStack->getParentOrderedRegionParam() &&
11285 DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
11286 ValueDecl* VD = DSAStack->getParentLoopControlVariable(
11287 DepCounter.getZExtValue());
11289 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11292 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11296 OpsOffs.push_back({RHS, OOK});
11298 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11299 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11303 .getNonReferenceType()
11304 ->isPointerType() &&
11305 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11306 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11307 << RefExpr->getSourceRange();
11310 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11311 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11312 ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
11313 RefExpr->IgnoreParenImpCasts());
11314 getDiagnostics().setSuppressAllDiagnostics(Suppress);
11315 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11316 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11317 << RefExpr->getSourceRange();
11321 Vars.push_back(RefExpr->IgnoreParenImpCasts());
11324 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11325 TotalDepCount > VarList.size() &&
11326 DSAStack->getParentOrderedRegionParam() &&
11327 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11328 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
11329 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11331 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11335 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11336 DepKind, DepLoc, ColonLoc, Vars);
11337 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
11338 DSAStack->addDoacrossDependClause(C, OpsOffs);
11342 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc,
11343 SourceLocation LParenLoc,
11344 SourceLocation EndLoc) {
11345 Expr *ValExpr = Device;
11346 Stmt *HelperValStmt = nullptr;
11348 // OpenMP [2.9.1, Restrictions]
11349 // The device expression must evaluate to a non-negative integer value.
11350 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11351 /*StrictlyPositive=*/false))
11354 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11355 OpenMPDirectiveKind CaptureRegion =
11356 getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11357 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11358 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11359 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11360 HelperValStmt = buildPreInits(Context, Captures);
11363 return new (Context)
11364 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc);
11367 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11368 DSAStackTy *Stack, QualType QTy) {
11370 if (QTy->isIncompleteType(&ND)) {
11371 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11377 /// \brief Return true if it can be proven that the provided array expression
11378 /// (array section or array subscript) does NOT specify the whole size of the
11379 /// array whose base type is \a BaseQTy.
11380 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
11382 QualType BaseQTy) {
11383 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11385 // If this is an array subscript, it refers to the whole size if the size of
11386 // the dimension is constant and equals 1. Also, an array section assumes the
11387 // format of an array subscript if no colon is used.
11388 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11389 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11390 return ATy->getSize().getSExtValue() != 1;
11391 // Size can't be evaluated statically.
11395 assert(OASE && "Expecting array section if not an array subscript.");
11396 auto *LowerBound = OASE->getLowerBound();
11397 auto *Length = OASE->getLength();
11399 // If there is a lower bound that does not evaluates to zero, we are not
11400 // covering the whole dimension.
11402 llvm::APSInt ConstLowerBound;
11403 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11404 return false; // Can't get the integer value as a constant.
11405 if (ConstLowerBound.getSExtValue())
11409 // If we don't have a length we covering the whole dimension.
11413 // If the base is a pointer, we don't have a way to get the size of the
11415 if (BaseQTy->isPointerType())
11418 // We can only check if the length is the same as the size of the dimension
11419 // if we have a constant array.
11420 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11424 llvm::APSInt ConstLength;
11425 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11426 return false; // Can't get the integer value as a constant.
11428 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11431 // Return true if it can be proven that the provided array expression (array
11432 // section or array subscript) does NOT specify a single element of the array
11433 // whose base type is \a BaseQTy.
11434 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
11436 QualType BaseQTy) {
11437 auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11439 // An array subscript always refer to a single element. Also, an array section
11440 // assumes the format of an array subscript if no colon is used.
11441 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11444 assert(OASE && "Expecting array section if not an array subscript.");
11445 auto *Length = OASE->getLength();
11447 // If we don't have a length we have to check if the array has unitary size
11448 // for this dimension. Also, we should always expect a length if the base type
11451 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11452 return ATy->getSize().getSExtValue() != 1;
11453 // We cannot assume anything.
11457 // Check if the length evaluates to 1.
11458 llvm::APSInt ConstLength;
11459 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11460 return false; // Can't get the integer value as a constant.
11462 return ConstLength.getSExtValue() != 1;
11465 // Return the expression of the base of the mappable expression or null if it
11466 // cannot be determined and do all the necessary checks to see if the expression
11467 // is valid as a standalone mappable expression. In the process, record all the
11468 // components of the expression.
11469 static Expr *CheckMapClauseExpressionBase(
11470 Sema &SemaRef, Expr *E,
11471 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
11472 OpenMPClauseKind CKind, bool NoDiagnose) {
11473 SourceLocation ELoc = E->getExprLoc();
11474 SourceRange ERange = E->getSourceRange();
11476 // The base of elements of list in a map clause have to be either:
11477 // - a reference to variable or field.
11478 // - a member expression.
11479 // - an array expression.
11481 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11482 // reference to 'r'.
11489 // #pragma omp target map (S.Arr[:12]);
11493 // We want to retrieve the member expression 'this->S';
11495 Expr *RelevantExpr = nullptr;
11497 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11498 // If a list item is an array section, it must specify contiguous storage.
11500 // For this restriction it is sufficient that we make sure only references
11501 // to variables or fields and array expressions, and that no array sections
11502 // exist except in the rightmost expression (unless they cover the whole
11503 // dimension of the array). E.g. these would be invalid:
11505 // r.ArrS[3:5].Arr[6:7]
11509 // but these would be valid:
11510 // r.ArrS[3].Arr[6:7]
11514 bool AllowUnitySizeArraySection = true;
11515 bool AllowWholeSizeArraySection = true;
11517 while (!RelevantExpr) {
11518 E = E->IgnoreParenImpCasts();
11520 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11521 if (!isa<VarDecl>(CurE->getDecl()))
11524 RelevantExpr = CurE;
11526 // If we got a reference to a declaration, we should not expect any array
11527 // section before that.
11528 AllowUnitySizeArraySection = false;
11529 AllowWholeSizeArraySection = false;
11531 // Record the component.
11532 CurComponents.emplace_back(CurE, CurE->getDecl());
11533 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11534 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11536 if (isa<CXXThisExpr>(BaseE))
11537 // We found a base expression: this->Val.
11538 RelevantExpr = CurE;
11542 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11544 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11545 << CurE->getSourceRange();
11553 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11555 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11556 // A bit-field cannot appear in a map clause.
11558 if (FD->isBitField()) {
11560 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11561 << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11569 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11570 // If the type of a list item is a reference to a type T then the type
11571 // will be considered to be T for all purposes of this clause.
11572 QualType CurType = BaseE->getType().getNonReferenceType();
11574 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11575 // A list item cannot be a variable that is a member of a structure with
11578 if (auto *RT = CurType->getAs<RecordType>()) {
11579 if (RT->isUnionType()) {
11581 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11582 << CurE->getSourceRange();
11589 // If we got a member expression, we should not expect any array section
11592 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11593 // If a list item is an element of a structure, only the rightmost symbol
11594 // of the variable reference can be an array section.
11596 AllowUnitySizeArraySection = false;
11597 AllowWholeSizeArraySection = false;
11599 // Record the component.
11600 CurComponents.emplace_back(CurE, FD);
11601 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11602 E = CurE->getBase()->IgnoreParenImpCasts();
11604 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11606 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11607 << 0 << CurE->getSourceRange();
11613 // If we got an array subscript that express the whole dimension we
11614 // can have any array expressions before. If it only expressing part of
11615 // the dimension, we can only have unitary-size array expressions.
11616 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE,
11618 AllowWholeSizeArraySection = false;
11620 // Record the component - we don't have any declaration associated.
11621 CurComponents.emplace_back(CurE, nullptr);
11622 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11623 assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
11624 E = CurE->getBase()->IgnoreParenImpCasts();
11627 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11629 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11630 // If the type of a list item is a reference to a type T then the type
11631 // will be considered to be T for all purposes of this clause.
11632 if (CurType->isReferenceType())
11633 CurType = CurType->getPointeeType();
11635 bool IsPointer = CurType->isAnyPointerType();
11637 if (!IsPointer && !CurType->isArrayType()) {
11638 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11639 << 0 << CurE->getSourceRange();
11644 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
11646 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
11648 if (AllowWholeSizeArraySection) {
11649 // Any array section is currently allowed. Allowing a whole size array
11650 // section implies allowing a unity array section as well.
11652 // If this array section refers to the whole dimension we can still
11653 // accept other array sections before this one, except if the base is a
11654 // pointer. Otherwise, only unitary sections are accepted.
11655 if (NotWhole || IsPointer)
11656 AllowWholeSizeArraySection = false;
11657 } else if (AllowUnitySizeArraySection && NotUnity) {
11658 // A unity or whole array section is not allowed and that is not
11659 // compatible with the properties of the current array section.
11661 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
11662 << CurE->getSourceRange();
11666 // Record the component - we don't have any declaration associated.
11667 CurComponents.emplace_back(CurE, nullptr);
11670 // If nothing else worked, this is not a valid map clause expression.
11672 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
11679 return RelevantExpr;
11682 // Return true if expression E associated with value VD has conflicts with other
11683 // map information.
11684 static bool CheckMapConflicts(
11685 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
11686 bool CurrentRegionOnly,
11687 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
11688 OpenMPClauseKind CKind) {
11690 SourceLocation ELoc = E->getExprLoc();
11691 SourceRange ERange = E->getSourceRange();
11693 // In order to easily check the conflicts we need to match each component of
11694 // the expression under test with the components of the expressions that are
11695 // already in the stack.
11697 assert(!CurComponents.empty() && "Map clause expression with no components!");
11698 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
11699 "Map clause expression with unexpected base!");
11701 // Variables to help detecting enclosing problems in data environment nests.
11702 bool IsEnclosedByDataEnvironmentExpr = false;
11703 const Expr *EnclosingExpr = nullptr;
11705 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
11706 VD, CurrentRegionOnly,
11707 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef
11709 OpenMPClauseKind) -> bool {
11711 assert(!StackComponents.empty() &&
11712 "Map clause expression with no components!");
11713 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
11714 "Map clause expression with unexpected base!");
11716 // The whole expression in the stack.
11717 auto *RE = StackComponents.front().getAssociatedExpression();
11719 // Expressions must start from the same base. Here we detect at which
11720 // point both expressions diverge from each other and see if we can
11721 // detect if the memory referred to both expressions is contiguous and
11723 auto CI = CurComponents.rbegin();
11724 auto CE = CurComponents.rend();
11725 auto SI = StackComponents.rbegin();
11726 auto SE = StackComponents.rend();
11727 for (; CI != CE && SI != SE; ++CI, ++SI) {
11729 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
11730 // At most one list item can be an array item derived from a given
11731 // variable in map clauses of the same construct.
11732 if (CurrentRegionOnly &&
11733 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
11734 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
11735 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
11736 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
11737 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
11738 diag::err_omp_multiple_array_items_in_map_clause)
11739 << CI->getAssociatedExpression()->getSourceRange();
11740 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
11741 diag::note_used_here)
11742 << SI->getAssociatedExpression()->getSourceRange();
11746 // Do both expressions have the same kind?
11747 if (CI->getAssociatedExpression()->getStmtClass() !=
11748 SI->getAssociatedExpression()->getStmtClass())
11751 // Are we dealing with different variables/fields?
11752 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
11755 // Check if the extra components of the expressions in the enclosing
11756 // data environment are redundant for the current base declaration.
11757 // If they are, the maps completely overlap, which is legal.
11758 for (; SI != SE; ++SI) {
11761 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
11762 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
11763 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>(
11764 SI->getAssociatedExpression())) {
11765 auto *E = OASE->getBase()->IgnoreParenImpCasts();
11767 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
11769 if (Type.isNull() || Type->isAnyPointerType() ||
11770 CheckArrayExpressionDoesNotReferToWholeSize(
11771 SemaRef, SI->getAssociatedExpression(), Type))
11775 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11776 // List items of map clauses in the same construct must not share
11777 // original storage.
11779 // If the expressions are exactly the same or one is a subset of the
11780 // other, it means they are sharing storage.
11781 if (CI == CE && SI == SE) {
11782 if (CurrentRegionOnly) {
11783 if (CKind == OMPC_map)
11784 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11786 assert(CKind == OMPC_to || CKind == OMPC_from);
11787 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11790 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11791 << RE->getSourceRange();
11794 // If we find the same expression in the enclosing data environment,
11796 IsEnclosedByDataEnvironmentExpr = true;
11801 QualType DerivedType =
11802 std::prev(CI)->getAssociatedDeclaration()->getType();
11803 SourceLocation DerivedLoc =
11804 std::prev(CI)->getAssociatedExpression()->getExprLoc();
11806 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11807 // If the type of a list item is a reference to a type T then the type
11808 // will be considered to be T for all purposes of this clause.
11809 DerivedType = DerivedType.getNonReferenceType();
11811 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
11812 // A variable for which the type is pointer and an array section
11813 // derived from that variable must not appear as list items of map
11814 // clauses of the same construct.
11816 // Also, cover one of the cases in:
11817 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11818 // If any part of the original storage of a list item has corresponding
11819 // storage in the device data environment, all of the original storage
11820 // must have corresponding storage in the device data environment.
11822 if (DerivedType->isAnyPointerType()) {
11823 if (CI == CE || SI == SE) {
11826 diag::err_omp_pointer_mapped_along_with_derived_section)
11829 assert(CI != CE && SI != SE);
11830 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
11833 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11834 << RE->getSourceRange();
11838 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11839 // List items of map clauses in the same construct must not share
11840 // original storage.
11842 // An expression is a subset of the other.
11843 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
11844 if (CKind == OMPC_map)
11845 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11847 assert(CKind == OMPC_to || CKind == OMPC_from);
11848 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11851 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11852 << RE->getSourceRange();
11856 // The current expression uses the same base as other expression in the
11857 // data environment but does not contain it completely.
11858 if (!CurrentRegionOnly && SI != SE)
11859 EnclosingExpr = RE;
11861 // The current expression is a subset of the expression in the data
11863 IsEnclosedByDataEnvironmentExpr |=
11864 (!CurrentRegionOnly && CI != CE && SI == SE);
11869 if (CurrentRegionOnly)
11872 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11873 // If any part of the original storage of a list item has corresponding
11874 // storage in the device data environment, all of the original storage must
11875 // have corresponding storage in the device data environment.
11876 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
11877 // If a list item is an element of a structure, and a different element of
11878 // the structure has a corresponding list item in the device data environment
11879 // prior to a task encountering the construct associated with the map clause,
11880 // then the list item must also have a corresponding list item in the device
11881 // data environment prior to the task encountering the construct.
11883 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
11885 diag::err_omp_original_storage_is_shared_and_does_not_contain)
11887 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
11888 << EnclosingExpr->getSourceRange();
11896 // Utility struct that gathers all the related lists associated with a mappable
11898 struct MappableVarListInfo final {
11899 // The list of expressions.
11900 ArrayRef<Expr *> VarList;
11901 // The list of processed expressions.
11902 SmallVector<Expr *, 16> ProcessedVarList;
11903 // The mappble components for each expression.
11904 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
11905 // The base declaration of the variable.
11906 SmallVector<ValueDecl *, 16> VarBaseDeclarations;
11908 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
11909 // We have a list of components and base declarations for each entry in the
11911 VarComponents.reserve(VarList.size());
11912 VarBaseDeclarations.reserve(VarList.size());
11917 // Check the validity of the provided variable list for the provided clause kind
11918 // \a CKind. In the check process the valid expressions, and mappable expression
11919 // components and variables are extracted and used to fill \a Vars,
11920 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
11921 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
11923 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
11924 OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
11925 SourceLocation StartLoc,
11926 OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
11927 bool IsMapTypeImplicit = false) {
11928 // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
11929 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
11930 "Unexpected clause kind with mappable expressions!");
11932 // Keep track of the mappable components and base declarations in this clause.
11933 // Each entry in the list is going to have a list of components associated. We
11934 // record each set of the components so that we can build the clause later on.
11935 // In the end we should have the same amount of declarations and component
11938 for (auto &RE : MVLI.VarList) {
11939 assert(RE && "Null expr in omp to/from/map clause");
11940 SourceLocation ELoc = RE->getExprLoc();
11942 auto *VE = RE->IgnoreParenLValueCasts();
11944 if (VE->isValueDependent() || VE->isTypeDependent() ||
11945 VE->isInstantiationDependent() ||
11946 VE->containsUnexpandedParameterPack()) {
11947 // We can only analyze this information once the missing information is
11949 MVLI.ProcessedVarList.push_back(RE);
11953 auto *SimpleExpr = RE->IgnoreParenCasts();
11955 if (!RE->IgnoreParenImpCasts()->isLValue()) {
11957 diag::err_omp_expected_named_var_member_or_array_expression)
11958 << RE->getSourceRange();
11962 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
11963 ValueDecl *CurDeclaration = nullptr;
11965 // Obtain the array or member expression bases if required. Also, fill the
11966 // components array with all the components identified in the process.
11967 auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents,
11968 CKind, /*NoDiagnose=*/false);
11972 assert(!CurComponents.empty() &&
11973 "Invalid mappable expression information.");
11975 // For the following checks, we rely on the base declaration which is
11976 // expected to be associated with the last component. The declaration is
11977 // expected to be a variable or a field (if 'this' is being mapped).
11978 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
11979 assert(CurDeclaration && "Null decl on map clause.");
11981 CurDeclaration->isCanonicalDecl() &&
11982 "Expecting components to have associated only canonical declarations.");
11984 auto *VD = dyn_cast<VarDecl>(CurDeclaration);
11985 auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
11987 assert((VD || FD) && "Only variables or fields are expected here!");
11990 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
11991 // threadprivate variables cannot appear in a map clause.
11992 // OpenMP 4.5 [2.10.5, target update Construct]
11993 // threadprivate variables cannot appear in a from clause.
11994 if (VD && DSAS->isThreadPrivate(VD)) {
11995 auto DVar = DSAS->getTopDSA(VD, false);
11996 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
11997 << getOpenMPClauseName(CKind);
11998 ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
12002 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12003 // A list item cannot appear in both a map clause and a data-sharing
12004 // attribute clause on the same construct.
12006 // Check conflicts with other map clause expressions. We check the conflicts
12007 // with the current construct separately from the enclosing data
12008 // environment, because the restrictions are different. We only have to
12009 // check conflicts across regions for the map clauses.
12010 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12011 /*CurrentRegionOnly=*/true, CurComponents, CKind))
12013 if (CKind == OMPC_map &&
12014 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12015 /*CurrentRegionOnly=*/false, CurComponents, CKind))
12018 // OpenMP 4.5 [2.10.5, target update Construct]
12019 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12020 // If the type of a list item is a reference to a type T then the type will
12021 // be considered to be T for all purposes of this clause.
12022 QualType Type = CurDeclaration->getType().getNonReferenceType();
12024 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12025 // A list item in a to or from clause must have a mappable type.
12026 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12027 // A list item must have a mappable type.
12028 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12032 if (CKind == OMPC_map) {
12033 // target enter data
12034 // OpenMP [2.10.2, Restrictions, p. 99]
12035 // A map-type must be specified in all map clauses and must be either
12037 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12038 if (DKind == OMPD_target_enter_data &&
12039 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12040 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12041 << (IsMapTypeImplicit ? 1 : 0)
12042 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12043 << getOpenMPDirectiveName(DKind);
12047 // target exit_data
12048 // OpenMP [2.10.3, Restrictions, p. 102]
12049 // A map-type must be specified in all map clauses and must be either
12050 // from, release, or delete.
12051 if (DKind == OMPD_target_exit_data &&
12052 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12053 MapType == OMPC_MAP_delete)) {
12054 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12055 << (IsMapTypeImplicit ? 1 : 0)
12056 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12057 << getOpenMPDirectiveName(DKind);
12061 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12062 // A list item cannot appear in both a map clause and a data-sharing
12063 // attribute clause on the same construct
12064 if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
12065 DKind == OMPD_target_teams_distribute ||
12066 DKind == OMPD_target_teams_distribute_parallel_for ||
12067 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
12068 DKind == OMPD_target_teams_distribute_simd) && VD) {
12069 auto DVar = DSAS->getTopDSA(VD, false);
12070 if (isOpenMPPrivate(DVar.CKind)) {
12071 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12072 << getOpenMPClauseName(DVar.CKind)
12073 << getOpenMPClauseName(OMPC_map)
12074 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12075 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
12081 // Save the current expression.
12082 MVLI.ProcessedVarList.push_back(RE);
12084 // Store the components in the stack so that they can be used to check
12085 // against other clauses later on.
12086 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12087 /*WhereFoundClauseKind=*/OMPC_map);
12089 // Save the components and declaration to create the clause. For purposes of
12090 // the clause creation, any component list that has has base 'this' uses
12091 // null as base declaration.
12092 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12093 MVLI.VarComponents.back().append(CurComponents.begin(),
12094 CurComponents.end());
12095 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12101 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier,
12102 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12103 SourceLocation MapLoc, SourceLocation ColonLoc,
12104 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12105 SourceLocation LParenLoc, SourceLocation EndLoc) {
12106 MappableVarListInfo MVLI(VarList);
12107 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
12108 MapType, IsMapTypeImplicit);
12110 // We need to produce a map clause even if we don't have variables so that
12111 // other diagnostics related with non-existing map clauses are accurate.
12112 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12113 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12114 MVLI.VarComponents, MapTypeModifier, MapType,
12115 IsMapTypeImplicit, MapLoc);
12118 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
12119 TypeResult ParsedType) {
12120 assert(ParsedType.isUsable());
12122 QualType ReductionType = GetTypeFromParser(ParsedType.get());
12123 if (ReductionType.isNull())
12126 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12127 // A type name in a declare reduction directive cannot be a function type, an
12128 // array type, a reference type, or a type qualified with const, volatile or
12130 if (ReductionType.hasQualifiers()) {
12131 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12135 if (ReductionType->isFunctionType()) {
12136 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12139 if (ReductionType->isReferenceType()) {
12140 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12143 if (ReductionType->isArrayType()) {
12144 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12147 return ReductionType;
12150 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
12151 Scope *S, DeclContext *DC, DeclarationName Name,
12152 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12153 AccessSpecifier AS, Decl *PrevDeclInScope) {
12154 SmallVector<Decl *, 8> Decls;
12155 Decls.reserve(ReductionTypes.size());
12157 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12158 forRedeclarationInCurContext());
12159 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12160 // A reduction-identifier may not be re-declared in the current scope for the
12161 // same type or for a type that is compatible according to the base language
12163 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12164 OMPDeclareReductionDecl *PrevDRD = nullptr;
12165 bool InCompoundScope = true;
12166 if (S != nullptr) {
12167 // Find previous declaration with the same name not referenced in other
12169 FunctionScopeInfo *ParentFn = getEnclosingFunction();
12171 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12172 LookupName(Lookup, S);
12173 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12174 /*AllowInlineNamespace=*/false);
12175 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12176 auto Filter = Lookup.makeFilter();
12177 while (Filter.hasNext()) {
12178 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12179 if (InCompoundScope) {
12180 auto I = UsedAsPrevious.find(PrevDecl);
12181 if (I == UsedAsPrevious.end())
12182 UsedAsPrevious[PrevDecl] = false;
12183 if (auto *D = PrevDecl->getPrevDeclInScope())
12184 UsedAsPrevious[D] = true;
12186 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12187 PrevDecl->getLocation();
12190 if (InCompoundScope) {
12191 for (auto &PrevData : UsedAsPrevious) {
12192 if (!PrevData.second) {
12193 PrevDRD = PrevData.first;
12198 } else if (PrevDeclInScope != nullptr) {
12199 auto *PrevDRDInScope = PrevDRD =
12200 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12202 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12203 PrevDRDInScope->getLocation();
12204 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12205 } while (PrevDRDInScope != nullptr);
12207 for (auto &TyData : ReductionTypes) {
12208 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12209 bool Invalid = false;
12210 if (I != PreviousRedeclTypes.end()) {
12211 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12213 Diag(I->second, diag::note_previous_definition);
12216 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12217 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12218 Name, TyData.first, PrevDRD);
12220 DRD->setAccess(AS);
12221 Decls.push_back(DRD);
12223 DRD->setInvalidDecl();
12228 return DeclGroupPtrTy::make(
12229 DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12232 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
12233 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12235 // Enter new function scope.
12236 PushFunctionScope();
12237 getCurFunction()->setHasBranchProtectedScope();
12238 getCurFunction()->setHasOMPDeclareReductionCombiner();
12241 PushDeclContext(S, DRD);
12245 PushExpressionEvaluationContext(
12246 ExpressionEvaluationContext::PotentiallyEvaluated);
12248 QualType ReductionType = DRD->getType();
12249 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12250 // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12251 // uses semantics of argument handles by value, but it should be passed by
12252 // reference. C lang does not support references, so pass all parameters as
12254 // Create 'T omp_in;' variable.
12256 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12257 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12258 // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12259 // uses semantics of argument handles by value, but it should be passed by
12260 // reference. C lang does not support references, so pass all parameters as
12262 // Create 'T omp_out;' variable.
12264 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12265 if (S != nullptr) {
12266 PushOnScopeChains(OmpInParm, S);
12267 PushOnScopeChains(OmpOutParm, S);
12269 DRD->addDecl(OmpInParm);
12270 DRD->addDecl(OmpOutParm);
12274 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
12275 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12276 DiscardCleanupsInEvaluationContext();
12277 PopExpressionEvaluationContext();
12280 PopFunctionScopeInfo();
12282 if (Combiner != nullptr)
12283 DRD->setCombiner(Combiner);
12285 DRD->setInvalidDecl();
12288 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
12289 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12291 // Enter new function scope.
12292 PushFunctionScope();
12293 getCurFunction()->setHasBranchProtectedScope();
12296 PushDeclContext(S, DRD);
12300 PushExpressionEvaluationContext(
12301 ExpressionEvaluationContext::PotentiallyEvaluated);
12303 QualType ReductionType = DRD->getType();
12304 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12305 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12306 // uses semantics of argument handles by value, but it should be passed by
12307 // reference. C lang does not support references, so pass all parameters as
12309 // Create 'T omp_priv;' variable.
12310 auto *OmpPrivParm =
12311 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12312 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12313 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12314 // uses semantics of argument handles by value, but it should be passed by
12315 // reference. C lang does not support references, so pass all parameters as
12317 // Create 'T omp_orig;' variable.
12318 auto *OmpOrigParm =
12319 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12320 if (S != nullptr) {
12321 PushOnScopeChains(OmpPrivParm, S);
12322 PushOnScopeChains(OmpOrigParm, S);
12324 DRD->addDecl(OmpPrivParm);
12325 DRD->addDecl(OmpOrigParm);
12327 return OmpPrivParm;
12330 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
12331 VarDecl *OmpPrivParm) {
12332 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12333 DiscardCleanupsInEvaluationContext();
12334 PopExpressionEvaluationContext();
12337 PopFunctionScopeInfo();
12339 if (Initializer != nullptr) {
12340 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12341 } else if (OmpPrivParm->hasInit()) {
12342 DRD->setInitializer(OmpPrivParm->getInit(),
12343 OmpPrivParm->isDirectInit()
12344 ? OMPDeclareReductionDecl::DirectInit
12345 : OMPDeclareReductionDecl::CopyInit);
12347 DRD->setInvalidDecl();
12351 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
12352 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12353 for (auto *D : DeclReductions.get()) {
12355 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12357 PushOnScopeChains(DRD, S, /*AddToContext=*/false);
12359 D->setInvalidDecl();
12361 return DeclReductions;
12364 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
12365 SourceLocation StartLoc,
12366 SourceLocation LParenLoc,
12367 SourceLocation EndLoc) {
12368 Expr *ValExpr = NumTeams;
12369 Stmt *HelperValStmt = nullptr;
12371 // OpenMP [teams Constrcut, Restrictions]
12372 // The num_teams expression must evaluate to a positive integer value.
12373 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12374 /*StrictlyPositive=*/true))
12377 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12378 OpenMPDirectiveKind CaptureRegion =
12379 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12380 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12381 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12382 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12383 HelperValStmt = buildPreInits(Context, Captures);
12386 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12387 StartLoc, LParenLoc, EndLoc);
12390 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
12391 SourceLocation StartLoc,
12392 SourceLocation LParenLoc,
12393 SourceLocation EndLoc) {
12394 Expr *ValExpr = ThreadLimit;
12395 Stmt *HelperValStmt = nullptr;
12397 // OpenMP [teams Constrcut, Restrictions]
12398 // The thread_limit expression must evaluate to a positive integer value.
12399 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12400 /*StrictlyPositive=*/true))
12403 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12404 OpenMPDirectiveKind CaptureRegion =
12405 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12406 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12407 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12408 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12409 HelperValStmt = buildPreInits(Context, Captures);
12412 return new (Context) OMPThreadLimitClause(
12413 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12416 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
12417 SourceLocation StartLoc,
12418 SourceLocation LParenLoc,
12419 SourceLocation EndLoc) {
12420 Expr *ValExpr = Priority;
12422 // OpenMP [2.9.1, task Constrcut]
12423 // The priority-value is a non-negative numerical scalar expression.
12424 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12425 /*StrictlyPositive=*/false))
12428 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12431 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
12432 SourceLocation StartLoc,
12433 SourceLocation LParenLoc,
12434 SourceLocation EndLoc) {
12435 Expr *ValExpr = Grainsize;
12437 // OpenMP [2.9.2, taskloop Constrcut]
12438 // The parameter of the grainsize clause must be a positive integer
12440 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12441 /*StrictlyPositive=*/true))
12444 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12447 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
12448 SourceLocation StartLoc,
12449 SourceLocation LParenLoc,
12450 SourceLocation EndLoc) {
12451 Expr *ValExpr = NumTasks;
12453 // OpenMP [2.9.2, taskloop Constrcut]
12454 // The parameter of the num_tasks clause must be a positive integer
12456 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12457 /*StrictlyPositive=*/true))
12460 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12463 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
12464 SourceLocation LParenLoc,
12465 SourceLocation EndLoc) {
12466 // OpenMP [2.13.2, critical construct, Description]
12467 // ... where hint-expression is an integer constant expression that evaluates
12468 // to a valid lock hint.
12469 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12470 if (HintExpr.isInvalid())
12472 return new (Context)
12473 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12476 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
12477 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12478 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12479 SourceLocation EndLoc) {
12480 if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12481 std::string Values;
12483 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12485 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12486 << Values << getOpenMPClauseName(OMPC_dist_schedule);
12489 Expr *ValExpr = ChunkSize;
12490 Stmt *HelperValStmt = nullptr;
12492 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12493 !ChunkSize->isInstantiationDependent() &&
12494 !ChunkSize->containsUnexpandedParameterPack()) {
12495 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12497 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12498 if (Val.isInvalid())
12501 ValExpr = Val.get();
12503 // OpenMP [2.7.1, Restrictions]
12504 // chunk_size must be a loop invariant integer expression with a positive
12506 llvm::APSInt Result;
12507 if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12508 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12509 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12510 << "dist_schedule" << ChunkSize->getSourceRange();
12513 } else if (getOpenMPCaptureRegionForClause(
12514 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12516 !CurContext->isDependentContext()) {
12517 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12518 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12519 HelperValStmt = buildPreInits(Context, Captures);
12524 return new (Context)
12525 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12526 Kind, ValExpr, HelperValStmt);
12529 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
12530 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
12531 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12532 SourceLocation KindLoc, SourceLocation EndLoc) {
12533 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12534 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12536 SourceLocation Loc;
12538 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12539 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12540 OMPC_DEFAULTMAP_MODIFIER_tofrom);
12543 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12544 OMPC_DEFAULTMAP_scalar);
12548 Diag(Loc, diag::err_omp_unexpected_clause_value)
12549 << Value << getOpenMPClauseName(OMPC_defaultmap);
12552 DSAStack->setDefaultDMAToFromScalar(StartLoc);
12554 return new (Context)
12555 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12558 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) {
12559 DeclContext *CurLexicalContext = getCurLexicalContext();
12560 if (!CurLexicalContext->isFileContext() &&
12561 !CurLexicalContext->isExternCContext() &&
12562 !CurLexicalContext->isExternCXXContext() &&
12563 !isa<CXXRecordDecl>(CurLexicalContext) &&
12564 !isa<ClassTemplateDecl>(CurLexicalContext) &&
12565 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12566 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12567 Diag(Loc, diag::err_omp_region_not_file_context);
12570 if (IsInOpenMPDeclareTargetContext) {
12571 Diag(Loc, diag::err_omp_enclosed_declare_target);
12575 IsInOpenMPDeclareTargetContext = true;
12579 void Sema::ActOnFinishOpenMPDeclareTargetDirective() {
12580 assert(IsInOpenMPDeclareTargetContext &&
12581 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12583 IsInOpenMPDeclareTargetContext = false;
12586 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
12587 CXXScopeSpec &ScopeSpec,
12588 const DeclarationNameInfo &Id,
12589 OMPDeclareTargetDeclAttr::MapTypeTy MT,
12590 NamedDeclSetType &SameDirectiveDecls) {
12591 LookupResult Lookup(*this, Id, LookupOrdinaryName);
12592 LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12594 if (Lookup.isAmbiguous())
12596 Lookup.suppressDiagnostics();
12598 if (!Lookup.isSingleResult()) {
12599 if (TypoCorrection Corrected =
12600 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12601 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12602 CTK_ErrorRecovery)) {
12603 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12605 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12609 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12613 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12614 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12615 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12616 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
12618 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
12619 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
12621 if (ASTMutationListener *ML = Context.getASTMutationListener())
12622 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
12623 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
12624 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
12625 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
12629 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
12632 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
12633 Sema &SemaRef, Decl *D) {
12636 Decl *LD = nullptr;
12637 if (isa<TagDecl>(D)) {
12638 LD = cast<TagDecl>(D)->getDefinition();
12639 } else if (isa<VarDecl>(D)) {
12640 LD = cast<VarDecl>(D)->getDefinition();
12642 // If this is an implicit variable that is legal and we do not need to do
12644 if (cast<VarDecl>(D)->isImplicit()) {
12645 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12646 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12648 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12649 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12653 } else if (isa<FunctionDecl>(D)) {
12654 const FunctionDecl *FD = nullptr;
12655 if (cast<FunctionDecl>(D)->hasBody(FD))
12656 LD = const_cast<FunctionDecl *>(FD);
12658 // If the definition is associated with the current declaration in the
12659 // target region (it can be e.g. a lambda) that is legal and we do not need
12660 // to do anything else.
12662 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12663 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12665 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12666 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12672 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12673 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
12674 // Outlined declaration is not declared target.
12675 if (LD->isOutOfLine()) {
12676 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12677 SemaRef.Diag(SL, diag::note_used_here) << SR;
12679 DeclContext *DC = LD->getDeclContext();
12681 if (isa<FunctionDecl>(DC) &&
12682 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
12684 DC = DC->getParent();
12689 // Is not declared in target context.
12690 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12691 SemaRef.Diag(SL, diag::note_used_here) << SR;
12693 // Mark decl as declared target to prevent further diagnostic.
12694 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12695 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12697 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener())
12698 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12702 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
12703 Sema &SemaRef, DSAStackTy *Stack,
12705 if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
12707 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType()))
12712 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
12713 SourceLocation IdLoc) {
12714 if (!D || D->isInvalidDecl())
12716 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
12717 SourceLocation SL = E ? E->getLocStart() : D->getLocation();
12718 // 2.10.6: threadprivate variable cannot appear in a declare target directive.
12719 if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12720 if (DSAStack->isThreadPrivate(VD)) {
12721 Diag(SL, diag::err_omp_threadprivate_in_target);
12722 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
12726 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
12727 // Problem if any with var declared with incomplete type will be reported
12728 // as normal, so no need to check it here.
12729 if ((E || !VD->getType()->isIncompleteType()) &&
12730 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
12731 // Mark decl as declared target to prevent further diagnostic.
12732 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
12733 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12734 Context, OMPDeclareTargetDeclAttr::MT_To);
12736 if (ASTMutationListener *ML = Context.getASTMutationListener())
12737 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
12742 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12743 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12744 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12745 OMPDeclareTargetDeclAttr::MT_Link)) {
12746 assert(IdLoc.isValid() && "Source location is expected");
12747 Diag(IdLoc, diag::err_omp_function_in_link_clause);
12748 Diag(FD->getLocation(), diag::note_defined_here) << FD;
12753 // Checking declaration inside declare target region.
12754 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
12755 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
12756 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12757 Context, OMPDeclareTargetDeclAttr::MT_To);
12759 if (ASTMutationListener *ML = Context.getASTMutationListener())
12760 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12764 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
12767 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList,
12768 SourceLocation StartLoc,
12769 SourceLocation LParenLoc,
12770 SourceLocation EndLoc) {
12771 MappableVarListInfo MVLI(VarList);
12772 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
12773 if (MVLI.ProcessedVarList.empty())
12776 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12777 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12778 MVLI.VarComponents);
12781 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList,
12782 SourceLocation StartLoc,
12783 SourceLocation LParenLoc,
12784 SourceLocation EndLoc) {
12785 MappableVarListInfo MVLI(VarList);
12786 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
12787 if (MVLI.ProcessedVarList.empty())
12790 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12791 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12792 MVLI.VarComponents);
12795 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
12796 SourceLocation StartLoc,
12797 SourceLocation LParenLoc,
12798 SourceLocation EndLoc) {
12799 MappableVarListInfo MVLI(VarList);
12800 SmallVector<Expr *, 8> PrivateCopies;
12801 SmallVector<Expr *, 8> Inits;
12803 for (auto &RefExpr : VarList) {
12804 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
12805 SourceLocation ELoc;
12806 SourceRange ERange;
12807 Expr *SimpleRefExpr = RefExpr;
12808 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12810 // It will be analyzed later.
12811 MVLI.ProcessedVarList.push_back(RefExpr);
12812 PrivateCopies.push_back(nullptr);
12813 Inits.push_back(nullptr);
12815 ValueDecl *D = Res.first;
12819 QualType Type = D->getType();
12820 Type = Type.getNonReferenceType().getUnqualifiedType();
12822 auto *VD = dyn_cast<VarDecl>(D);
12824 // Item should be a pointer or reference to pointer.
12825 if (!Type->isPointerType()) {
12826 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
12827 << 0 << RefExpr->getSourceRange();
12831 // Build the private variable and the expression that refers to it.
12832 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
12833 D->hasAttrs() ? &D->getAttrs() : nullptr);
12834 if (VDPrivate->isInvalidDecl())
12837 CurContext->addDecl(VDPrivate);
12838 auto VDPrivateRefExpr = buildDeclRefExpr(
12839 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12841 // Add temporary variable to initialize the private copy of the pointer.
12843 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
12844 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12845 RefExpr->getExprLoc());
12846 AddInitializerToDecl(VDPrivate,
12847 DefaultLvalueConversion(VDInitRefExpr).get(),
12848 /*DirectInit=*/false);
12850 // If required, build a capture to implement the privatization initialized
12851 // with the current list item value.
12852 DeclRefExpr *Ref = nullptr;
12854 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12855 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
12856 PrivateCopies.push_back(VDPrivateRefExpr);
12857 Inits.push_back(VDInitRefExpr);
12859 // We need to add a data sharing attribute for this variable to make sure it
12860 // is correctly captured. A variable that shows up in a use_device_ptr has
12861 // similar properties of a first private variable.
12862 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12864 // Create a mappable component for the list item. List items in this clause
12865 // only need a component.
12866 MVLI.VarBaseDeclarations.push_back(D);
12867 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12868 MVLI.VarComponents.back().push_back(
12869 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D));
12872 if (MVLI.ProcessedVarList.empty())
12875 return OMPUseDevicePtrClause::Create(
12876 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12877 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
12880 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
12881 SourceLocation StartLoc,
12882 SourceLocation LParenLoc,
12883 SourceLocation EndLoc) {
12884 MappableVarListInfo MVLI(VarList);
12885 for (auto &RefExpr : VarList) {
12886 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
12887 SourceLocation ELoc;
12888 SourceRange ERange;
12889 Expr *SimpleRefExpr = RefExpr;
12890 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12892 // It will be analyzed later.
12893 MVLI.ProcessedVarList.push_back(RefExpr);
12895 ValueDecl *D = Res.first;
12899 QualType Type = D->getType();
12900 // item should be a pointer or array or reference to pointer or array
12901 if (!Type.getNonReferenceType()->isPointerType() &&
12902 !Type.getNonReferenceType()->isArrayType()) {
12903 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
12904 << 0 << RefExpr->getSourceRange();
12908 // Check if the declaration in the clause does not show up in any data
12909 // sharing attribute.
12910 auto DVar = DSAStack->getTopDSA(D, false);
12911 if (isOpenMPPrivate(DVar.CKind)) {
12912 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12913 << getOpenMPClauseName(DVar.CKind)
12914 << getOpenMPClauseName(OMPC_is_device_ptr)
12915 << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12916 ReportOriginalDSA(*this, DSAStack, D, DVar);
12920 Expr *ConflictExpr;
12921 if (DSAStack->checkMappableExprComponentListsForDecl(
12922 D, /*CurrentRegionOnly=*/true,
12924 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
12925 OpenMPClauseKind) -> bool {
12926 ConflictExpr = R.front().getAssociatedExpression();
12929 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
12930 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
12931 << ConflictExpr->getSourceRange();
12935 // Store the components in the stack so that they can be used to check
12936 // against other clauses later on.
12937 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D);
12938 DSAStack->addMappableExpressionComponents(
12939 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
12941 // Record the expression we've just processed.
12942 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
12944 // Create a mappable component for the list item. List items in this clause
12945 // only need a component. We use a null declaration to signal fields in
12947 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
12948 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
12949 "Unexpected device pointer expression!");
12950 MVLI.VarBaseDeclarations.push_back(
12951 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
12952 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12953 MVLI.VarComponents.back().push_back(MC);
12956 if (MVLI.ProcessedVarList.empty())
12959 return OMPIsDevicePtrClause::Create(
12960 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12961 MVLI.VarBaseDeclarations, MVLI.VarComponents);