31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang;
64 const Expr *RefExpr =
nullptr;
67 DSAVarData() =
default;
71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
74 using OperatorOffsetTy =
76 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
94 struct MappedExprComponentTy {
98 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102 struct ReductionData {
103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106 ReductionData() =
default;
113 ReductionOp = RefExpr;
116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
119 struct SharingMapTy {
120 DeclSAMapTy SharingMap;
121 DeclReductionMapTy ReductionMap;
122 AlignedMapTy AlignedMap;
123 MappedExprComponentsTy MappedExprComponents;
124 LoopControlVariablesMapTy LCVMap;
131 Scope *CurScope =
nullptr;
136 DoacrossDependMapTy DoacrossDepends;
141 bool NowaitRegion =
false;
142 bool CancelRegion =
false;
143 unsigned AssociatedLoops = 1;
146 Expr *TaskgroupReductionRef =
nullptr;
149 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
151 SharingMapTy() =
default;
157 DeclSAMapTy Threadprivates;
164 bool ForceCapturing =
false;
165 CriticalsWithHintsTy Criticals;
167 using iterator = StackTy::const_reverse_iterator;
169 DSAVarData getDSA(iterator &Iter,
ValueDecl *D)
const;
172 bool isOpenMPLocal(
VarDecl *D, iterator Iter)
const;
174 bool isStackEmpty()
const {
175 return Stack.empty() ||
176 Stack.back().second != CurrentNonCapturingFunctionScope ||
177 Stack.back().first.empty();
181 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
183 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
185 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
186 return ClauseKindMode;
190 bool isForceVarCapturing()
const {
return ForceCapturing; }
191 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
196 Stack.back().second != CurrentNonCapturingFunctionScope)
197 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
198 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
199 Stack.back().first.back().DefaultAttrLoc = Loc;
203 assert(!Stack.back().first.empty() &&
204 "Data-sharing attributes stack is empty!");
205 Stack.back().first.pop_back();
209 void pushFunction() {
211 assert(!isa<CapturingScopeInfo>(CurFnScope));
212 CurrentNonCapturingFunctionScope = CurFnScope;
216 if (!Stack.empty() && Stack.back().second == OldFSI) {
217 assert(Stack.back().first.empty());
220 CurrentNonCapturingFunctionScope =
nullptr;
222 if (!isa<CapturingScopeInfo>(FSI)) {
223 CurrentNonCapturingFunctionScope = FSI;
232 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
235 if (I != Criticals.end())
237 return std::make_pair(
nullptr, llvm::APSInt());
250 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
255 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
258 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
271 const Expr *ReductionRef);
277 Expr *&TaskgroupDescriptor)
const;
282 const Expr *&ReductionRef,
283 Expr *&TaskgroupDescriptor)
const;
285 Expr *getTaskgroupReductionRef()
const {
286 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
287 "taskgroup reference expression requested for non taskgroup " 289 return Stack.back().first.back().TaskgroupReductionRef;
293 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
294 return Stack.back().first[
Level].TaskgroupReductionRef &&
295 cast<DeclRefExpr>(Stack.back().first[
Level].TaskgroupReductionRef)
301 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
303 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
310 bool FromParent)
const;
318 bool FromParent)
const;
324 unsigned Level,
bool NotLastprivate =
false)
const;
328 bool hasExplicitDirective(
330 unsigned Level)
const;
334 const llvm::function_ref<
bool(
337 bool FromParent)
const;
341 return isStackEmpty() ?
OMPD_unknown : Stack.back().first.back().Directive;
345 assert(!isStackEmpty() &&
"No directive at specified level.");
346 return Stack.back().first[
Level].Directive;
350 if (isStackEmpty() || Stack.back().first.size() == 1)
352 return std::next(Stack.back().first.rbegin())->
Directive;
357 assert(!isStackEmpty());
358 Stack.back().first.back().DefaultAttr = DSA_none;
359 Stack.back().first.back().DefaultAttrLoc = Loc;
363 assert(!isStackEmpty());
364 Stack.back().first.back().DefaultAttr = DSA_shared;
365 Stack.back().first.back().DefaultAttrLoc = Loc;
369 assert(!isStackEmpty());
370 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
371 Stack.back().first.back().DefaultMapAttrLoc = Loc;
375 return isStackEmpty() ? DSA_unspecified
376 : Stack.back().first.back().DefaultAttr;
380 : Stack.back().first.back().DefaultAttrLoc;
383 return isStackEmpty() ? DMA_unspecified
384 : Stack.back().first.back().DefaultMapAttr;
387 return Stack.back().first[
Level].DefaultMapAttr;
391 : Stack.back().first.back().DefaultMapAttrLoc;
395 bool isThreadPrivate(
VarDecl *D) {
396 const DSAVarData DVar = getTopDSA(D,
false);
401 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
403 assert(!isStackEmpty());
405 Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
407 Stack.back().first.back().OrderedRegion.reset();
411 bool isOrderedRegion()
const {
414 return Stack.back().first.rbegin()->OrderedRegion.hasValue();
417 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
418 if (isStackEmpty() ||
419 !Stack.back().first.rbegin()->OrderedRegion.hasValue())
420 return std::make_pair(
nullptr,
nullptr);
421 return Stack.back().first.rbegin()->OrderedRegion.getValue();
425 bool isParentOrderedRegion()
const {
426 if (isStackEmpty() || Stack.back().first.size() == 1)
428 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
431 std::pair<const Expr *, OMPOrderedClause *>
432 getParentOrderedRegionParam()
const {
433 if (isStackEmpty() || Stack.back().first.size() == 1 ||
434 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
435 return std::make_pair(
nullptr,
nullptr);
436 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
439 void setNowaitRegion(
bool IsNowait =
true) {
440 assert(!isStackEmpty());
441 Stack.back().first.back().NowaitRegion = IsNowait;
445 bool isParentNowaitRegion()
const {
446 if (isStackEmpty() || Stack.back().first.size() == 1)
448 return std::next(Stack.back().first.rbegin())->NowaitRegion;
451 void setParentCancelRegion(
bool Cancel =
true) {
452 if (!isStackEmpty() && Stack.back().first.size() > 1) {
453 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
454 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
458 bool isCancelRegion()
const {
459 return isStackEmpty() ?
false : Stack.back().first.back().CancelRegion;
463 void setAssociatedLoops(
unsigned Val) {
464 assert(!isStackEmpty());
465 Stack.back().first.back().AssociatedLoops = Val;
468 unsigned getAssociatedLoops()
const {
469 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
475 if (!isStackEmpty() && Stack.back().first.size() > 1) {
476 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
481 bool hasInnerTeamsRegion()
const {
482 return getInnerTeamsRegionLoc().
isValid();
487 : Stack.back().first.back().InnerTeamsRegionLoc;
490 Scope *getCurScope()
const {
491 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
495 : Stack.back().first.back().ConstructLoc;
500 bool checkMappableExprComponentListsForDecl(
501 const ValueDecl *VD,
bool CurrentRegionOnly,
502 const llvm::function_ref<
508 auto SI = Stack.back().first.rbegin();
509 auto SE = Stack.back().first.rend();
514 if (CurrentRegionOnly)
519 for (; SI != SE; ++SI) {
520 auto MI = SI->MappedExprComponents.find(VD);
521 if (MI != SI->MappedExprComponents.end())
523 MI->second.Components)
524 if (Check(L, MI->second.Kind))
532 bool checkMappableExprComponentListsForDeclAtLevel(
534 const llvm::function_ref<
541 auto StartI = Stack.back().first.begin();
542 auto EndI = Stack.back().first.end();
545 std::advance(StartI, Level);
547 auto MI = StartI->MappedExprComponents.find(VD);
548 if (MI != StartI->MappedExprComponents.end())
550 MI->second.Components)
551 if (Check(L, MI->second.Kind))
558 void addMappableExpressionComponents(
562 assert(!isStackEmpty() &&
563 "Not expecting to retrieve components from a empty stack!");
564 MappedExprComponentTy &MEC =
565 Stack.back().first.back().MappedExprComponents[VD];
567 MEC.Components.resize(MEC.Components.size() + 1);
568 MEC.Components.back().append(Components.begin(), Components.end());
569 MEC.Kind = WhereFoundClauseKind;
572 unsigned getNestingLevel()
const {
573 assert(!isStackEmpty());
574 return Stack.back().first.size() - 1;
577 const OperatorOffsetTy &OpsOffs) {
578 assert(!isStackEmpty() && Stack.back().first.size() > 1);
579 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
581 StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
583 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
584 getDoacrossDependClauses()
const {
585 assert(!isStackEmpty());
586 const SharingMapTy &StackElem = Stack.back().first.back();
588 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
589 return llvm::make_range(Ref.begin(), Ref.end());
591 return llvm::make_range(StackElem.DoacrossDepends.end(),
592 StackElem.DoacrossDepends.end());
603 if (
const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
604 E = ExprTemp->getSubExpr();
606 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
607 E = MTE->GetTemporaryExpr();
609 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
610 E = Binder->getSubExpr();
612 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
613 E = ICE->getSubExprAsWritten();
622 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
623 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
624 D = ME->getMemberDecl();
625 const auto *VD = dyn_cast<
VarDecl>(D);
632 FD = FD->getCanonicalDecl();
643 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
646 auto *VD = dyn_cast<
VarDecl>(D);
649 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
655 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
656 DVar.CKind = OMPC_shared;
662 if (VD && VD->hasGlobalStorage())
663 DVar.CKind = OMPC_shared;
667 DVar.CKind = OMPC_shared;
676 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
677 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
678 DVar.CKind = OMPC_private;
682 DVar.DKind = Iter->Directive;
685 if (Iter->SharingMap.count(D)) {
686 const DSAInfo &Data = Iter->SharingMap.lookup(D);
687 DVar.RefExpr = Data.RefExpr.getPointer();
688 DVar.PrivateCopy = Data.PrivateCopy;
689 DVar.CKind = Data.Attributes;
690 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
698 switch (Iter->DefaultAttr) {
700 DVar.CKind = OMPC_shared;
701 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
705 case DSA_unspecified:
710 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
713 DVar.CKind = OMPC_shared;
724 iterator I = Iter, E = Stack.back().first.rend();
732 DVarTemp = getDSA(I, D);
733 if (DVarTemp.CKind != OMPC_shared) {
734 DVar.RefExpr =
nullptr;
735 DVar.CKind = OMPC_firstprivate;
738 }
while (I != E && !isParallelOrTaskRegion(I->Directive));
740 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
749 return getDSA(++Iter, D);
754 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
756 SharingMapTy &StackElem = Stack.back().first.back();
757 auto It = StackElem.AlignedMap.find(D);
758 if (It == StackElem.AlignedMap.end()) {
759 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
760 StackElem.AlignedMap[D] = NewDE;
763 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
768 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
770 SharingMapTy &StackElem = Stack.back().first.back();
771 StackElem.LCVMap.try_emplace(
772 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
775 const DSAStackTy::LCDeclInfo
776 DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
777 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
779 const SharingMapTy &StackElem = Stack.back().first.back();
780 auto It = StackElem.LCVMap.find(D);
781 if (It != StackElem.LCVMap.end())
786 const DSAStackTy::LCDeclInfo
787 DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
788 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
789 "Data-sharing attributes stack is empty");
791 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
792 auto It = StackElem.LCVMap.find(D);
793 if (It != StackElem.LCVMap.end())
798 const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
799 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
800 "Data-sharing attributes stack is empty");
801 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
802 if (StackElem.LCVMap.size() < I)
804 for (
const auto &Pair : StackElem.LCVMap)
805 if (Pair.second.first == I)
814 DSAInfo &Data = Threadprivates[D];
816 Data.RefExpr.setPointer(E);
817 Data.PrivateCopy =
nullptr;
819 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
820 DSAInfo &Data = Stack.back().first.back().SharingMap[D];
821 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
822 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
823 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
824 (isLoopControlVariable(D).first && A == OMPC_private));
825 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
826 Data.RefExpr.setInt(
true);
829 const bool IsLastprivate =
830 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
832 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
833 Data.PrivateCopy = PrivateCopy;
836 Stack.back().first.back().SharingMap[PrivateCopy->
getDecl()];
838 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
839 Data.PrivateCopy =
nullptr;
846 StringRef Name,
const AttrVec *Attrs =
nullptr,
861 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
868 bool RefersToCapture =
false) {
879 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
881 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
882 "Additional reduction info may be specified only for reduction items.");
883 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
884 assert(ReductionData.ReductionRange.isInvalid() &&
885 Stack.back().first.back().Directive == OMPD_taskgroup &&
886 "Additional reduction info may be specified only once for reduction " 888 ReductionData.set(BOK, SR);
889 Expr *&TaskgroupReductionRef =
890 Stack.back().first.back().TaskgroupReductionRef;
891 if (!TaskgroupReductionRef) {
893 SemaRef.Context.VoidPtrTy,
".task_red.");
894 TaskgroupReductionRef =
900 const Expr *ReductionRef) {
902 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
904 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
905 "Additional reduction info may be specified only for reduction items.");
906 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
907 assert(ReductionData.ReductionRange.isInvalid() &&
908 Stack.back().first.back().Directive == OMPD_taskgroup &&
909 "Additional reduction info may be specified only once for reduction " 911 ReductionData.set(ReductionRef, SR);
912 Expr *&TaskgroupReductionRef =
913 Stack.back().first.back().TaskgroupReductionRef;
914 if (!TaskgroupReductionRef) {
916 SemaRef.Context.VoidPtrTy,
".task_red.");
917 TaskgroupReductionRef =
922 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
924 Expr *&TaskgroupDescriptor)
const {
926 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
927 if (Stack.back().first.empty())
929 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
930 E = Stack.back().first.rend();
931 I != E; std::advance(I, 1)) {
932 const DSAInfo &Data = I->SharingMap.lookup(D);
933 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
935 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
936 if (!ReductionData.ReductionOp ||
937 ReductionData.ReductionOp.is<
const Expr *>())
939 SR = ReductionData.ReductionRange;
940 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
941 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 942 "expression for the descriptor is not " 944 TaskgroupDescriptor = I->TaskgroupReductionRef;
945 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
946 Data.PrivateCopy, I->DefaultAttrLoc);
951 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
953 Expr *&TaskgroupDescriptor)
const {
955 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
956 if (Stack.back().first.empty())
958 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
959 E = Stack.back().first.rend();
960 I != E; std::advance(I, 1)) {
961 const DSAInfo &Data = I->SharingMap.lookup(D);
962 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
964 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
965 if (!ReductionData.ReductionOp ||
966 !ReductionData.ReductionOp.is<
const Expr *>())
968 SR = ReductionData.ReductionRange;
969 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
970 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 971 "expression for the descriptor is not " 973 TaskgroupDescriptor = I->TaskgroupReductionRef;
974 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
975 Data.PrivateCopy, I->DefaultAttrLoc);
980 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, iterator Iter)
const {
982 if (!isStackEmpty()) {
983 iterator I = Iter, E = Stack.back().first.rend();
984 Scope *TopScope =
nullptr;
985 while (I != E && !isParallelOrTaskRegion(I->Directive) &&
990 TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
991 Scope *CurScope = getCurScope();
992 while (CurScope != TopScope && !CurScope->
isDeclScope(D))
994 return CurScope != TopScope;
999 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1004 auto *VD = dyn_cast<
VarDecl>(D);
1005 auto TI = Threadprivates.find(D);
1006 if (TI != Threadprivates.end()) {
1007 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1011 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1014 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1023 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1024 SemaRef.getLangOpts().OpenMPUseTLS &&
1025 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1027 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1034 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1035 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1036 !isLoopControlVariable(D).first) {
1037 iterator IterTarget =
1038 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1039 [](
const SharingMapTy &Data) {
1042 if (IterTarget != Stack.back().first.rend()) {
1043 iterator ParentIterTarget = std::next(IterTarget, 1);
1044 for (iterator Iter = Stack.back().first.rbegin();
1045 Iter != ParentIterTarget; std::advance(Iter, 1)) {
1046 if (isOpenMPLocal(VD, Iter)) {
1054 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1055 auto DSAIter = IterTarget->SharingMap.find(D);
1056 if (DSAIter != IterTarget->SharingMap.end() &&
1058 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1062 iterator
End = Stack.back().first.rend();
1063 if (!SemaRef.isOpenMPCapturedByRef(
1067 IterTarget->ConstructLoc);
1087 if (VD && VD->isStaticDataMember()) {
1088 DSAVarData DVarTemp = hasDSA(D,
isOpenMPPrivate, MatchesAlways, FromParent);
1089 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1092 DVar.CKind = OMPC_shared;
1097 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
1098 Type = SemaRef.getASTContext().getBaseElementType(Type);
1105 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1107 RD = CTD->getTemplatedDecl();
1109 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->
hasDefinition() &&
1113 DSAVarData DVarTemp =
1115 MatchesAlways, FromParent);
1116 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1119 DVar.CKind = OMPC_shared;
1125 iterator I = Stack.back().first.rbegin();
1126 iterator EndI = Stack.back().first.rend();
1127 if (FromParent && I != EndI)
1129 auto It = I->SharingMap.find(D);
1130 if (It != I->SharingMap.end()) {
1131 const DSAInfo &Data = It->getSecond();
1132 DVar.RefExpr = Data.RefExpr.getPointer();
1133 DVar.PrivateCopy = Data.PrivateCopy;
1134 DVar.CKind = Data.Attributes;
1135 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1136 DVar.DKind = I->Directive;
1142 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1143 bool FromParent)
const {
1144 if (isStackEmpty()) {
1146 return getDSA(I, D);
1149 iterator StartI = Stack.back().first.rbegin();
1150 iterator EndI = Stack.back().first.rend();
1151 if (FromParent && StartI != EndI)
1152 std::advance(StartI, 1);
1153 return getDSA(StartI, D);
1156 const DSAStackTy::DSAVarData
1160 bool FromParent)
const {
1164 iterator I = Stack.back().first.rbegin();
1165 iterator EndI = Stack.back().first.rend();
1166 if (FromParent && I != EndI)
1168 for (; I != EndI; std::advance(I, 1)) {
1169 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1172 DSAVarData DVar = getDSA(NewI, D);
1173 if (I == NewI && CPred(DVar.CKind))
1179 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1182 bool FromParent)
const {
1186 iterator StartI = Stack.back().first.rbegin();
1187 iterator EndI = Stack.back().first.rend();
1188 if (FromParent && StartI != EndI)
1189 std::advance(StartI, 1);
1190 if (StartI == EndI || !DPred(StartI->Directive))
1192 iterator NewI = StartI;
1193 DSAVarData DVar = getDSA(NewI, D);
1194 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1197 bool DSAStackTy::hasExplicitDSA(
1199 unsigned Level,
bool NotLastprivate)
const {
1203 auto StartI = Stack.back().first.begin();
1204 auto EndI = Stack.back().first.end();
1207 std::advance(StartI, Level);
1208 auto I = StartI->SharingMap.find(D);
1209 return (I != StartI->SharingMap.end()) &&
1210 I->getSecond().RefExpr.getPointer() &&
1211 CPred(I->getSecond().Attributes) &&
1212 (!NotLastprivate || !I->getSecond().RefExpr.getInt());
1215 bool DSAStackTy::hasExplicitDirective(
1217 unsigned Level)
const {
1220 auto StartI = Stack.back().first.begin();
1221 auto EndI = Stack.back().first.end();
1224 std::advance(StartI, Level);
1225 return DPred(StartI->Directive);
1228 bool DSAStackTy::hasDirective(
1232 bool FromParent)
const {
1236 auto StartI = std::next(Stack.back().first.rbegin());
1237 auto EndI = Stack.back().first.rend();
1238 if (FromParent && StartI != EndI)
1239 StartI = std::next(StartI);
1240 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
1241 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1247 void Sema::InitDataSharingAttributesStack() {
1248 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1251 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1253 void Sema::pushOpenMPFunctionRegion() {
1262 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1265 bool IsByRef =
true;
1326 if (Ty->isReferenceType())
1332 bool IsVariableUsedInMapClause =
false;
1333 bool IsVariableAssociatedWithSection =
false;
1335 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1337 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1344 if (WhereFoundClauseKind != OMPC_map)
1347 auto EI = MapExprComponents.rbegin();
1348 auto EE = MapExprComponents.rend();
1350 assert(EI != EE &&
"Invalid map expression!");
1352 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1353 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1359 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1360 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1361 isa<MemberExpr>(EI->getAssociatedExpression())) {
1362 IsVariableAssociatedWithSection =
true;
1371 if (IsVariableUsedInMapClause) {
1374 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1379 !Ty->isScalarType() ||
1380 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1386 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1394 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
1395 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1412 unsigned Sema::getOpenMPNestingLevel()
const {
1413 assert(getLangOpts().OpenMP);
1414 return DSAStack->getNestingLevel();
1419 !
DSAStack->isClauseParsingMode()) ||
1423 return isOpenMPTargetExecutionDirective(K);
1429 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1435 auto *VD = dyn_cast<
VarDecl>(D);
1436 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective()) {
1440 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1446 (!
DSAStack->isClauseParsingMode() ||
1448 auto &&Info =
DSAStack->isLoopControlVariable(D);
1450 (VD && VD->hasLocalStorage() &&
1451 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
1452 (VD &&
DSAStack->isForceVarCapturing()))
1453 return VD ? VD : Info.second;
1454 DSAStackTy::DSAVarData DVarPrivate =
1457 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1462 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1467 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
1468 unsigned Level)
const {
1471 FunctionScopesIndex -= Regions.size();
1475 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1478 (
DSAStack->isClauseParsingMode() &&
1479 DSAStack->getClauseParsingMode() == OMPC_private) ||
1485 DSAStack->isTaskgroupReductionRef(D, Level));
1490 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1493 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
1494 const unsigned NewLevel = I - 1;
1497 if (isOpenMPPrivate(K)) {
1505 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1516 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1517 DefaultMapAttributes::DMA_tofrom_scalar)
1518 OMPC = OMPC_firstprivate;
1523 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1527 unsigned Level)
const {
1528 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1531 const auto *VD = dyn_cast<
VarDecl>(D);
1537 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1542 DSAStack->push(DKind, DirName, CurScope, Loc);
1543 PushExpressionEvaluationContext(
1544 ExpressionEvaluationContext::PotentiallyEvaluated);
1561 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1563 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
1565 for (
Expr *DE : Clause->varlists()) {
1566 if (DE->isValueDependent() || DE->isTypeDependent()) {
1567 PrivateCopies.push_back(
nullptr);
1570 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1571 auto *VD = cast<VarDecl>(DRE->getDecl());
1573 const DSAStackTy::DSAVarData DVar =
1575 if (DVar.CKind == OMPC_lastprivate) {
1582 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
1583 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr, DRE);
1584 ActOnUninitializedDecl(VDPrivate);
1588 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
1592 PrivateCopies.push_back(
nullptr);
1596 if (PrivateCopies.size() == Clause->varlist_size())
1597 Clause->setPrivateCopies(PrivateCopies);
1603 DiscardCleanupsInEvaluationContext();
1604 PopExpressionEvaluationContext();
1608 Expr *NumIterations,
Sema &SemaRef,
1609 Scope *S, DSAStackTy *Stack);
1618 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1619 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1621 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1622 return VD->hasGlobalStorage() &&
1635 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1636 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1638 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1652 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
1660 Id, LookupOrdinaryName, CurScope,
nullptr,
1661 llvm::make_unique<VarDeclFilterCCC>(*
this), CTK_ErrorRecovery)) {
1662 diagnoseTypo(Corrected,
1663 PDiag(Lookup.
empty()
1664 ? diag::err_undeclared_var_use_suggest
1665 : diag::err_omp_expected_var_arg_suggest)
1667 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1670 : diag::err_omp_expected_var_arg)
1684 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1689 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1700 !getCurLexicalContext()->isTranslationUnit()) {
1706 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1721 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1730 (!getCurLexicalContext()->isFileContext() ||
1731 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
1737 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1745 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1751 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1776 CurContext->addDecl(D);
1783 class LocalVarRefChecker final
1789 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1790 if (VD->hasLocalStorage()) {
1792 diag::err_omp_local_var_in_threadprivate_init)
1794 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1795 << VD << VD->getSourceRange();
1801 bool VisitStmt(
const Stmt *S) {
1803 if (Child && Visit(Child))
1808 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
1815 for (
Expr *RefExpr : VarList) {
1816 auto *DE = cast<DeclRefExpr>(RefExpr);
1817 auto *VD = cast<VarDecl>(DE->getDecl());
1821 VD->setReferenced();
1822 VD->markUsed(Context);
1833 if (RequireCompleteType(ILoc, VD->getType(),
1834 diag::err_omp_threadprivate_incomplete_type)) {
1840 if (VD->getType()->isReferenceType()) {
1841 Diag(ILoc, diag::err_omp_ref_type_arg)
1845 Diag(VD->getLocation(),
1846 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1854 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1855 getLangOpts().OpenMPUseTLS &&
1856 getASTContext().getTargetInfo().isTLSSupported())) ||
1857 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1858 !VD->isLocalVarDecl())) {
1859 Diag(ILoc, diag::err_omp_var_thread_local)
1863 Diag(VD->getLocation(),
1864 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1871 if (
const Expr *Init = VD->getAnyInitializer()) {
1872 LocalVarRefChecker Checker(*
this);
1873 if (Checker.Visit(Init))
1877 Vars.push_back(RefExpr);
1879 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1882 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1885 if (!Vars.empty()) {
1895 const DSAStackTy::DSAVarData &DVar,
1896 bool IsLoopIterVar =
false) {
1898 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1903 PDSA_StaticMemberShared,
1904 PDSA_StaticLocalVarShared,
1905 PDSA_LoopIterVarPrivate,
1906 PDSA_LoopIterVarLinear,
1907 PDSA_LoopIterVarLastprivate,
1908 PDSA_ConstVarShared,
1909 PDSA_GlobalVarShared,
1910 PDSA_TaskVarFirstprivate,
1911 PDSA_LocalVarPrivate,
1913 } Reason = PDSA_Implicit;
1914 bool ReportHint =
false;
1916 auto *VD = dyn_cast<
VarDecl>(D);
1917 if (IsLoopIterVar) {
1918 if (DVar.CKind == OMPC_private)
1919 Reason = PDSA_LoopIterVarPrivate;
1920 else if (DVar.CKind == OMPC_lastprivate)
1921 Reason = PDSA_LoopIterVarLastprivate;
1923 Reason = PDSA_LoopIterVarLinear;
1925 DVar.CKind == OMPC_firstprivate) {
1926 Reason = PDSA_TaskVarFirstprivate;
1927 ReportLoc = DVar.ImplicitDSALoc;
1928 }
else if (VD && VD->isStaticLocal())
1929 Reason = PDSA_StaticLocalVarShared;
1930 else if (VD && VD->isStaticDataMember())
1931 Reason = PDSA_StaticMemberShared;
1932 else if (VD && VD->isFileVarDecl())
1933 Reason = PDSA_GlobalVarShared;
1935 Reason = PDSA_ConstVarShared;
1936 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1938 Reason = PDSA_LocalVarPrivate;
1940 if (Reason != PDSA_Implicit) {
1941 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1942 << Reason << ReportHint
1944 }
else if (DVar.ImplicitDSALoc.isValid()) {
1945 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1951 class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
1954 bool ErrorFound =
false;
1959 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
1966 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1967 VD = VD->getCanonicalDecl();
1972 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
1974 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1979 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
1981 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
1990 if (DVar.CKind ==
OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1991 isParallelOrTaskRegion(DKind) &&
1992 VarsWithInheritedDSA.count(VD) == 0) {
1993 VarsWithInheritedDSA[VD] = E;
1998 !Stack->isLoopControlVariable(VD).first) {
1999 if (!Stack->checkMappableExprComponentListsForDecl(
2006 return StackComponents.size() == 1 ||
2008 std::next(StackComponents.rbegin()),
2009 StackComponents.rend(),
2010 [](const OMPClauseMappableExprCommon::
2011 MappableComponent &MC) {
2012 return MC.getAssociatedDeclaration() ==
2014 (isa<OMPArraySectionExpr>(
2015 MC.getAssociatedExpression()) ||
2016 isa<ArraySubscriptExpr>(
2017 MC.getAssociatedExpression()));
2020 bool IsFirstprivate =
false;
2022 if (
const auto *RD =
2023 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2024 IsFirstprivate = RD->isLambda();
2027 (VD->getType().getNonReferenceType()->isScalarType() &&
2028 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2030 ImplicitFirstprivate.emplace_back(E);
2032 ImplicitMap.emplace_back(E);
2041 DVar = Stack->hasInnermostDSA(
2050 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2056 DVar = Stack->getImplicitDSA(VD,
false);
2058 !Stack->isLoopControlVariable(VD).first)
2059 ImplicitFirstprivate.push_back(E);
2071 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
2074 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2078 !Stack->isLoopControlVariable(FD).first &&
2079 !Stack->checkMappableExprComponentListsForDecl(
2084 return isa<CXXThisExpr>(
2086 StackComponents.back().getAssociatedExpression())
2093 if (FD->isBitField())
2095 ImplicitMap.emplace_back(E);
2104 DVar = Stack->hasInnermostDSA(
2113 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2119 DVar = Stack->getImplicitDSA(FD,
false);
2121 !Stack->isLoopControlVariable(FD).first)
2122 ImplicitFirstprivate.push_back(E);
2130 const auto *VD = cast<ValueDecl>(
2131 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2132 if (!Stack->checkMappableExprComponentListsForDecl(
2138 auto CCI = CurComponents.rbegin();
2139 auto CCE = CurComponents.rend();
2140 for (const auto &SC : llvm::reverse(StackComponents)) {
2142 if (CCI->getAssociatedExpression()->getStmtClass() !=
2143 SC.getAssociatedExpression()->getStmtClass())
2144 if (!(isa<OMPArraySectionExpr>(
2145 SC.getAssociatedExpression()) &&
2146 isa<ArraySubscriptExpr>(
2147 CCI->getAssociatedExpression())))
2150 const Decl *CCD = CCI->getAssociatedDeclaration();
2151 const Decl *SCD = SC.getAssociatedDeclaration();
2152 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2153 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2156 std::advance(CCI, 1);
2174 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
2176 for (
Stmt *CC :
C->children()) {
2183 void VisitStmt(
Stmt *S) {
2185 if (
C && !isa<OMPExecutableDirective>(
C))
2190 bool isErrorFound()
const {
return ErrorFound; }
2192 return ImplicitFirstprivate;
2196 return VarsWithInheritedDSA;
2200 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
2207 case OMPD_parallel_for:
2208 case OMPD_parallel_for_simd:
2209 case OMPD_parallel_sections:
2211 case OMPD_teams_distribute:
2212 case OMPD_teams_distribute_simd: {
2217 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2218 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2219 std::make_pair(StringRef(),
QualType())
2225 case OMPD_target_teams:
2226 case OMPD_target_parallel:
2227 case OMPD_target_parallel_for:
2228 case OMPD_target_parallel_for_simd:
2229 case OMPD_target_teams_distribute:
2230 case OMPD_target_teams_distribute_simd: {
2240 std::make_pair(
".global_tid.", KmpInt32Ty),
2241 std::make_pair(
".part_id.", KmpInt32PtrTy),
2242 std::make_pair(
".privates.", VoidPtrTy),
2247 std::make_pair(StringRef(),
QualType())
2253 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2254 AlwaysInlineAttr::CreateImplicit(
2255 Context, AlwaysInlineAttr::Keyword_forceinline));
2257 std::make_pair(StringRef(),
QualType())
2263 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2264 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2265 std::make_pair(StringRef(),
QualType())
2270 ParamsTeamsOrParallel);
2274 case OMPD_target_simd: {
2284 std::make_pair(
".global_tid.", KmpInt32Ty),
2285 std::make_pair(
".part_id.", KmpInt32PtrTy),
2286 std::make_pair(
".privates.", VoidPtrTy),
2291 std::make_pair(StringRef(),
QualType())
2297 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2298 AlwaysInlineAttr::CreateImplicit(
2299 Context, AlwaysInlineAttr::Keyword_forceinline));
2301 std::make_pair(StringRef(),
QualType()));
2312 case OMPD_taskgroup:
2313 case OMPD_distribute:
2314 case OMPD_distribute_simd:
2317 case OMPD_target_data: {
2319 std::make_pair(StringRef(),
QualType())
2335 std::make_pair(
".global_tid.", KmpInt32Ty),
2336 std::make_pair(
".part_id.", KmpInt32PtrTy),
2337 std::make_pair(
".privates.", VoidPtrTy),
2342 std::make_pair(StringRef(),
QualType())
2348 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2349 AlwaysInlineAttr::CreateImplicit(
2350 Context, AlwaysInlineAttr::Keyword_forceinline));
2354 case OMPD_taskloop_simd: {
2372 std::make_pair(
".global_tid.", KmpInt32Ty),
2373 std::make_pair(
".part_id.", KmpInt32PtrTy),
2374 std::make_pair(
".privates.", VoidPtrTy),
2379 std::make_pair(
".lb.", KmpUInt64Ty),
2380 std::make_pair(
".ub.", KmpUInt64Ty),
2381 std::make_pair(
".st.", KmpInt64Ty),
2382 std::make_pair(
".liter.", KmpInt32Ty),
2383 std::make_pair(
".reductions.", VoidPtrTy),
2384 std::make_pair(StringRef(),
QualType())
2390 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2391 AlwaysInlineAttr::CreateImplicit(
2392 Context, AlwaysInlineAttr::Keyword_forceinline));
2395 case OMPD_distribute_parallel_for_simd:
2396 case OMPD_distribute_parallel_for: {
2401 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2402 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2405 std::make_pair(StringRef(),
QualType())
2411 case OMPD_target_teams_distribute_parallel_for:
2412 case OMPD_target_teams_distribute_parallel_for_simd: {
2423 std::make_pair(
".global_tid.", KmpInt32Ty),
2424 std::make_pair(
".part_id.", KmpInt32PtrTy),
2425 std::make_pair(
".privates.", VoidPtrTy),
2430 std::make_pair(StringRef(),
QualType())
2436 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2437 AlwaysInlineAttr::CreateImplicit(
2438 Context, AlwaysInlineAttr::Keyword_forceinline));
2440 std::make_pair(StringRef(),
QualType())
2447 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2448 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2449 std::make_pair(StringRef(),
QualType())
2456 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2457 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2460 std::make_pair(StringRef(),
QualType())
2469 case OMPD_teams_distribute_parallel_for:
2470 case OMPD_teams_distribute_parallel_for_simd: {
2476 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2477 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2478 std::make_pair(StringRef(),
QualType())
2485 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2486 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2489 std::make_pair(StringRef(),
QualType())
2497 case OMPD_target_update:
2498 case OMPD_target_enter_data:
2499 case OMPD_target_exit_data: {
2509 std::make_pair(
".global_tid.", KmpInt32Ty),
2510 std::make_pair(
".part_id.", KmpInt32PtrTy),
2511 std::make_pair(
".privates.", VoidPtrTy),
2516 std::make_pair(StringRef(),
QualType())
2522 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2523 AlwaysInlineAttr::CreateImplicit(
2524 Context, AlwaysInlineAttr::Keyword_forceinline));
2527 case OMPD_threadprivate:
2528 case OMPD_taskyield:
2531 case OMPD_cancellation_point:
2534 case OMPD_declare_reduction:
2535 case OMPD_declare_simd:
2536 case OMPD_declare_target:
2537 case OMPD_end_declare_target:
2538 llvm_unreachable(
"OpenMP Directive is not allowed");
2540 llvm_unreachable(
"Unknown OpenMP directive");
2547 return CaptureRegions.size();
2551 Expr *CaptureExpr,
bool WithInit,
2552 bool AsExpression) {
2553 assert(CaptureExpr);
2573 CED->
addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2583 CD = cast<OMPCapturedExprDecl>(VD);
2605 if (!Res.isUsable())
2620 class CaptureRegionUnwinderRAII {
2627 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
2629 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2630 ~CaptureRegionUnwinderRAII() {
2633 while (--ThisCaptureLevel >= 0)
2642 bool ErrorFound =
false;
2643 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2644 *
this, ErrorFound,
DSAStack->getCurrentDirective());
2662 auto *IRC = cast<OMPInReductionClause>(Clause);
2663 for (
Expr *E : IRC->taskgroup_descriptors())
2665 MarkDeclarationsReferencedInExpr(E);
2669 (getLangOpts().OpenMPUseTLS &&
2670 getASTContext().getTargetInfo().isTLSSupported() &&
2675 if (
auto *E = cast_or_null<Expr>(VarRef)) {
2676 MarkDeclarationsReferencedInExpr(E);
2679 DSAStack->setForceVarCapturing(
false);
2680 }
else if (CaptureRegions.size() > 1 ||
2685 if (
Expr *E =
C->getPostUpdateExpr())
2686 MarkDeclarationsReferencedInExpr(E);
2690 SC = cast<OMPScheduleClause>(Clause);
2692 OC = cast<OMPOrderedClause>(Clause);
2694 LCs.push_back(cast<OMPLinearClause>(Clause));
2702 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2707 diag::err_omp_schedule_nonmonotonic_ordered)
2708 <<
SourceRange(OC->getLocStart(), OC->getLocEnd());
2711 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2713 Diag(
C->getLocStart(), diag::err_omp_linear_ordered)
2714 <<
SourceRange(OC->getLocStart(), OC->getLocEnd());
2720 OC->getNumForLoops()) {
2721 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2741 if (CaptureRegion == ThisCaptureRegion ||
2743 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
2744 for (
Decl *D : DS->decls())
2745 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
2750 SR = ActOnCapturedRegionEnd(SR.
get());
2759 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2762 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2763 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2766 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2776 if (Stack->getCurScope()) {
2779 bool NestingProhibited =
false;
2780 bool CloseNesting =
true;
2781 bool OrphanSeen =
false;
2784 ShouldBeInParallelRegion,
2785 ShouldBeInOrderedRegion,
2786 ShouldBeInTargetRegion,
2787 ShouldBeInTeamsRegion
2788 } Recommend = NoRecommend;
2798 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
2799 ? diag::err_omp_prohibited_region_simd
2800 : diag::warn_omp_nesting_simd);
2801 return CurrentRegion != OMPD_simd;
2803 if (ParentRegion == OMPD_atomic) {
2806 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2809 if (CurrentRegion == OMPD_section) {
2814 if (ParentRegion != OMPD_sections &&
2815 ParentRegion != OMPD_parallel_sections) {
2816 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2829 if (CurrentRegion == OMPD_cancellation_point ||
2830 CurrentRegion == OMPD_cancel) {
2843 !((CancelRegion == OMPD_parallel &&
2844 (ParentRegion == OMPD_parallel ||
2845 ParentRegion == OMPD_target_parallel)) ||
2846 (CancelRegion == OMPD_for &&
2847 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2848 ParentRegion == OMPD_target_parallel_for ||
2849 ParentRegion == OMPD_distribute_parallel_for ||
2850 ParentRegion == OMPD_teams_distribute_parallel_for ||
2851 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2852 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2853 (CancelRegion == OMPD_sections &&
2854 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2855 ParentRegion == OMPD_parallel_sections)));
2856 }
else if (CurrentRegion == OMPD_master) {
2862 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
2868 bool DeadLock = Stack->hasDirective(
2872 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
2873 PreviousCriticalLoc = Loc;
2880 SemaRef.
Diag(StartLoc,
2881 diag::err_omp_prohibited_region_critical_same_name)
2883 if (PreviousCriticalLoc.
isValid())
2884 SemaRef.
Diag(PreviousCriticalLoc,
2885 diag::note_omp_previous_critical_region);
2888 }
else if (CurrentRegion == OMPD_barrier) {
2894 ParentRegion == OMPD_master ||
2895 ParentRegion == OMPD_critical ||
2896 ParentRegion == OMPD_ordered;
2905 ParentRegion == OMPD_master ||
2906 ParentRegion == OMPD_critical ||
2907 ParentRegion == OMPD_ordered;
2908 Recommend = ShouldBeInParallelRegion;
2909 }
else if (CurrentRegion == OMPD_ordered) {
2918 NestingProhibited = ParentRegion == OMPD_critical ||
2921 Stack->isParentOrderedRegion());
2922 Recommend = ShouldBeInOrderedRegion;
2927 NestingProhibited = ParentRegion != OMPD_target;
2929 Recommend = ShouldBeInTargetRegion;
2931 if (!NestingProhibited &&
2934 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2941 Recommend = ShouldBeInParallelRegion;
2943 if (!NestingProhibited &&
2949 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2950 Recommend = ShouldBeInTeamsRegion;
2952 if (!NestingProhibited &&
2959 NestingProhibited = Stack->hasDirective(
2963 OffendingRegion = K;
2969 CloseNesting =
false;
2971 if (NestingProhibited) {
2973 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2976 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
2989 bool ErrorFound =
false;
2990 unsigned NamedModifiersNumber = 0;
2995 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
2999 if (FoundNameModifiers[CurNM]) {
3000 S.
Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
3005 NameModifierLoc.push_back(IC->getNameModifierLoc());
3006 ++NamedModifiersNumber;
3008 FoundNameModifiers[CurNM] = IC;
3015 bool MatchFound =
false;
3016 for (
auto NM : AllowedNameModifiers) {
3023 S.
Diag(IC->getNameModifierLoc(),
3024 diag::err_omp_wrong_if_directive_name_modifier)
3032 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
3033 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3035 diag::err_omp_no_more_if_clause);
3038 std::string Sep(
", ");
3039 unsigned AllowedCnt = 0;
3040 unsigned TotalAllowedNum =
3041 AllowedNameModifiers.size() - NamedModifiersNumber;
3042 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
3045 if (!FoundNameModifiers[NM]) {
3049 if (AllowedCnt + 2 == TotalAllowedNum)
3051 else if (AllowedCnt + 1 != TotalAllowedNum)
3057 diag::err_omp_unnamed_if_clause)
3058 << (TotalAllowedNum > 1) << Values;
3061 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
3081 bool ErrorFound =
false;
3082 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3083 if (AStmt && !CurContext->isDependentContext()) {
3084 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3087 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
3088 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3090 while (--ThisCaptureLevel >= 0)
3091 S = cast<CapturedStmt>(S)->getCapturedStmt();
3092 DSAChecker.Visit(S);
3093 if (DSAChecker.isErrorFound())
3096 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3099 DSAChecker.getImplicitFirstprivate().begin(),
3100 DSAChecker.getImplicitFirstprivate().end());
3102 DSAChecker.getImplicitMap().end());
3105 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
3106 for (
Expr *E : IRC->taskgroup_descriptors())
3108 ImplicitFirstprivates.emplace_back(E);
3111 if (!ImplicitFirstprivates.empty()) {
3112 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3115 ClausesWithImplicit.push_back(Implicit);
3116 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3117 ImplicitFirstprivates.size();
3122 if (!ImplicitMaps.empty()) {
3123 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
3127 ClausesWithImplicit.emplace_back(Implicit);
3129 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3139 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3141 AllowedNameModifiers.push_back(OMPD_parallel);
3144 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3145 VarsWithInheritedDSA);
3148 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3149 VarsWithInheritedDSA);
3152 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3153 EndLoc, VarsWithInheritedDSA);
3156 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3160 assert(ClausesWithImplicit.empty() &&
3161 "No clauses are allowed for 'omp section' directive");
3162 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3165 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3169 assert(ClausesWithImplicit.empty() &&
3170 "No clauses are allowed for 'omp master' directive");
3171 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3174 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3177 case OMPD_parallel_for:
3178 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3179 EndLoc, VarsWithInheritedDSA);
3180 AllowedNameModifiers.push_back(OMPD_parallel);
3182 case OMPD_parallel_for_simd:
3183 Res = ActOnOpenMPParallelForSimdDirective(
3184 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3185 AllowedNameModifiers.push_back(OMPD_parallel);
3187 case OMPD_parallel_sections:
3188 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3190 AllowedNameModifiers.push_back(OMPD_parallel);
3194 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3195 AllowedNameModifiers.push_back(OMPD_task);
3197 case OMPD_taskyield:
3198 assert(ClausesWithImplicit.empty() &&
3199 "No clauses are allowed for 'omp taskyield' directive");
3200 assert(AStmt ==
nullptr &&
3201 "No associated statement allowed for 'omp taskyield' directive");
3202 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3205 assert(ClausesWithImplicit.empty() &&
3206 "No clauses are allowed for 'omp barrier' directive");
3207 assert(AStmt ==
nullptr &&
3208 "No associated statement allowed for 'omp barrier' directive");
3209 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3212 assert(ClausesWithImplicit.empty() &&
3213 "No clauses are allowed for 'omp taskwait' directive");
3214 assert(AStmt ==
nullptr &&
3215 "No associated statement allowed for 'omp taskwait' directive");
3216 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3218 case OMPD_taskgroup:
3219 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3223 assert(AStmt ==
nullptr &&
3224 "No associated statement allowed for 'omp flush' directive");
3225 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3228 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3232 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3237 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3240 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3242 AllowedNameModifiers.push_back(OMPD_target);
3244 case OMPD_target_parallel:
3245 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3247 AllowedNameModifiers.push_back(OMPD_target);
3248 AllowedNameModifiers.push_back(OMPD_parallel);
3250 case OMPD_target_parallel_for:
3251 Res = ActOnOpenMPTargetParallelForDirective(
3252 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3253 AllowedNameModifiers.push_back(OMPD_target);
3254 AllowedNameModifiers.push_back(OMPD_parallel);
3256 case OMPD_cancellation_point:
3257 assert(ClausesWithImplicit.empty() &&
3258 "No clauses are allowed for 'omp cancellation point' directive");
3259 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp " 3260 "cancellation point' directive");
3261 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3264 assert(AStmt ==
nullptr &&
3265 "No associated statement allowed for 'omp cancel' directive");
3266 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3268 AllowedNameModifiers.push_back(OMPD_cancel);
3270 case OMPD_target_data:
3271 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3273 AllowedNameModifiers.push_back(OMPD_target_data);
3275 case OMPD_target_enter_data:
3276 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3278 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3280 case OMPD_target_exit_data:
3281 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3283 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3286 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3287 EndLoc, VarsWithInheritedDSA);
3288 AllowedNameModifiers.push_back(OMPD_taskloop);
3290 case OMPD_taskloop_simd:
3291 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3292 EndLoc, VarsWithInheritedDSA);
3293 AllowedNameModifiers.push_back(OMPD_taskloop);
3295 case OMPD_distribute:
3296 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3297 EndLoc, VarsWithInheritedDSA);
3299 case OMPD_target_update:
3300 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3302 AllowedNameModifiers.push_back(OMPD_target_update);
3304 case OMPD_distribute_parallel_for:
3305 Res = ActOnOpenMPDistributeParallelForDirective(
3306 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3307 AllowedNameModifiers.push_back(OMPD_parallel);
3309 case OMPD_distribute_parallel_for_simd:
3310 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3311 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3312 AllowedNameModifiers.push_back(OMPD_parallel);
3314 case OMPD_distribute_simd:
3315 Res = ActOnOpenMPDistributeSimdDirective(
3316 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3318 case OMPD_target_parallel_for_simd:
3319 Res = ActOnOpenMPTargetParallelForSimdDirective(
3320 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3321 AllowedNameModifiers.push_back(OMPD_target);
3322 AllowedNameModifiers.push_back(OMPD_parallel);
3324 case OMPD_target_simd:
3325 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3326 EndLoc, VarsWithInheritedDSA);
3327 AllowedNameModifiers.push_back(OMPD_target);
3329 case OMPD_teams_distribute:
3330 Res = ActOnOpenMPTeamsDistributeDirective(
3331 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3333 case OMPD_teams_distribute_simd:
3334 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3335 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3337 case OMPD_teams_distribute_parallel_for_simd:
3338 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3339 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3340 AllowedNameModifiers.push_back(OMPD_parallel);
3342 case OMPD_teams_distribute_parallel_for:
3343 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3344 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3345 AllowedNameModifiers.push_back(OMPD_parallel);
3347 case OMPD_target_teams:
3348 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3350 AllowedNameModifiers.push_back(OMPD_target);
3352 case OMPD_target_teams_distribute:
3353 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3354 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3355 AllowedNameModifiers.push_back(OMPD_target);
3357 case OMPD_target_teams_distribute_parallel_for:
3358 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3359 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3360 AllowedNameModifiers.push_back(OMPD_target);
3361 AllowedNameModifiers.push_back(OMPD_parallel);
3363 case OMPD_target_teams_distribute_parallel_for_simd:
3364 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3365 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3366 AllowedNameModifiers.push_back(OMPD_target);
3367 AllowedNameModifiers.push_back(OMPD_parallel);
3369 case OMPD_target_teams_distribute_simd:
3370 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3371 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3372 AllowedNameModifiers.push_back(OMPD_target);
3374 case OMPD_declare_target:
3375 case OMPD_end_declare_target:
3376 case OMPD_threadprivate:
3377 case OMPD_declare_reduction:
3378 case OMPD_declare_simd:
3379 llvm_unreachable(
"OpenMP Directive is not allowed");
3381 llvm_unreachable(
"Unknown OpenMP directive");
3384 for (
const auto &
P : VarsWithInheritedDSA) {
3385 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3386 <<
P.first <<
P.second->getSourceRange();
3388 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3390 if (!AllowedNameModifiers.empty())
3391 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
3404 assert(Aligneds.size() == Alignments.size());
3405 assert(Linears.size() == LinModifiers.size());
3406 assert(Linears.size() == Steps.size());
3407 if (!DG || DG.
get().isNull())
3410 if (!DG.
get().isSingleDecl()) {
3411 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
3414 Decl *ADecl = DG.
get().getSingleDecl();
3415 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3416 ADecl = FTD->getTemplatedDecl();
3429 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3436 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3437 const Expr *UniformedLinearThis =
nullptr;
3438 for (
const Expr *E : Uniforms) {
3440 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3441 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3442 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3443 FD->getParamDecl(PVD->getFunctionScopeIndex())
3445 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3448 if (isa<CXXThisExpr>(E)) {
3449 UniformedLinearThis = E;
3453 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3463 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3464 const Expr *AlignedThis =
nullptr;
3465 for (
const Expr *E : Aligneds) {
3467 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3468 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3470 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3471 FD->getParamDecl(PVD->getFunctionScopeIndex())
3475 if (AlignedArgs.count(CanonPVD) > 0) {
3478 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3479 diag::note_omp_explicit_dsa)
3483 AlignedArgs[CanonPVD] = E;
3485 .getNonReferenceType()
3486 .getUnqualifiedType()
3487 .getCanonicalType();
3490 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3492 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3497 if (isa<CXXThisExpr>(E)) {
3508 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3515 for (
Expr *E : Alignments) {
3518 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3519 NewAligns.push_back(Align.
get());
3530 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3531 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
3532 auto MI = LinModifiers.begin();
3533 for (
const Expr *E : Linears) {
3537 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3538 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3540 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3541 FD->getParamDecl(PVD->getFunctionScopeIndex())
3545 if (LinearArgs.count(CanonPVD) > 0) {
3549 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3550 diag::note_omp_explicit_dsa)
3555 if (UniformedArgs.count(CanonPVD) > 0) {
3559 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3560 diag::note_omp_explicit_dsa)
3564 LinearArgs[CanonPVD] = E;
3569 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
3570 PVD->getOriginalType());
3574 if (isa<CXXThisExpr>(E)) {
3575 if (UniformedLinearThis) {
3580 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
3585 UniformedLinearThis = E;
3589 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
3594 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3597 Expr *NewStep =
nullptr;
3599 for (
Expr *E : Steps) {
3601 if (Step == E || !E) {
3602 NewSteps.push_back(E ? NewStep :
nullptr);
3606 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3607 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3609 if (UniformedArgs.count(CanonPVD) == 0) {
3616 NewSteps.push_back(Step);
3627 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(),
Step)
3630 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3632 NewSteps.push_back(NewStep);
3634 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3635 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
3636 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
3637 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
3638 const_cast<Expr **
>(Linears.data()), Linears.size(),
3639 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
3640 NewSteps.data(), NewSteps.size(), SR);
3642 return ConvertDeclToDeclGroup(ADecl);
3652 auto *CS = cast<CapturedStmt>(AStmt);
3660 setFunctionHasBranchProtectedScope();
3670 class OpenMPIterationSpaceChecker {
3686 Expr *LCRef =
nullptr;
3698 bool TestIsLessOp =
false;
3700 bool TestIsStrictOp =
false;
3702 bool SubtractStep =
false;
3706 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3709 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
3712 bool checkAndSetCond(
Expr *S);
3715 bool checkAndSetInc(
Expr *S);
3717 ValueDecl *getLoopDecl()
const {
return LCDecl; }
3719 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
3721 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
3723 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
3725 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
3727 bool shouldSubtractStep()
const {
return SubtractStep; }
3729 Expr *buildNumIterations(
3730 Scope *S,
const bool LimitedType,
3731 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
3735 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
3738 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3739 DSAStackTy &DSA)
const;
3742 Expr *buildPrivateCounterVar()
const;
3746 Expr *buildCounterStep()
const;
3750 buildOrderedLoopData(
Scope *S,
Expr *Counter,
3751 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3755 bool dependent()
const;
3760 bool checkAndSetIncRHS(
Expr *RHS);
3770 bool OpenMPIterationSpaceChecker::dependent()
const {
3772 assert(!LB && !UB && !
Step);
3775 return LCDecl->getType()->isDependentType() ||
3776 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3777 (
Step &&
Step->isValueDependent());
3780 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
3784 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
3785 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3786 if (!NewLCDecl || !NewLB)
3789 LCRef = NewLCRefExpr;
3790 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3792 if ((Ctor->isCopyOrMoveConstructor() ||
3793 Ctor->isConvertingConstructor(
false)) &&
3794 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3800 bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
3803 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
3804 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3808 TestIsLessOp = LessOp;
3809 TestIsStrictOp = StrictOp;
3810 ConditionSrcRange = SR;
3817 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
3827 NewStep = Val.
get();
3844 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3846 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3847 bool IsConstZero = IsConstant && !Result.getBoolValue();
3848 if (UB && (IsConstZero ||
3849 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3850 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3852 diag::err_omp_loop_incr_not_compatible)
3854 SemaRef.
Diag(ConditionLoc,
3855 diag::note_omp_loop_cond_requres_compatible_incr)
3856 << TestIsLessOp << ConditionSrcRange;
3859 if (TestIsLessOp == Subtract) {
3863 Subtract = !Subtract;
3868 SubtractStep = Subtract;
3872 bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
3883 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3887 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3888 if (!ExprTemp->cleanupsHaveSideEffects())
3889 S = ExprTemp->getSubExpr();
3892 if (
Expr *E = dyn_cast<Expr>(S))
3894 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3895 if (BO->getOpcode() == BO_Assign) {
3897 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3898 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3900 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3901 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3903 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3904 if (ME->isArrow() &&
3905 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3906 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3909 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
3910 if (DS->isSingleDecl()) {
3911 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3912 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3916 diag::ext_omp_loop_not_canonical_init)
3918 return setLCDeclAndLB(
3921 Var->getType().getNonReferenceType(),
3927 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3928 if (CE->getOperator() == OO_Equal) {
3929 Expr *LHS = CE->getArg(0);
3930 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3931 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3933 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3934 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3936 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3937 if (ME->isArrow() &&
3938 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3939 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3959 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3961 if ((Ctor->isCopyOrMoveConstructor() ||
3962 Ctor->isConvertingConstructor(
false)) &&
3963 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3965 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3966 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3969 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
3970 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3975 bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
3983 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3988 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3989 if (BO->isRelationalOp()) {
3990 if (getInitLCDecl(BO->getLHS()) == LCDecl)
3991 return setUB(BO->getRHS(),
3992 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3993 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3994 BO->getSourceRange(), BO->getOperatorLoc());
3995 if (getInitLCDecl(BO->getRHS()) == LCDecl)
3996 return setUB(BO->getLHS(),
3997 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3998 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3999 BO->getSourceRange(), BO->getOperatorLoc());
4001 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4002 if (CE->getNumArgs() == 2) {
4003 auto Op = CE->getOperator();
4006 case OO_GreaterEqual:
4009 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4010 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4011 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4012 CE->getOperatorLoc());
4013 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4014 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4015 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4016 CE->getOperatorLoc());
4025 SemaRef.
Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4030 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
4037 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4038 if (BO->isAdditiveOp()) {
4039 bool IsAdd = BO->getOpcode() == BO_Add;
4040 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4041 return setStep(BO->getRHS(), !IsAdd);
4042 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4043 return setStep(BO->getLHS(),
false);
4045 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4046 bool IsAdd = CE->getOperator() == OO_Plus;
4047 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4048 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4049 return setStep(CE->getArg(1), !IsAdd);
4050 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4051 return setStep(CE->getArg(0),
false);
4056 SemaRef.
Diag(RHS->
getLocStart(), diag::err_omp_loop_not_canonical_incr)
4061 bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
4076 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4079 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4080 if (!ExprTemp->cleanupsHaveSideEffects())
4081 S = ExprTemp->getSubExpr();
4085 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
4086 if (UO->isIncrementDecrementOp() &&
4087 getInitLCDecl(UO->getSubExpr()) == LCDecl)
4089 .ActOnIntegerConstant(UO->getLocStart(),
4090 (UO->isDecrementOp() ? -1 : 1))
4093 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
4094 switch (BO->getOpcode()) {
4097 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4098 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4101 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4102 return checkAndSetIncRHS(BO->getRHS());
4107 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4108 switch (CE->getOperator()) {
4111 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4113 .ActOnIntegerConstant(
4115 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4121 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4122 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4125 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4126 return checkAndSetIncRHS(CE->getArg(1));
4140 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
4141 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4148 auto I = Captures.find(Capture);
4149 if (I != Captures.end())
4153 Captures[Capture] = Ref;
4158 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4159 Scope *S,
const bool LimitedType,
4160 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
4162 QualType VarType = LCDecl->getType().getNonReferenceType();
4166 Expr *UBExpr = TestIsLessOp ? UB : LB;
4167 Expr *LBExpr = TestIsLessOp ? LB : UB;
4168 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4169 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4170 if (!Upper || !Lower)
4173 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4190 S, DefaultLoc, BO_Sub, Diff.
get(),
4199 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.
get());
4209 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
4232 unsigned NewSize = (C.
getTypeSize(Type) > 32) ? 64 : 32;
4235 assert(NewSize == 64 &&
"incorrect loop var size");
4236 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4237 << InitSrcRange << ConditionSrcRange;
4254 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4256 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
4261 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4262 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4268 TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4269 : (TestIsStrictOp ? BO_GT : BO_GE),
4270 NewLB.
get(), NewUB.
get());
4280 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
4284 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4285 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4286 DSAStackTy &DSA)
const {
4287 auto *VD = dyn_cast<
VarDecl>(LCDecl);
4291 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4292 const DSAStackTy::DSAVarData Data =
4293 DSA.getTopDSA(LCDecl,
false);
4297 Captures.insert(std::make_pair(LCRef, Ref));
4304 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
4305 if (LCDecl && !LCDecl->isInvalidDecl()) {
4306 QualType Type = LCDecl->getType().getNonReferenceType();
4308 SemaRef, DefaultLoc, Type, LCDecl->getName(),
4309 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr,
4310 isa<VarDecl>(LCDecl)
4324 Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
4326 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4328 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
4334 assert((OOK == OO_Plus || OOK == OO_Minus) &&
4335 "Expected only + or - operations for depend clauses.");
4342 QualType VarType = LCDecl->getType().getNonReferenceType();
4347 TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4349 TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4350 if (!Upper || !Lower)
4353 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4376 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
4384 struct LoopIterationSpace final {
4386 Expr *PreCond =
nullptr;
4389 Expr *NumIterations =
nullptr;
4391 Expr *CounterVar =
nullptr;
4393 Expr *PrivateCounterVar =
nullptr;
4395 Expr *CounterInit =
nullptr;
4398 Expr *CounterStep =
nullptr;
4400 bool Subtract =
false;
4412 assert(getLangOpts().OpenMP &&
"OpenMP is not active.");
4413 assert(Init &&
"Expected loop in canonical form.");
4414 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
4415 if (AssociatedLoops > 0 &&
4417 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
4418 if (!ISC.checkAndSetInit(Init,
false)) {
4420 auto *VD = dyn_cast<
VarDecl>(D);
4422 if (
VarDecl *Private = isOpenMPCapturedDecl(D)) {
4427 VD = cast<VarDecl>(Ref->
getDecl());
4430 DSAStack->addLoopControlVariable(D, VD);
4433 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4441 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
4442 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
4443 Expr *OrderedLoopCountExpr,
4445 LoopIterationSpace &ResultIterSpace,
4446 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4449 auto *For = dyn_cast_or_null<ForStmt>(S);
4452 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
4454 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4455 if (TotalNestedLoopCount > 1) {
4456 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4457 SemaRef.
Diag(DSA.getConstructLoc(),
4458 diag::note_omp_collapse_ordered_expr)
4461 else if (CollapseLoopCountExpr)
4463 diag::note_omp_collapse_ordered_expr)
4467 diag::note_omp_collapse_ordered_expr)
4472 assert(For->getBody());
4474 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4477 Stmt *Init = For->getInit();
4478 if (ISC.checkAndSetInit(Init))
4481 bool HasErrors =
false;
4484 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
4485 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4492 QualType VarType = LCDecl->getType().getNonReferenceType();
4496 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4510 VarsWithImplicitDSA.erase(LCDecl);
4520 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl,
false);
4525 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4528 DVar.CKind != PredeterminedCKind) ||
4532 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4533 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
4534 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4537 if (DVar.RefExpr ==
nullptr)
4538 DVar.CKind = PredeterminedCKind;
4541 }
else if (LoopDeclRefExpr !=
nullptr) {
4550 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4556 HasErrors |= ISC.checkAndSetCond(For->getCond());
4559 HasErrors |= ISC.checkAndSetInc(For->getInc());
4566 ResultIterSpace.PreCond =
4567 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4568 ResultIterSpace.NumIterations = ISC.buildNumIterations(
4573 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4574 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4575 ResultIterSpace.CounterInit = ISC.buildCounterInit();
4576 ResultIterSpace.CounterStep = ISC.buildCounterStep();
4577 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4578 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4579 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4580 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4582 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
4583 ResultIterSpace.NumIterations ==
nullptr ||
4584 ResultIterSpace.CounterVar ==
nullptr ||
4585 ResultIterSpace.PrivateCounterVar ==
nullptr ||
4586 ResultIterSpace.CounterInit ==
nullptr ||
4587 ResultIterSpace.CounterStep ==
nullptr);
4588 if (!HasErrors && DSA.isOrderedRegion()) {
4589 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4590 if (CurrentNestedLoopCount <
4591 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4592 DSA.getOrderedRegionParam().second->setLoopNumIterations(
4593 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4594 DSA.getOrderedRegionParam().second->setLoopCounter(
4595 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4598 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
4599 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4603 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4604 Pair.second.size() <= CurrentNestedLoopCount) {
4606 Pair.first->setLoopData(CurrentNestedLoopCount,
nullptr);
4610 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4611 CntValue = ISC.buildOrderedLoopData(
4612 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4613 Pair.first->getDependencyLoc());
4615 CntValue = ISC.buildOrderedLoopData(
4616 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4617 Pair.first->getDependencyLoc(),
4618 Pair.second[CurrentNestedLoopCount].first,
4619 Pair.second[CurrentNestedLoopCount].second);
4620 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4631 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4633 ExprResult NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
4637 VarRef.
get()->getType())) {
4654 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
4663 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
4675 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
4682 if (VarRef.
get()->getType()->isOverloadableType() ||
4683 NewStart.
get()->getType()->isOverloadableType() ||
4684 Update.
get()->getType()->isOverloadableType()) {
4691 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4692 VarRef.
get(), SavedUpdate.
get());
4703 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4704 NewStart.
get(), SavedUpdate.
get());
4709 VarRef.
get()->getType())) {
4716 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
4729 if (HasBits >= Bits)
4744 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4751 if (!PreInits.empty()) {
4762 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4763 if (!Captures.empty()) {
4765 for (
const auto &Pair : Captures)
4766 PreInits.push_back(Pair.second->getDecl());
4774 Expr *PostUpdate =
nullptr;
4775 if (!PostUpdates.empty()) {
4776 for (
Expr *E : PostUpdates) {
4782 PostUpdate = PostUpdate
4797 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
4801 unsigned NestedLoopCount = 1;
4802 if (CollapseLoopCountExpr) {
4806 NestedLoopCount = Result.getLimitedValue();
4808 unsigned OrderedLoopCount = 1;
4809 if (OrderedLoopCountExpr) {
4813 if (Result.getLimitedValue() < NestedLoopCount) {
4815 diag::err_omp_wrong_ordered_loop_count)
4818 diag::note_collapse_loop_count)
4821 OrderedLoopCount = Result.getLimitedValue();
4826 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
4828 IterSpaces.resize(
std::max(OrderedLoopCount, NestedLoopCount));
4830 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4832 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4833 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4834 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4844 for (
unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
4846 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4847 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4848 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4851 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
4853 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
4854 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
4855 Captures[DRE] = DRE;
4866 Built.
clear( NestedLoopCount);
4869 return NestedLoopCount;
4902 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
4903 Expr *N0 = IterSpaces[0].NumIterations;
4907 .PerformImplicitConversion(
4921 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
4922 return NestedLoopCount;
4927 Scope *CurScope = DSA.getCurScope();
4928 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4929 if (PreCond.isUsable()) {
4931 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4932 PreCond.get(), IterSpaces[Cnt].PreCond);
4934 Expr *N = IterSpaces[Cnt].NumIterations;
4939 CurScope, Loc, BO_Mul, LastIteration32.
get(),
4945 if (LastIteration64.isUsable())
4947 CurScope, Loc, BO_Mul, LastIteration64.get(),
4959 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4962 LastIteration32.
get()->getType()->hasSignedIntegerRepresentation(),
4963 LastIteration64.get(), SemaRef)))
4964 LastIteration = LastIteration32;
4982 CurScope, LastIteration.
get()->getExprLoc(), BO_Sub,
4983 LastIteration.
get(),
4993 LastIteration.
get()->isIntegerConstantExpr(Result, SemaRef.
Context);
4997 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
4998 LastIteration = SaveRef;
5002 CurScope, SaveRef.
get()->getExprLoc(), BO_Add, SaveRef.
get(),
5011 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5038 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
5047 UB.
get(), LastIteration.
get());
5049 LastIteration.
get()->getExprLoc(), InitLoc, IsUBGreater.
get(),
5050 LastIteration.
get(), UB.
get());
5051 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
5076 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
5079 LastIteration.
get(), CombUB.
get());
5080 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
5084 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5088 "Unexpected number of parameters in loop combined directive");
5115 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5126 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5136 ? SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get())
5137 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5138 NumIterations.
get());
5142 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.
get());
5147 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5151 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
5160 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5189 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
5200 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
5215 DistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get());
5216 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
5219 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
5220 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5221 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5224 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5232 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
5233 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
5239 bool HasErrors =
false;
5240 Built.
Counters.resize(NestedLoopCount);
5241 Built.
Inits.resize(NestedLoopCount);
5242 Built.
Updates.resize(NestedLoopCount);
5243 Built.
Finals.resize(NestedLoopCount);
5247 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5248 LoopIterationSpace &IS = IterSpaces[Cnt];
5255 SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.
get());
5258 assert((Cnt == (
int)NestedLoopCount - 1) &&
5259 "unusable div expected on first iteration only");
5263 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.
get(),
5271 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5273 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5276 IS.CounterInit, Captures);
5277 if (!Init.isUsable()) {
5282 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5283 IS.CounterStep, IS.Subtract, &Captures);
5291 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5292 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5301 Div = IS.NumIterations;
5303 Div = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.
get(),
5308 Div = tryBuildCapture(SemaRef, Div.
get(), Captures);
5319 Built.
Counters[Cnt] = IS.CounterVar;
5321 Built.
Inits[Cnt] = Init.get();
5336 Built.
PreCond = PreCond.get();
5341 Built.
LB = LB.
get();
5342 Built.
UB = UB.
get();
5343 Built.
IL = IL.
get();
5344 Built.
ST = ST.
get();
5346 Built.
NLB = NextLB.
get();
5347 Built.
NUB = NextUB.
get();
5360 return NestedLoopCount;
5364 auto CollapseClauses =
5365 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5366 if (CollapseClauses.begin() != CollapseClauses.end())
5367 return (*CollapseClauses.begin())->getNumForLoops();
5372 auto OrderedClauses =
5373 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5374 if (OrderedClauses.begin() != OrderedClauses.end())
5375 return (*OrderedClauses.begin())->getNumForLoops();
5384 for (
const OMPClause *Clause : Clauses) {
5386 Safelen = cast<OMPSafelenClause>(Clause);
5388 Simdlen = cast<OMPSimdlenClause>(Clause);
5389 if (Safelen && Simdlen)
5393 if (Simdlen && Safelen) {
5394 llvm::APSInt SimdlenRes, SafelenRes;
5411 if (SimdlenRes > SafelenRes) {
5413 diag::err_omp_wrong_simdlen_safelen_values)
5428 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5434 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5435 if (NestedLoopCount == 0)
5438 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5439 "omp simd loop exprs were not built");
5441 if (!CurContext->isDependentContext()) {
5444 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5455 setFunctionHasBranchProtectedScope();
5467 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5473 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5474 if (NestedLoopCount == 0)
5477 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5478 "omp for loop exprs were not built");
5480 if (!CurContext->isDependentContext()) {
5483 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5491 setFunctionHasBranchProtectedScope();
5493 Clauses, AStmt, B,
DSAStack->isCancelRegion());
5502 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5506 unsigned NestedLoopCount =
5509 VarsWithImplicitDSA, B);
5510 if (NestedLoopCount == 0)
5513 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5514 "omp for simd loop exprs were not built");
5516 if (!CurContext->isDependentContext()) {
5519 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5530 setFunctionHasBranchProtectedScope();
5542 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5543 auto BaseStmt = AStmt;
5544 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5546 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5547 auto S =
C->children();
5548 if (S.begin() == S.end())
5552 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5553 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5555 Diag(SectionStmt->getLocStart(),
5556 diag::err_omp_sections_substmt_not_section);
5559 cast<OMPSectionDirective>(SectionStmt)
5560 ->setHasCancel(
DSAStack->isCancelRegion());
5567 setFunctionHasBranchProtectedScope();
5579 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5581 setFunctionHasBranchProtectedScope();
5595 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5597 setFunctionHasBranchProtectedScope();
5603 for (
const OMPClause *Clause : Clauses) {
5607 Copyprivate = Clause;
5608 if (Copyprivate && Nowait) {
5610 diag::err_omp_single_copyprivate_with_nowait);
5625 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5627 setFunctionHasBranchProtectedScope();
5638 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5640 bool ErrorFound =
false;
5643 bool DependentHint =
false;
5645 if (
C->getClauseKind() == OMPC_hint) {
5647 Diag(
C->getLocStart(), diag::err_omp_hint_clause_no_name);
5650 Expr *E = cast<OMPHintClause>(
C)->getHint();
5653 DependentHint =
true;
5656 HintLoc =
C->getLocStart();
5662 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
5663 if (Pair.first && DirName.
getName() && !DependentHint) {
5664 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5665 Diag(StartLoc, diag::err_omp_critical_with_hint);
5667 Diag(HintLoc, diag::note_omp_critical_hint_here)
5668 << 0 << Hint.toString(10,
false);
5670 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5671 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
5672 Diag(
C->getLocStart(), diag::note_omp_critical_hint_here)
5674 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
5677 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5682 setFunctionHasBranchProtectedScope();
5686 if (!Pair.first && DirName.
getName() && !DependentHint)
5687 DSAStack->addCriticalWithHint(Dir, Hint);
5697 auto *CS = cast<CapturedStmt>(AStmt);
5708 unsigned NestedLoopCount =
5711 VarsWithImplicitDSA, B);
5712 if (NestedLoopCount == 0)
5715 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5716 "omp parallel for loop exprs were not built");
5718 if (!CurContext->isDependentContext()) {
5721 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5729 setFunctionHasBranchProtectedScope();
5731 NestedLoopCount, Clauses, AStmt, B,
5741 auto *CS = cast<CapturedStmt>(AStmt);
5752 unsigned NestedLoopCount =
5755 VarsWithImplicitDSA, B);
5756 if (NestedLoopCount == 0)
5759 if (!CurContext->isDependentContext()) {
5762 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5773 setFunctionHasBranchProtectedScope();
5775 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5785 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5786 auto BaseStmt = AStmt;
5787 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5789 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5790 auto S =
C->children();
5791 if (S.begin() == S.end())
5795 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5796 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5798 Diag(SectionStmt->getLocStart(),
5799 diag::err_omp_parallel_sections_substmt_not_section);
5802 cast<OMPSectionDirective>(SectionStmt)
5803 ->setHasCancel(
DSAStack->isCancelRegion());
5807 diag::err_omp_parallel_sections_not_compound_stmt);
5811 setFunctionHasBranchProtectedScope();
5814 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
5823 auto *CS = cast<CapturedStmt>(AStmt);
5831 setFunctionHasBranchProtectedScope();
5859 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5861 setFunctionHasBranchProtectedScope();
5865 DSAStack->getTaskgroupReductionRef());
5871 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
5880 const OMPClause *DependSourceClause =
nullptr;
5881 const OMPClause *DependSinkClause =
nullptr;
5882 bool ErrorFound =
false;
5886 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
5888 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5889 if (DependSourceClause) {
5890 Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
5895 DependSourceClause =
C;
5897 if (DependSinkClause) {
5898 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5902 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5903 if (DependSourceClause) {
5904 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5908 DependSinkClause =
C;
5910 }
else if (
C->getClauseKind() == OMPC_threads) {
5911 TC = cast<OMPThreadsClause>(
C);
5912 }
else if (
C->getClauseKind() == OMPC_simd) {
5913 SC = cast<OMPSIMDClause>(
C);
5916 if (!ErrorFound && !SC &&
5921 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5923 }
else if (DependFound && (TC || SC)) {
5924 Diag(DependFound->
getLocStart(), diag::err_omp_depend_clause_thread_simd)
5927 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
5929 diag::err_omp_ordered_directive_without_param);
5931 }
else if (TC || Clauses.empty()) {
5932 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
5934 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5936 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5940 if ((!AStmt && !DependFound) || ErrorFound)
5944 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5946 setFunctionHasBranchProtectedScope();
5955 class OpenMPAtomicUpdateChecker {
5957 enum ExprAnalysisErrorCode {
5961 NotABinaryOrUnaryExpression,
5963 NotAnUnaryIncDecExpression,
5969 NotABinaryExpression,
5975 NotAnUpdateExpression,
5993 bool IsXLHSInRHSPart;
5998 bool IsPostfixUpdate;
6001 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
6002 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
6003 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
6011 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
6013 Expr *getX()
const {
return X; }
6015 Expr *getExpr()
const {
return E; }
6019 Expr *getUpdateExpr()
const {
return UpdateExpr; }
6022 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
6026 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
6029 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
6030 unsigned NoteId = 0);
6034 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6036 ExprAnalysisErrorCode ErrorFound = NoError;
6042 if (AtomicBinOp->
getOpcode() == BO_Assign) {
6044 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6046 if (AtomicInnerBinOp->isMultiplicativeOp() ||
6047 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6048 AtomicInnerBinOp->isBitwiseOp()) {
6049 Op = AtomicInnerBinOp->getOpcode();
6050 OpLoc = AtomicInnerBinOp->getOperatorLoc();
6051 Expr *LHS = AtomicInnerBinOp->getLHS();
6052 Expr *RHS = AtomicInnerBinOp->getRHS();
6053 llvm::FoldingSetNodeID XId, LHSId, RHSId;
6062 IsXLHSInRHSPart =
true;
6063 }
else if (XId == RHSId) {
6065 IsXLHSInRHSPart =
false;
6067 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6068 ErrorRange = AtomicInnerBinOp->getSourceRange();
6069 NoteLoc =
X->getExprLoc();
6070 NoteRange =
X->getSourceRange();
6071 ErrorFound = NotAnUpdateExpression;
6074 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6075 ErrorRange = AtomicInnerBinOp->getSourceRange();
6076 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6078 ErrorFound = NotABinaryOperator;
6083 ErrorFound = NotABinaryExpression;
6090 ErrorFound = NotAnAssignmentOp;
6092 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6093 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6094 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6098 E =
X = UpdateExpr =
nullptr;
6099 return ErrorFound != NoError;
6102 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
6104 ExprAnalysisErrorCode ErrorFound = NoError;
6115 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
6116 AtomicBody = AtomicBody->IgnoreParenImpCasts();
6117 if (AtomicBody->getType()->isScalarType() ||
6118 AtomicBody->isInstantiationDependent()) {
6119 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6120 AtomicBody->IgnoreParenImpCasts())) {
6123 AtomicCompAssignOp->getOpcode());
6124 OpLoc = AtomicCompAssignOp->getOperatorLoc();
6125 E = AtomicCompAssignOp->getRHS();
6126 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6127 IsXLHSInRHSPart =
true;
6128 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6129 AtomicBody->IgnoreParenImpCasts())) {
6131 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6133 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6134 AtomicBody->IgnoreParenImpCasts())) {
6136 if (AtomicUnaryOp->isIncrementDecrementOp()) {
6137 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6138 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6139 OpLoc = AtomicUnaryOp->getOperatorLoc();
6140 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6142 IsXLHSInRHSPart =
true;
6144 ErrorFound = NotAnUnaryIncDecExpression;
6145 ErrorLoc = AtomicUnaryOp->getExprLoc();
6146 ErrorRange = AtomicUnaryOp->getSourceRange();
6147 NoteLoc = AtomicUnaryOp->getOperatorLoc();
6150 }
else if (!AtomicBody->isInstantiationDependent()) {
6151 ErrorFound = NotABinaryOrUnaryExpression;
6152 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6153 NoteRange = ErrorRange = AtomicBody->getSourceRange();
6156 ErrorFound = NotAScalarType;
6157 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
6158 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6161 ErrorFound = NotAnExpression;
6163 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6165 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6166 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6167 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6171 E =
X = UpdateExpr =
nullptr;
6172 if (ErrorFound == NoError && E &&
X) {
6182 IsXLHSInRHSPart ? OVEExpr : OVEX);
6189 UpdateExpr = Update.
get();
6191 return ErrorFound != NoError;
6201 auto *CS = cast<CapturedStmt>(AStmt);
6210 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
6211 C->getClauseKind() == OMPC_update ||
6212 C->getClauseKind() == OMPC_capture) {
6214 Diag(
C->getLocStart(), diag::err_omp_atomic_several_clauses)
6216 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6219 AtomicKind =
C->getClauseKind();
6220 AtomicKindLoc =
C->getLocStart();
6226 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6227 Body = EWC->getSubExpr();
6233 bool IsXLHSInRHSPart =
false;
6234 bool IsPostfixUpdate =
false;
6257 if (AtomicKind == OMPC_read) {
6264 } ErrorFound = NoError;
6269 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6270 const auto *AtomicBinOp =
6272 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6279 ErrorFound = NotAnLValue;
6287 const Expr *NotScalarExpr =
6291 ErrorFound = NotAScalarType;
6297 }
else if (!AtomicBody->isInstantiationDependent()) {
6298 ErrorFound = NotAnAssignmentOp;
6299 ErrorLoc = AtomicBody->getExprLoc();
6300 ErrorRange = AtomicBody->getSourceRange();
6302 : AtomicBody->getExprLoc();
6304 : AtomicBody->getSourceRange();
6307 ErrorFound = NotAnExpression;
6309 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6311 if (ErrorFound != NoError) {
6312 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6314 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6318 if (CurContext->isDependentContext())
6320 }
else if (AtomicKind == OMPC_write) {
6327 } ErrorFound = NoError;
6332 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6333 const auto *AtomicBinOp =
6335 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6336 X = AtomicBinOp->
getLHS();
6337 E = AtomicBinOp->
getRHS();
6341 ErrorFound = NotAnLValue;
6349 const Expr *NotScalarExpr =
6353 ErrorFound = NotAScalarType;
6359 }
else if (!AtomicBody->isInstantiationDependent()) {
6360 ErrorFound = NotAnAssignmentOp;
6361 ErrorLoc = AtomicBody->getExprLoc();
6362 ErrorRange = AtomicBody->getSourceRange();
6364 : AtomicBody->getExprLoc();
6366 : AtomicBody->getSourceRange();
6369 ErrorFound = NotAnExpression;
6371 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6373 if (ErrorFound != NoError) {
6374 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6376 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6380 if (CurContext->isDependentContext())
6382 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
6391 OpenMPAtomicUpdateChecker Checker(*
this);
6392 if (Checker.checkStatement(
6393 Body, (AtomicKind == OMPC_update)
6394 ? diag::err_omp_atomic_update_not_expression_statement
6395 : diag::err_omp_atomic_not_expression_statement,
6396 diag::note_omp_atomic_update))
6398 if (!CurContext->isDependentContext()) {
6399 E = Checker.getExpr();
6401 UE = Checker.getUpdateExpr();
6402 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6404 }
else if (AtomicKind == OMPC_capture) {
6407 NotACompoundStatement,
6408 NotTwoSubstatements,
6409 NotASpecificExpression,
6411 } ErrorFound = NoError;
6414 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6423 const auto *AtomicBinOp =
6425 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6426 V = AtomicBinOp->
getLHS();
6428 OpenMPAtomicUpdateChecker Checker(*
this);
6429 if (Checker.checkStatement(
6430 Body, diag::err_omp_atomic_capture_not_expression_statement,
6431 diag::note_omp_atomic_update))
6433 E = Checker.getExpr();
6435 UE = Checker.getUpdateExpr();
6436 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6437 IsPostfixUpdate = Checker.isPostfixUpdate();
6438 }
else if (!AtomicBody->isInstantiationDependent()) {
6439 ErrorLoc = AtomicBody->getExprLoc();
6440 ErrorRange = AtomicBody->getSourceRange();
6442 : AtomicBody->getExprLoc();
6444 : AtomicBody->getSourceRange();
6445 ErrorFound = NotAnAssignmentOp;
6447 if (ErrorFound != NoError) {
6448 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6450 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6453 if (CurContext->isDependentContext())
6454 UE = V = E = X =
nullptr;
6472 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
6474 if (CS->size() == 2) {
6476 Stmt *Second = CS->body_back();
6477 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
6478 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6479 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6480 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6482 OpenMPAtomicUpdateChecker Checker(*
this);
6483 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6485 if (IsUpdateExprFound) {
6487 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6489 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6499 llvm::FoldingSetNodeID XId, PossibleXId;
6500 Checker.getX()->Profile(XId, Context,
true);
6501 PossibleX->
Profile(PossibleXId, Context,
true);
6502 IsUpdateExprFound = XId == PossibleXId;
6503 if (IsUpdateExprFound) {
6506 E = Checker.getExpr();
6507 UE = Checker.getUpdateExpr();
6508 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6509 IsPostfixUpdate =
true;
6512 if (!IsUpdateExprFound) {
6513 IsUpdateExprFound = !Checker.checkStatement(First);
6515 if (IsUpdateExprFound) {
6517 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6519 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6529 llvm::FoldingSetNodeID XId, PossibleXId;
6530 Checker.getX()->Profile(XId, Context,
true);
6531 PossibleX->
Profile(PossibleXId, Context,
true);
6532 IsUpdateExprFound = XId == PossibleXId;
6533 if (IsUpdateExprFound) {
6536 E = Checker.getExpr();
6537 UE = Checker.getUpdateExpr();
6538 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6539 IsPostfixUpdate =
false;
6543 if (!IsUpdateExprFound) {
6545 auto *FirstExpr = dyn_cast<
Expr>(
First);
6546 auto *SecondExpr = dyn_cast<
Expr>(Second);
6547 if (!FirstExpr || !SecondExpr ||
6548 !(FirstExpr->isInstantiationDependent() ||
6549 SecondExpr->isInstantiationDependent())) {
6551 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6552 ErrorFound = NotAnAssignmentOp;
6553 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6555 NoteRange = ErrorRange = FirstBinOp
6556 ? FirstBinOp->getSourceRange()
6560 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6561 ErrorFound = NotAnAssignmentOp;
6562 NoteLoc = ErrorLoc = SecondBinOp
6563 ? SecondBinOp->getOperatorLoc()
6565 NoteRange = ErrorRange =
6566 SecondBinOp ? SecondBinOp->getSourceRange()
6569 Expr *PossibleXRHSInFirst =
6571 Expr *PossibleXLHSInSecond =
6573 llvm::FoldingSetNodeID X1Id, X2Id;
6574 PossibleXRHSInFirst->
Profile(X1Id, Context,
6576 PossibleXLHSInSecond->
Profile(X2Id, Context,
6578 IsUpdateExprFound = X1Id == X2Id;
6579 if (IsUpdateExprFound) {
6580 V = FirstBinOp->getLHS();
6581 X = SecondBinOp->getLHS();
6582 E = SecondBinOp->getRHS();
6584 IsXLHSInRHSPart =
false;
6585 IsPostfixUpdate =
true;
6587 ErrorFound = NotASpecificExpression;
6588 ErrorLoc = FirstBinOp->getExprLoc();
6589 ErrorRange = FirstBinOp->getSourceRange();
6590 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6591 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6599 NoteRange = ErrorRange =
6601 ErrorFound = NotTwoSubstatements;
6605 NoteRange = ErrorRange =
6607 ErrorFound = NotACompoundStatement;
6609 if (ErrorFound != NoError) {
6610 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6612 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6615 if (CurContext->isDependentContext())
6616 UE = V = E = X =
nullptr;
6620 setFunctionHasBranchProtectedScope();
6623 X, V, E, UE, IsXLHSInRHSPart,
6634 auto *CS = cast<CapturedStmt>(AStmt);
6641 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6642 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6656 if (
DSAStack->hasInnerTeamsRegion()) {
6658 bool OMPTeamsFound =
true;
6659 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
6660 auto I = CS->body_begin();
6661 while (I != CS->body_end()) {
6664 OMPTeamsFound =
false;
6669 assert(I != CS->body_end() &&
"Not found statement");
6675 if (!OMPTeamsFound) {
6676 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6678 diag::note_omp_nested_teams_construct_here);
6680 << isa<OMPExecutableDirective>(S);
6685 setFunctionHasBranchProtectedScope();
6697 auto *CS = cast<CapturedStmt>(AStmt);
6704 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
6705 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6715 setFunctionHasBranchProtectedScope();
6727 auto *CS = cast<CapturedStmt>(AStmt);
6734 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6735 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6748 unsigned NestedLoopCount =
6751 VarsWithImplicitDSA, B);
6752 if (NestedLoopCount == 0)
6755 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6756 "omp target parallel for loop exprs were not built");
6758 if (!CurContext->isDependentContext()) {
6761 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6769 setFunctionHasBranchProtectedScope();
6771 NestedLoopCount, Clauses, AStmt,
6778 return llvm::any_of(
6782 template <
typename... Params>
6784 const Params... ClauseTypes) {
6795 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6799 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6800 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6801 <<
"'map' or 'use_device_ptr'" 6806 setFunctionHasBranchProtectedScope();
6819 auto *CS = cast<CapturedStmt>(AStmt);
6826 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6827 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6840 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6856 auto *CS = cast<CapturedStmt>(AStmt);
6863 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6864 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6877 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6893 auto *CS = cast<CapturedStmt>(AStmt);
6900 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6901 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6911 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
6912 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6925 auto *CS = cast<CapturedStmt>(AStmt);
6933 setFunctionHasBranchProtectedScope();
6935 DSAStack->setParentTeamsRegionLoc(StartLoc);
6944 if (
DSAStack->isParentNowaitRegion()) {
6945 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6948 if (
DSAStack->isParentOrderedRegion()) {
6949 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6960 if (
DSAStack->isParentNowaitRegion()) {
6961 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6964 if (
DSAStack->isParentOrderedRegion()) {
6965 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6968 DSAStack->setParentCancelRegion(
true);
6976 bool ErrorFound =
false;
6978 if (
C->getClauseKind() == OMPC_grainsize ||
6979 C->getClauseKind() == OMPC_num_tasks) {
6983 S.
Diag(
C->getLocStart(),
6984 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6988 diag::note_omp_previous_grainsize_num_tasks)
6999 const OMPClause *ReductionClause =
nullptr;
7000 const OMPClause *NogroupClause =
nullptr;
7002 if (
C->getClauseKind() == OMPC_reduction) {
7003 ReductionClause =
C;
7008 if (
C->getClauseKind() == OMPC_nogroup) {
7010 if (ReductionClause)
7015 if (ReductionClause && NogroupClause) {
7016 S.
Diag(ReductionClause->
getLocStart(), diag::err_omp_reduction_with_nogroup)
7030 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7034 unsigned NestedLoopCount =
7037 VarsWithImplicitDSA, B);
7038 if (NestedLoopCount == 0)
7041 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7042 "omp for loop exprs were not built");
7055 setFunctionHasBranchProtectedScope();
7057 NestedLoopCount, Clauses, AStmt, B);
7066 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7070 unsigned NestedLoopCount =
7073 VarsWithImplicitDSA, B);
7074 if (NestedLoopCount == 0)
7077 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7078 "omp for loop exprs were not built");
7080 if (!CurContext->isDependentContext()) {
7083 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7104 setFunctionHasBranchProtectedScope();
7106 NestedLoopCount, Clauses, AStmt, B);
7115 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7119 unsigned NestedLoopCount =
7122 *
this, *
DSAStack, VarsWithImplicitDSA, B);
7123 if (NestedLoopCount == 0)
7126 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7127 "omp for loop exprs were not built");
7129 setFunctionHasBranchProtectedScope();
7131 NestedLoopCount, Clauses, AStmt, B);
7140 auto *CS = cast<CapturedStmt>(AStmt);
7147 for (
int ThisCaptureLevel =
7148 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7149 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7165 VarsWithImplicitDSA, B);
7166 if (NestedLoopCount == 0)
7169 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7170 "omp for loop exprs were not built");
7172 setFunctionHasBranchProtectedScope();
7174 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7184 auto *CS = cast<CapturedStmt>(AStmt);
7191 for (
int ThisCaptureLevel =
7192 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7193 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7209 VarsWithImplicitDSA, B);
7210 if (NestedLoopCount == 0)
7213 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7214 "omp for loop exprs were not built");
7216 if (!CurContext->isDependentContext()) {
7219 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7230 setFunctionHasBranchProtectedScope();
7232 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7241 auto *CS = cast<CapturedStmt>(AStmt);
7248 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7249 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7262 unsigned NestedLoopCount =
7264 nullptr , CS, *
this,
7265 *
DSAStack, VarsWithImplicitDSA, B);
7266 if (NestedLoopCount == 0)
7269 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7270 "omp for loop exprs were not built");
7272 if (!CurContext->isDependentContext()) {
7275 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7286 setFunctionHasBranchProtectedScope();
7288 NestedLoopCount, Clauses, AStmt, B);
7297 auto *CS = cast<CapturedStmt>(AStmt);
7304 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7305 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7321 VarsWithImplicitDSA, B);
7322 if (NestedLoopCount == 0)
7325 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7326 "omp target parallel for simd loop exprs were not built");
7328 if (!CurContext->isDependentContext()) {
7331 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7341 setFunctionHasBranchProtectedScope();
7343 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7352 auto *CS = cast<CapturedStmt>(AStmt);
7359 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7360 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7373 unsigned NestedLoopCount =
7376 VarsWithImplicitDSA, B);
7377 if (NestedLoopCount == 0)
7380 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7381 "omp target simd loop exprs were not built");
7383 if (!CurContext->isDependentContext()) {
7386 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7397 setFunctionHasBranchProtectedScope();
7399 NestedLoopCount, Clauses, AStmt, B);
7408 auto *CS = cast<CapturedStmt>(AStmt);
7415 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7416 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7429 unsigned NestedLoopCount =
7431 nullptr , CS, *
this,
7432 *
DSAStack, VarsWithImplicitDSA, B);
7433 if (NestedLoopCount == 0)
7436 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7437 "omp teams distribute loop exprs were not built");
7439 setFunctionHasBranchProtectedScope();
7441 DSAStack->setParentTeamsRegionLoc(StartLoc);
7444 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7453 auto *CS = cast<CapturedStmt>(AStmt);
7460 for (
int ThisCaptureLevel =
7461 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7462 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7479 VarsWithImplicitDSA, B);
7481 if (NestedLoopCount == 0)
7484 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7485 "omp teams distribute simd loop exprs were not built");
7487 if (!CurContext->isDependentContext()) {
7490 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7501 setFunctionHasBranchProtectedScope();
7503 DSAStack->setParentTeamsRegionLoc(StartLoc);
7506 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7515 auto *CS = cast<CapturedStmt>(AStmt);
7523 for (
int ThisCaptureLevel =
7524 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7525 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7541 VarsWithImplicitDSA, B);
7543 if (NestedLoopCount == 0)
7546 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7547 "omp for loop exprs were not built");
7549 if (!CurContext->isDependentContext()) {
7552 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7563 setFunctionHasBranchProtectedScope();
7565 DSAStack->setParentTeamsRegionLoc(StartLoc);
7568 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7577 auto *CS = cast<CapturedStmt>(AStmt);
7585 for (
int ThisCaptureLevel =
7586 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7587 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7603 VarsWithImplicitDSA, B);
7605 if (NestedLoopCount == 0)
7608 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7609 "omp for loop exprs were not built");
7611 setFunctionHasBranchProtectedScope();
7613 DSAStack->setParentTeamsRegionLoc(StartLoc);
7616 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7627 auto *CS = cast<CapturedStmt>(AStmt);
7635 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7636 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7645 setFunctionHasBranchProtectedScope();
7657 auto *CS = cast<CapturedStmt>(AStmt);
7664 for (
int ThisCaptureLevel =
7665 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7666 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7682 VarsWithImplicitDSA, B);
7683 if (NestedLoopCount == 0)
7686 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7687 "omp target teams distribute loop exprs were not built");
7689 setFunctionHasBranchProtectedScope();
7691 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7700 auto *CS = cast<CapturedStmt>(AStmt);
7707 for (
int ThisCaptureLevel =
7708 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
7709 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7725 VarsWithImplicitDSA, B);
7726 if (NestedLoopCount == 0)
7729 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7730 "omp target teams distribute parallel for loop exprs were not built");
7732 if (!CurContext->isDependentContext()) {
7735 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7743 setFunctionHasBranchProtectedScope();
7745 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7755 auto *CS = cast<CapturedStmt>(AStmt);
7762 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(
7763 OMPD_target_teams_distribute_parallel_for_simd);
7764 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7777 unsigned NestedLoopCount =
7780 nullptr , CS, *
this,
7781 *
DSAStack, VarsWithImplicitDSA, B);
7782 if (NestedLoopCount == 0)
7785 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7786 "omp target teams distribute parallel for simd loop exprs were not " 7789 if (!CurContext->isDependentContext()) {
7792 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7803 setFunctionHasBranchProtectedScope();
7805 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7814 auto *CS = cast<CapturedStmt>(AStmt);
7821 for (
int ThisCaptureLevel =
7822 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7823 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7839 VarsWithImplicitDSA, B);
7840 if (NestedLoopCount == 0)
7843 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7844 "omp target teams distribute simd loop exprs were not built");
7846 if (!CurContext->isDependentContext()) {
7849 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7860 setFunctionHasBranchProtectedScope();
7862 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7872 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7874 case OMPC_num_threads:
7875 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7878 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7881 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7884 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7887 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7890 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7892 case OMPC_num_teams:
7893 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7895 case OMPC_thread_limit:
7896 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7899 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7901 case OMPC_grainsize:
7902 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7904 case OMPC_num_tasks:
7905 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7908 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7912 case OMPC_proc_bind:
7915 case OMPC_firstprivate:
7916 case OMPC_lastprivate:
7918 case OMPC_reduction:
7919 case OMPC_task_reduction:
7920 case OMPC_in_reduction:
7924 case OMPC_copyprivate:
7927 case OMPC_mergeable:
7940 case OMPC_dist_schedule:
7941 case OMPC_defaultmap:
7946 case OMPC_use_device_ptr:
7947 case OMPC_is_device_ptr:
7948 llvm_unreachable(
"Clause is not allowed.");
7965 case OMPD_target_parallel:
7966 case OMPD_target_parallel_for:
7967 case OMPD_target_parallel_for_simd:
7970 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
7971 CaptureRegion = OMPD_target;
7973 case OMPD_target_teams_distribute_parallel_for:
7974 case OMPD_target_teams_distribute_parallel_for_simd:
7977 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
7978 CaptureRegion = OMPD_teams;
7980 case OMPD_teams_distribute_parallel_for:
7981 case OMPD_teams_distribute_parallel_for_simd:
7982 CaptureRegion = OMPD_teams;
7984 case OMPD_target_update:
7985 case OMPD_target_enter_data:
7986 case OMPD_target_exit_data:
7987 CaptureRegion = OMPD_task;
7991 case OMPD_parallel_sections:
7992 case OMPD_parallel_for:
7993 case OMPD_parallel_for_simd:
7995 case OMPD_target_simd:
7996 case OMPD_target_teams:
7997 case OMPD_target_teams_distribute:
7998 case OMPD_target_teams_distribute_simd:
7999 case OMPD_distribute_parallel_for:
8000 case OMPD_distribute_parallel_for_simd:
8003 case OMPD_taskloop_simd:
8004 case OMPD_target_data:
8007 case OMPD_threadprivate:
8008 case OMPD_taskyield:
8011 case OMPD_cancellation_point:
8013 case OMPD_declare_reduction:
8014 case OMPD_declare_simd:
8015 case OMPD_declare_target:
8016 case OMPD_end_declare_target:
8026 case OMPD_taskgroup:
8027 case OMPD_distribute:
8030 case OMPD_distribute_simd:
8031 case OMPD_teams_distribute:
8032 case OMPD_teams_distribute_simd:
8033 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
8035 llvm_unreachable(
"Unknown OpenMP directive");
8038 case OMPC_num_threads:
8040 case OMPD_target_parallel:
8041 case OMPD_target_parallel_for:
8042 case OMPD_target_parallel_for_simd:
8043 CaptureRegion = OMPD_target;
8045 case OMPD_teams_distribute_parallel_for:
8046 case OMPD_teams_distribute_parallel_for_simd:
8047 case OMPD_target_teams_distribute_parallel_for:
8048 case OMPD_target_teams_distribute_parallel_for_simd:
8049 CaptureRegion = OMPD_teams;
8052 case OMPD_parallel_sections:
8053 case OMPD_parallel_for:
8054 case OMPD_parallel_for_simd:
8055 case OMPD_distribute_parallel_for:
8056 case OMPD_distribute_parallel_for_simd:
8059 case OMPD_target_data:
8060 case OMPD_target_enter_data:
8061 case OMPD_target_exit_data:
8062 case OMPD_target_update:
8064 case OMPD_target_simd:
8065 case OMPD_target_teams:
8066 case OMPD_target_teams_distribute:
8067 case OMPD_target_teams_distribute_simd:
8071 case OMPD_taskloop_simd:
8072 case OMPD_threadprivate:
8073 case OMPD_taskyield:
8076 case OMPD_cancellation_point:
8078 case OMPD_declare_reduction:
8079 case OMPD_declare_simd:
8080 case OMPD_declare_target:
8081 case OMPD_end_declare_target:
8091 case OMPD_taskgroup:
8092 case OMPD_distribute:
8095 case OMPD_distribute_simd:
8096 case OMPD_teams_distribute:
8097 case OMPD_teams_distribute_simd:
8098 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
8100 llvm_unreachable(
"Unknown OpenMP directive");
8103 case OMPC_num_teams:
8105 case OMPD_target_teams:
8106 case OMPD_target_teams_distribute:
8107 case OMPD_target_teams_distribute_simd:
8108 case OMPD_target_teams_distribute_parallel_for:
8109 case OMPD_target_teams_distribute_parallel_for_simd:
8110 CaptureRegion = OMPD_target;
8112 case OMPD_teams_distribute_parallel_for:
8113 case OMPD_teams_distribute_parallel_for_simd:
8115 case OMPD_teams_distribute:
8116 case OMPD_teams_distribute_simd:
8119 case OMPD_distribute_parallel_for:
8120 case OMPD_distribute_parallel_for_simd:
8123 case OMPD_taskloop_simd:
8124 case OMPD_target_data:
8125 case OMPD_target_enter_data:
8126 case OMPD_target_exit_data:
8127 case OMPD_target_update:
8130 case OMPD_parallel_sections:
8131 case OMPD_parallel_for:
8132 case OMPD_parallel_for_simd:
8134 case OMPD_target_simd:
8135 case OMPD_target_parallel:
8136 case OMPD_target_parallel_for:
8137 case OMPD_target_parallel_for_simd:
8138 case OMPD_threadprivate:
8139 case OMPD_taskyield:
8142 case OMPD_cancellation_point:
8144 case OMPD_declare_reduction:
8145 case OMPD_declare_simd:
8146 case OMPD_declare_target:
8147 case OMPD_end_declare_target:
8156 case OMPD_taskgroup:
8157 case OMPD_distribute:
8160 case OMPD_distribute_simd:
8161 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8163 llvm_unreachable(
"Unknown OpenMP directive");
8166 case OMPC_thread_limit:
8168 case OMPD_target_teams:
8169 case OMPD_target_teams_distribute:
8170 case OMPD_target_teams_distribute_simd:
8171 case OMPD_target_teams_distribute_parallel_for:
8172 case OMPD_target_teams_distribute_parallel_for_simd:
8173 CaptureRegion = OMPD_target;
8175 case OMPD_teams_distribute_parallel_for:
8176 case OMPD_teams_distribute_parallel_for_simd:
8178 case OMPD_teams_distribute:
8179 case OMPD_teams_distribute_simd:
8182 case OMPD_distribute_parallel_for:
8183 case OMPD_distribute_parallel_for_simd:
8186 case OMPD_taskloop_simd:
8187 case OMPD_target_data:
8188 case OMPD_target_enter_data:
8189 case OMPD_target_exit_data:
8190 case OMPD_target_update:
8193 case OMPD_parallel_sections:
8194 case OMPD_parallel_for:
8195 case OMPD_parallel_for_simd:
8197 case OMPD_target_simd:
8198 case OMPD_target_parallel:
8199 case OMPD_target_parallel_for:
8200 case OMPD_target_parallel_for_simd:
8201 case OMPD_threadprivate:
8202 case OMPD_taskyield:
8205 case OMPD_cancellation_point:
8207 case OMPD_declare_reduction:
8208 case OMPD_declare_simd:
8209 case OMPD_declare_target:
8210 case OMPD_end_declare_target:
8219 case OMPD_taskgroup:
8220 case OMPD_distribute:
8223 case OMPD_distribute_simd:
8224 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
8226 llvm_unreachable(
"Unknown OpenMP directive");
8231 case OMPD_parallel_for:
8232 case OMPD_parallel_for_simd:
8233 case OMPD_distribute_parallel_for:
8234 case OMPD_distribute_parallel_for_simd:
8235 case OMPD_teams_distribute_parallel_for:
8236 case OMPD_teams_distribute_parallel_for_simd:
8237 case OMPD_target_parallel_for:
8238 case OMPD_target_parallel_for_simd:
8239 case OMPD_target_teams_distribute_parallel_for:
8240 case OMPD_target_teams_distribute_parallel_for_simd:
8241 CaptureRegion = OMPD_parallel;
8249 case OMPD_taskloop_simd:
8250 case OMPD_target_data:
8251 case OMPD_target_enter_data:
8252 case OMPD_target_exit_data:
8253 case OMPD_target_update:
8255 case OMPD_teams_distribute:
8256 case OMPD_teams_distribute_simd:
8257 case OMPD_target_teams_distribute:
8258 case OMPD_target_teams_distribute_simd:
8260 case OMPD_target_simd:
8261 case OMPD_target_parallel:
8264 case OMPD_parallel_sections:
8265 case OMPD_threadprivate:
8266 case OMPD_taskyield:
8269 case OMPD_cancellation_point:
8271 case OMPD_declare_reduction:
8272 case OMPD_declare_simd:
8273 case OMPD_declare_target:
8274 case OMPD_end_declare_target:
8281 case OMPD_taskgroup:
8282 case OMPD_distribute:
8285 case OMPD_distribute_simd:
8286 case OMPD_target_teams:
8287 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8289 llvm_unreachable(
"Unknown OpenMP directive");
8292 case OMPC_dist_schedule:
8294 case OMPD_teams_distribute_parallel_for:
8295 case OMPD_teams_distribute_parallel_for_simd:
8296 case OMPD_teams_distribute:
8297 case OMPD_teams_distribute_simd:
8298 case OMPD_target_teams_distribute_parallel_for:
8299 case OMPD_target_teams_distribute_parallel_for_simd:
8300 case OMPD_target_teams_distribute:
8301 case OMPD_target_teams_distribute_simd:
8302 CaptureRegion = OMPD_teams;
8304 case OMPD_distribute_parallel_for:
8305 case OMPD_distribute_parallel_for_simd:
8306 case OMPD_distribute:
8307 case OMPD_distribute_simd:
8310 case OMPD_parallel_for:
8311 case OMPD_parallel_for_simd:
8312 case OMPD_target_parallel_for_simd:
8313 case OMPD_target_parallel_for:
8316 case OMPD_taskloop_simd:
8317 case OMPD_target_data:
8318 case OMPD_target_enter_data:
8319 case OMPD_target_exit_data:
8320 case OMPD_target_update:
8323 case OMPD_target_simd:
8324 case OMPD_target_parallel:
8327 case OMPD_parallel_sections:
8328 case OMPD_threadprivate:
8329 case OMPD_taskyield:
8332 case OMPD_cancellation_point:
8334 case OMPD_declare_reduction:
8335 case OMPD_declare_simd:
8336 case OMPD_declare_target:
8337 case OMPD_end_declare_target:
8346 case OMPD_taskgroup:
8349 case OMPD_target_teams:
8350 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8352 llvm_unreachable(
"Unknown OpenMP directive");
8357 case OMPD_target_update:
8358 case OMPD_target_enter_data:
8359 case OMPD_target_exit_data:
8361 case OMPD_target_simd:
8362 case OMPD_target_teams:
8363 case OMPD_target_parallel:
8364 case OMPD_target_teams_distribute:
8365 case OMPD_target_teams_distribute_simd:
8366 case OMPD_target_parallel_for:
8367 case OMPD_target_parallel_for_simd:
8368 case OMPD_target_teams_distribute_parallel_for:
8369 case OMPD_target_teams_distribute_parallel_for_simd:
8370 CaptureRegion = OMPD_task;
8372 case OMPD_target_data:
8375 case OMPD_teams_distribute_parallel_for:
8376 case OMPD_teams_distribute_parallel_for_simd:
8378 case OMPD_teams_distribute:
8379 case OMPD_teams_distribute_simd:
8380 case OMPD_distribute_parallel_for:
8381 case OMPD_distribute_parallel_for_simd:
8384 case OMPD_taskloop_simd:
8387 case OMPD_parallel_sections:
8388 case OMPD_parallel_for:
8389 case OMPD_parallel_for_simd:
8390 case OMPD_threadprivate:
8391 case OMPD_taskyield:
8394 case OMPD_cancellation_point:
8396 case OMPD_declare_reduction:
8397 case OMPD_declare_simd:
8398 case OMPD_declare_target:
8399 case OMPD_end_declare_target:
8408 case OMPD_taskgroup:
8409 case OMPD_distribute:
8412 case OMPD_distribute_simd:
8413 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8415 llvm_unreachable(
"Unknown OpenMP directive");
8418 case OMPC_firstprivate:
8419 case OMPC_lastprivate:
8420 case OMPC_reduction:
8421 case OMPC_task_reduction:
8422 case OMPC_in_reduction:
8425 case OMPC_proc_bind:
8434 case OMPC_copyprivate:
8438 case OMPC_mergeable:
8451 case OMPC_grainsize:
8453 case OMPC_num_tasks:
8455 case OMPC_defaultmap:
8460 case OMPC_use_device_ptr:
8461 case OMPC_is_device_ptr:
8462 llvm_unreachable(
"Unexpected OpenMP clause.");
8464 return CaptureRegion;
8473 Expr *ValExpr = Condition;
8474 Stmt *HelperValStmt =
nullptr;
8479 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8483 ValExpr = Val.
get();
8488 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8489 ValExpr = MakeFullExpr(ValExpr).get();
8490 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8491 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8496 return new (Context)
8497 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8498 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8505 Expr *ValExpr = Condition;
8509 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8513 ValExpr = MakeFullExpr(Val.
get()).
get();
8516 return new (Context)
OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8525 IntConvertDiagnoser()
8529 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
8533 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
8538 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8547 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8556 llvm_unreachable(
"conversion functions are permitted");
8559 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8564 bool StrictlyPositive) {
8573 ValExpr = Value.
get();
8577 Result.isSigned() &&
8578 !((!StrictlyPositive && Result.isNonNegative()) ||
8579 (StrictlyPositive && Result.isStrictlyPositive()))) {
8580 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
8593 Expr *ValExpr = NumThreads;
8594 Stmt *HelperValStmt =
nullptr;
8605 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8606 ValExpr = MakeFullExpr(ValExpr).get();
8607 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8608 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8613 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8618 bool StrictlyPositive) {
8625 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8628 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8629 (!StrictlyPositive && !Result.isNonNegative())) {
8630 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
8635 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8640 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
8641 DSAStack->setAssociatedLoops(Result.getExtValue());
8642 else if (CKind == OMPC_ordered)
8643 DSAStack->setAssociatedLoops(Result.getExtValue());
8653 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8656 return new (Context)
8666 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8669 return new (Context)
8683 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8686 return new (Context)
8693 Expr *NumForLoops) {
8699 if (NumForLoops && LParenLoc.
isValid()) {
8701 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8704 NumForLoops = NumForLoopsResult.
get();
8706 NumForLoops =
nullptr;
8709 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
8710 StartLoc, LParenLoc, EndLoc);
8711 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
8722 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8723 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8725 case OMPC_proc_bind:
8726 Res = ActOnOpenMPProcBindClause(
8727 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8732 case OMPC_num_threads:
8738 case OMPC_firstprivate:
8739 case OMPC_lastprivate:
8741 case OMPC_reduction:
8742 case OMPC_task_reduction:
8743 case OMPC_in_reduction:
8747 case OMPC_copyprivate:
8751 case OMPC_mergeable:
8764 case OMPC_num_teams:
8765 case OMPC_thread_limit:
8767 case OMPC_grainsize:
8769 case OMPC_num_tasks:
8771 case OMPC_dist_schedule:
8772 case OMPC_defaultmap:
8777 case OMPC_use_device_ptr:
8778 case OMPC_is_device_ptr:
8779 llvm_unreachable(
"Clause is not allowed.");
8788 llvm::raw_svector_ostream Out(Buffer);
8789 unsigned Bound = Last >= 2 ? Last - 2 : 0;
8790 unsigned Skipped = Exclude.size();
8791 auto S = Exclude.begin(), E = Exclude.end();
8792 for (
unsigned I = First; I <
Last; ++I) {
8793 if (std::find(S, E, I) != E) {
8798 if (I == Bound - Skipped)
8800 else if (I != Bound + 1 - Skipped)
8813 "OMPC_DEFAULT_unknown not greater than 0");
8814 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8821 case OMPC_DEFAULT_none:
8822 DSAStack->setDefaultDSANone(KindKwLoc);
8824 case OMPC_DEFAULT_shared:
8825 DSAStack->setDefaultDSAShared(KindKwLoc);
8828 llvm_unreachable(
"Clause kind is not allowed.");
8831 return new (Context)
8841 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8847 return new (Context)
8859 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8860 assert(Argument.size() == NumberOfElements &&
8861 ArgumentLoc.size() == NumberOfElements);
8862 Res = ActOnOpenMPScheduleClause(
8863 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8864 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8865 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8866 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8867 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8870 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8871 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8872 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8875 case OMPC_dist_schedule:
8876 Res = ActOnOpenMPDistScheduleClause(
8877 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8878 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8880 case OMPC_defaultmap:
8882 Res = ActOnOpenMPDefaultmapClause(
8883 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
8884 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8885 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8889 case OMPC_num_threads:
8894 case OMPC_proc_bind:
8896 case OMPC_firstprivate:
8897 case OMPC_lastprivate:
8899 case OMPC_reduction:
8900 case OMPC_task_reduction:
8901 case OMPC_in_reduction:
8905 case OMPC_copyprivate:
8909 case OMPC_mergeable:
8922 case OMPC_num_teams:
8923 case OMPC_thread_limit:
8925 case OMPC_grainsize:
8927 case OMPC_num_tasks:
8933 case OMPC_use_device_ptr:
8934 case OMPC_is_device_ptr:
8935 llvm_unreachable(
"Clause is not allowed.");
8946 Excluded.push_back(M2);
8947 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8948 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8949 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8950 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8951 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8974 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8975 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8976 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8977 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8978 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8994 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9001 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9002 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9003 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9004 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9005 diag::err_omp_schedule_nonmonotonic_static);
9008 Expr *ValExpr = ChunkSize;
9009 Stmt *HelperValStmt =
nullptr;
9016 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9020 ValExpr = Val.
get();
9027 if (Result.isSigned() && !Result.isStrictlyPositive()) {
9028 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9033 DSAStack->getCurrentDirective(), OMPC_schedule) !=
9035 !CurContext->isDependentContext()) {
9036 ValExpr = MakeFullExpr(ValExpr).get();
9037 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9038 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
9044 return new (Context)
9046 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9055 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9058 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9061 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9063 case OMPC_mergeable:
9064 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9067 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9070 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9073 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9076 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9079 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9082 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9085 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9088 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9092 case OMPC_num_threads:
9098 case OMPC_firstprivate:
9099 case OMPC_lastprivate:
9101 case OMPC_reduction:
9102 case OMPC_task_reduction:
9103 case OMPC_in_reduction:
9107 case OMPC_copyprivate:
9109 case OMPC_proc_bind:
9115 case OMPC_num_teams:
9116 case OMPC_thread_limit:
9118 case OMPC_grainsize:
9119 case OMPC_num_tasks:
9121 case OMPC_dist_schedule:
9122 case OMPC_defaultmap:
9127 case OMPC_use_device_ptr:
9128 case OMPC_is_device_ptr:
9129 llvm_unreachable(
"Clause is not allowed.");
9201 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9203 case OMPC_firstprivate:
9204 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9206 case OMPC_lastprivate:
9207 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9210 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9212 case OMPC_reduction:
9213 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9214 EndLoc, ReductionIdScopeSpec, ReductionId);
9216 case OMPC_task_reduction:
9217 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9218 EndLoc, ReductionIdScopeSpec,
9221 case OMPC_in_reduction:
9223 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9224 EndLoc, ReductionIdScopeSpec, ReductionId);
9227 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9228 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9231 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9235 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9237 case OMPC_copyprivate:
9238 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9241 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9244 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9245 StartLoc, LParenLoc, EndLoc);
9248 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
9249 DepLinMapLoc, ColonLoc, VarList, StartLoc,
9253 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9256 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9258 case OMPC_use_device_ptr:
9259 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9261 case OMPC_is_device_ptr:
9262 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9266 case OMPC_num_threads:
9271 case OMPC_proc_bind:
9276 case OMPC_mergeable:
9286 case OMPC_num_teams:
9287 case OMPC_thread_limit:
9289 case OMPC_grainsize:
9291 case OMPC_num_tasks:
9293 case OMPC_dist_schedule:
9294 case OMPC_defaultmap:
9297 llvm_unreachable(
"Clause is not allowed.");
9308 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
9309 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
9314 Res = DefaultLvalueConversion(Res.
get());
9321 static std::pair<ValueDecl *, bool>
9323 SourceRange &ERange,
bool AllowArraySection =
false) {
9326 return std::make_pair(
nullptr,
true);
9338 } IsArrayExpr = NoArrayExpr;
9339 if (AllowArraySection) {
9340 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9341 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
9342 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9345 IsArrayExpr = ArraySubscript;
9346 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9347 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
9348 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9350 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9353 IsArrayExpr = OMPArraySection;
9359 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9360 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9361 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9363 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9364 !isa<FieldDecl>(ME->getMemberDecl()))) {
9365 if (IsArrayExpr != NoArrayExpr) {
9366 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9371 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9372 : diag::err_omp_expected_var_name_member_expr)
9375 return std::make_pair(
nullptr,
false);
9377 return std::make_pair(
9387 for (
Expr *RefExpr : VarList) {
9388 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
9391 Expr *SimpleRefExpr = RefExpr;
9395 Vars.push_back(RefExpr);
9396 PrivateCopies.push_back(
nullptr);
9403 auto *VD = dyn_cast<
VarDecl>(D);
9408 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9419 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9420 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
9431 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9438 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9448 if (
DSAStack->checkMappableExprComponentListsForDecl(
9452 ConflictKind = WhereFoundClauseKind;
9455 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9477 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
9478 ActOnUninitializedDecl(VDPrivate);
9485 if (!VD && !CurContext->isDependentContext())
9487 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9488 Vars.push_back((VD || CurContext->isDependentContext())
9489 ? RefExpr->IgnoreParens()
9491 PrivateCopies.push_back(VDPrivateRefExpr);
9502 class DiagsUninitializedSeveretyRAII {
9506 bool IsIgnored =
false;
9511 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9513 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
9517 ~DiagsUninitializedSeveretyRAII() {
9532 bool IsImplicitClause =
9536 for (
Expr *RefExpr : VarList) {
9537 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
9540 Expr *SimpleRefExpr = RefExpr;
9544 Vars.push_back(RefExpr);
9545 PrivateCopies.push_back(
nullptr);
9546 Inits.push_back(
nullptr);
9552 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9554 auto *VD = dyn_cast<
VarDecl>(D);
9559 if (RequireCompleteType(ELoc, Type,
9560 diag::err_omp_firstprivate_incomplete_type))
9571 DSAStackTy::DSAVarData TopDVar;
9572 if (!IsImplicitClause) {
9573 DSAStackTy::DSAVarData DVar =
9577 bool IsConstant = ElemType.
isConstant(Context);
9585 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9587 DVar.CKind != OMPC_lastprivate) &&
9589 Diag(ELoc, diag::err_omp_wrong_dsa)
9607 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9608 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
9609 Diag(ELoc, diag::err_omp_wrong_dsa)
9635 DVar =
DSAStack->getImplicitDSA(D,
true);
9636 if (DVar.CKind != OMPC_shared &&
9640 Diag(ELoc, diag::err_omp_required_access)
9667 if (DVar.CKind == OMPC_reduction &&
9671 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9683 if (
DSAStack->checkMappableExprComponentListsForDecl(
9688 ConflictKind = WhereFoundClauseKind;
9691 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9704 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9711 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9720 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
9726 Expr *VDInitRefExpr =
nullptr;
9733 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
9736 ".firstprivate.temp");
9751 ".firstprivate.temp");
9753 RefExpr->getExprLoc());
9754 AddInitializerToDecl(VDPrivate,
9755 DefaultLvalueConversion(VDInitRefExpr).
get(),
9759 if (IsImplicitClause) {
9760 Diag(RefExpr->getExprLoc(),
9761 diag::note_omp_task_predetermined_firstprivate_here);
9765 CurContext->addDecl(VDPrivate);
9768 RefExpr->getExprLoc());
9770 if (!VD && !CurContext->isDependentContext()) {
9771 if (TopDVar.CKind == OMPC_lastprivate) {
9772 Ref = TopDVar.PrivateCopy;
9775 if (!isOpenMPCapturedDecl(D))
9776 ExprCaptures.push_back(Ref->getDecl());
9779 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9780 Vars.push_back((VD || CurContext->isDependentContext())
9781 ? RefExpr->IgnoreParens()
9783 PrivateCopies.push_back(VDPrivateRefExpr);
9784 Inits.push_back(VDInitRefExpr);
9791 Vars, PrivateCopies, Inits,
9805 for (
Expr *RefExpr : VarList) {
9806 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
9809 Expr *SimpleRefExpr = RefExpr;
9813 Vars.push_back(RefExpr);
9814 SrcExprs.push_back(
nullptr);
9815 DstExprs.push_back(
nullptr);
9816 AssignmentOps.push_back(
nullptr);
9823 auto *VD = dyn_cast<
VarDecl>(D);
9828 if (RequireCompleteType(ELoc, Type,
9829 diag::err_omp_lastprivate_incomplete_type))
9842 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9843 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9845 DVar.CKind != OMPC_firstprivate) &&
9846 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
9847 Diag(ELoc, diag::err_omp_wrong_dsa)
9860 DSAStackTy::DSAVarData TopDVar = DVar;
9864 DVar =
DSAStack->getImplicitDSA(D,
true);
9865 if (DVar.CKind != OMPC_shared) {
9866 Diag(ELoc, diag::err_omp_required_access)
9894 ExprResult AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
9895 PseudoDstExpr, PseudoSrcExpr);
9898 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
9904 if (!VD && !CurContext->isDependentContext()) {
9905 if (TopDVar.CKind == OMPC_firstprivate) {
9906 Ref = TopDVar.PrivateCopy;
9909 if (!isOpenMPCapturedDecl(D))
9910 ExprCaptures.push_back(Ref->
getDecl());
9912 if (TopDVar.CKind == OMPC_firstprivate ||
9913 (!isOpenMPCapturedDecl(D) &&
9915 ExprResult RefRes = DefaultLvalueConversion(Ref);
9919 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9923 ExprPostUpdates.push_back(
9924 IgnoredValueConversions(PostUpdateRes.
get()).
get());
9927 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9928 Vars.push_back((VD || CurContext->isDependentContext())
9929 ? RefExpr->IgnoreParens()
9931 SrcExprs.push_back(PseudoSrcExpr);
9932 DstExprs.push_back(PseudoDstExpr);
9933 AssignmentOps.push_back(AssignmentOp.
get());
9940 Vars, SrcExprs, DstExprs, AssignmentOps,
9950 for (
Expr *RefExpr : VarList) {
9951 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
9954 Expr *SimpleRefExpr = RefExpr;
9958 Vars.push_back(RefExpr);
9964 auto *VD = dyn_cast<
VarDecl>(D);
9972 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9973 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
9982 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9984 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9985 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9986 ? RefExpr->IgnoreParens()
9997 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
10002 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
10003 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
10004 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10008 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10015 bool VisitStmt(
Stmt *S) {
10017 if (Child && Visit(Child))
10022 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10029 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
10036 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
10041 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
10042 return CapturedExpr;
10044 return BaseTransform::TransformMemberExpr(E);
10046 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
10050 template <
typename T,
typename U>
10052 const llvm::function_ref<T(
ValueDecl *)> Gen) {
10053 for (U &Set : Lookups) {
10054 for (
auto *D : Set) {
10055 if (T Res = Gen(cast<ValueDecl>(D)))
10081 Lookups.back().append(Lookup.
begin(), Lookup.
end());
10084 }
else if (
auto *ULE =
10085 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10087 Decl *PrevD =
nullptr;
10091 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
10092 Lookups.back().addDecl(DRD);
10099 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) {
10107 ResSet.
append(Set.begin(), Set.end());
10109 ResSet.
addDecl(Set[Set.size() - 1]);
10114 true,
true, ResSet.
begin(), ResSet.
end());
10116 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10124 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10134 if (SemaRef.
IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10136 VD->getType().getUnqualifiedType()))) {
10146 if (ReductionIdScopeSpec.
isSet()) {
10147 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10155 struct ReductionData {
10173 ReductionData() =
delete;
10175 ReductionData(
unsigned Size) {
10176 Vars.reserve(Size);
10177 Privates.reserve(Size);
10178 LHSs.reserve(Size);
10179 RHSs.reserve(Size);
10180 ReductionOps.reserve(Size);
10181 TaskgroupDescriptors.reserve(Size);
10182 ExprCaptures.reserve(Size);
10183 ExprPostUpdates.reserve(Size);
10187 void push(
Expr *Item,
Expr *ReductionOp) {
10188 Vars.emplace_back(Item);
10189 Privates.emplace_back(
nullptr);
10190 LHSs.emplace_back(
nullptr);
10191 RHSs.emplace_back(
nullptr);
10192 ReductionOps.emplace_back(ReductionOp);
10193 TaskgroupDescriptors.emplace_back(
nullptr);
10197 Expr *TaskgroupDescriptor) {
10198 Vars.emplace_back(Item);
10199 Privates.emplace_back(Private);
10200 LHSs.emplace_back(LHS);
10201 RHSs.emplace_back(RHS);
10202 ReductionOps.emplace_back(ReductionOp);
10203 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10212 if (Length ==
nullptr) {
10219 SingleElement =
true;
10220 ArraySizes.push_back(llvm::APSInt::get(1));
10222 llvm::APSInt ConstantLengthValue;
10226 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10227 ArraySizes.push_back(ConstantLengthValue);
10235 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10236 Length = TempOASE->getLength();
10237 if (Length ==
nullptr) {
10244 ArraySizes.push_back(llvm::APSInt::get(1));
10246 llvm::APSInt ConstantLengthValue;
10247 if (!Length->
EvaluateAsInt(ConstantLengthValue, Context) ||
10248 ConstantLengthValue.getSExtValue() != 1)
10251 ArraySizes.push_back(ConstantLengthValue);
10257 if (!SingleElement) {
10258 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10260 ArraySizes.push_back(llvm::APSInt::get(1));
10314 case OO_Array_Delete:
10323 case OO_GreaterEqual:
10325 case OO_MinusEqual:
10327 case OO_SlashEqual:
10328 case OO_PercentEqual:
10329 case OO_CaretEqual:
10333 case OO_GreaterGreater:
10334 case OO_LessLessEqual:
10335 case OO_GreaterGreaterEqual:
10336 case OO_EqualEqual:
10337 case OO_ExclaimEqual:
10340 case OO_MinusMinus:
10346 case OO_Conditional:
10349 llvm_unreachable(
"Unexpected reduction identifier");
10352 if (II->isStr(
"max"))
10354 else if (II->isStr(
"min"))
10360 if (ReductionIdScopeSpec.
isValid())
10366 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10367 bool FirstIter =
true;
10368 for (
Expr *RefExpr : VarList) {
10369 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
10377 if (!FirstIter && IR != ER)
10382 Expr *SimpleRefExpr = RefExpr;
10391 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10392 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10393 Expr *ReductionOp =
nullptr;
10395 (DeclareReductionRef.
isUnset() ||
10396 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
10397 ReductionOp = DeclareReductionRef.
get();
10399 RD.push(RefExpr, ReductionOp);
10405 Expr *TaskgroupDescriptor =
nullptr;
10410 Type = ASE->getType().getNonReferenceType();
10415 Type = ATy->getElementType();
10422 auto *VD = dyn_cast<
VarDecl>(D);
10428 diag::err_omp_reduction_incomplete_type))
10434 S.
Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10435 if (!ASE && !OASE) {
10436 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10439 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10447 if (!ASE && !OASE && VD) {
10449 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
10450 DSARefChecker Check(Stack);
10451 if (Check.Visit(VDDef->
getInit())) {
10452 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10471 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
10472 if (DVar.CKind == OMPC_reduction) {
10473 S.
Diag(ELoc, diag::err_omp_once_referenced)
10476 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10480 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
10495 DVar = Stack->getImplicitDSA(D,
true);
10496 if (DVar.CKind != OMPC_shared) {
10497 S.
Diag(ELoc, diag::err_omp_required_access)
10509 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10510 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10514 (DeclareReductionRef.
isUnset() ||
10515 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
10516 RD.push(RefExpr, DeclareReductionRef.
get());
10519 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
10521 S.
Diag(ReductionId.getLocStart(),
10522 diag::err_omp_unknown_reduction_identifier)
10523 << Type << ReductionIdRange;
10535 if (DeclareReductionRef.
isUnset()) {
10536 if ((BOK == BO_GT || BOK == BO_LT) &&
10537 !(Type->isScalarType() ||
10538 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10539 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10541 if (!ASE && !OASE) {
10542 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10545 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10550 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10551 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
10552 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10554 if (!ASE && !OASE) {
10555 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10558 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10565 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10574 bool ConstantLengthOASE =
false;
10576 bool SingleElement;
10579 Context, OASE, SingleElement, ArraySizes);
10582 if (ConstantLengthOASE && !SingleElement) {
10583 for (llvm::APSInt &Size : ArraySizes)
10589 if ((OASE && !ConstantLengthOASE) ||
10594 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10595 S.
Diag(ELoc, diag::note_vla_unsupported);
10607 }
else if (!ASE && !OASE &&
10615 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
10617 Expr *Init =
nullptr;
10620 if (DeclareReductionRef.
isUsable()) {
10622 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10623 if (DRD->getInitializer()) {
10625 RHSVD->setInit(DRDRef);
10635 if (Type->isScalarType() || Type->isAnyComplexType())
10640 if (Type->isScalarType() || Type->isAnyComplexType()) {
10649 Type = ComplexTy->getElementType();
10650 if (Type->isRealFloatingType()) {
10651 llvm::APFloat InitValue =
10652 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
10656 }
else if (Type->isScalarType()) {
10659 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10676 if (Type->isIntegerType() || Type->isPointerType()) {
10681 llvm::APInt InitValue =
10682 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10683 : llvm::APInt::getMinValue(Size)
10684 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10685 : llvm::APInt::getMaxValue(Size);
10687 if (Type->isPointerType()) {
10693 Init = CastExpr.
get();
10695 }
else if (Type->isRealFloatingType()) {
10696 llvm::APFloat InitValue = llvm::APFloat::getLargest(
10727 llvm_unreachable(
"Unexpected reduction operation");
10730 if (Init && DeclareReductionRef.
isUnset())
10734 if (RHSVD->isInvalidDecl())
10736 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
10737 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10738 << Type << ReductionIdRange;
10739 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10742 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10748 PrivateVD->
setInit(RHSVD->getInit());
10752 if (DeclareReductionRef.
isUsable()) {
10753 QualType RedTy = DeclareReductionRef.
get()->getType();
10757 if (!BasePath.empty()) {
10761 CK_UncheckedDerivedToBase, LHS.
get(),
10762 &BasePath, LHS.
get()->getValueKind());
10764 CK_UncheckedDerivedToBase, RHS.get(),
10765 &BasePath, RHS.get()->getValueKind());
10768 QualType Params[] = {PtrRedTy, PtrRedTy};
10774 ReductionOp =
new (Context)
10778 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10780 if (BOK != BO_LT && BOK != BO_GT) {
10782 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10783 BO_Assign, LHSDRE, ReductionOp.
get());
10785 auto *ConditionalOp =
new (Context)
10789 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10790 BO_Assign, LHSDRE, ConditionalOp);
10806 if (ClauseKind == OMPC_in_reduction) {
10809 const Expr *ParentReductionOp;
10810 Expr *ParentBOKTD, *ParentReductionOpTD;
10811 DSAStackTy::DSAVarData ParentBOKDSA =
10812 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10814 DSAStackTy::DSAVarData ParentReductionOpDSA =
10815 Stack->getTopMostTaskgroupReductionData(
10816 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10817 bool IsParentBOK = ParentBOKDSA.DKind !=
OMPD_unknown;
10818 bool IsParentReductionOp = ParentReductionOpDSA.DKind !=
OMPD_unknown;
10819 if (!IsParentBOK && !IsParentReductionOp) {
10820 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10823 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
10824 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
10825 IsParentReductionOp) {
10826 bool EmitError =
true;
10827 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
10828 llvm::FoldingSetNodeID RedId, ParentRedId;
10829 ParentReductionOp->
Profile(ParentRedId, Context,
true);
10830 DeclareReductionRef.
get()->Profile(RedId, Context,
10832 EmitError = RedId != ParentRedId;
10835 S.
Diag(ReductionId.getLocStart(),
10836 diag::err_omp_reduction_identifier_mismatch)
10837 << ReductionIdRange << RefExpr->getSourceRange();
10839 diag::note_omp_previous_reduction_identifier)
10841 << (IsParentBOK ? ParentBOKDSA.RefExpr
10842 : ParentReductionOpDSA.RefExpr)
10843 ->getSourceRange();
10847 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10848 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
10855 TransformExprToCaptures RebuildToCapture(S, D);
10857 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
10858 Ref = RebuildToCapture.getCapturedExpr();
10860 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
10863 RD.ExprCaptures.emplace_back(Ref->
getDecl());
10869 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10874 Stack->getCurrentDirective() == OMPD_taskgroup) {
10875 S.
Diag(RefExpr->getExprLoc(),
10876 diag::err_omp_reduction_non_addressable_expression)
10877 << RefExpr->getSourceRange();
10880 RD.ExprPostUpdates.emplace_back(
10887 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10888 if (CurrDir == OMPD_taskgroup) {
10889 if (DeclareReductionRef.
isUsable())
10890 Stack->addTaskgroupReductionData(D, ReductionIdRange,
10891 DeclareReductionRef.
get());
10893 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10895 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
10896 TaskgroupDescriptor);
10898 return RD.Vars.empty();
10906 ReductionData RD(VarList.size());
10908 StartLoc, LParenLoc, ColonLoc, EndLoc,
10909 ReductionIdScopeSpec, ReductionId,
10910 UnresolvedReductions, RD))
10914 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10916 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10926 ReductionData RD(VarList.size());
10928 StartLoc, LParenLoc, ColonLoc, EndLoc,
10929 ReductionIdScopeSpec, ReductionId,
10930 UnresolvedReductions, RD))
10934 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10936 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10946 ReductionData RD(VarList.size());
10948 StartLoc, LParenLoc, ColonLoc, EndLoc,
10949 ReductionIdScopeSpec, ReductionId,
10950 UnresolvedReductions, RD))
10954 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10956 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10963 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10965 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10974 const auto *VD = dyn_cast_or_null<VarDecl>(D);
10976 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10978 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10980 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10988 Diag(ELoc, diag::err_omp_const_variable)
10995 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11004 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11005 !Ty->isPointerType())) {
11006 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11012 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11029 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11030 LinKind = OMPC_LINEAR_val;
11031 for (
Expr *RefExpr : VarList) {
11032 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11035 Expr *SimpleRefExpr = RefExpr;
11040 Vars.push_back(RefExpr);
11041 Privates.push_back(
nullptr);
11042 Inits.push_back(
nullptr);
11049 auto *VD = dyn_cast<
VarDecl>(D);
11055 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
11056 if (DVar.RefExpr) {
11063 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11071 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11077 if (!VD && !CurContext->isDependentContext()) {
11079 if (!isOpenMPCapturedDecl(D)) {
11080 ExprCaptures.push_back(Ref->
getDecl());
11082 ExprResult RefRes = DefaultLvalueConversion(Ref);
11086 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
11087 SimpleRefExpr, RefRes.
get());
11090 ExprPostUpdates.push_back(
11091 IgnoredValueConversions(PostUpdateRes.
get()).
get());
11095 if (LinKind == OMPC_LINEAR_uval)
11096 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11098 InitExpr = VD ? SimpleRefExpr : Ref;
11099 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
11103 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11104 Vars.push_back((VD || CurContext->isDependentContext())
11105 ? RefExpr->IgnoreParens()
11107 Privates.push_back(PrivateRef);
11108 Inits.push_back(InitRef);
11115 Expr *CalcStepExpr =
nullptr;
11120 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11123 StepExpr = Val.
get();
11131 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11132 CalcStep = ActOnFinishFullExpr(CalcStep.get());
11138 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11139 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11140 << (Vars.size() > 1);
11141 if (!IsConstant && CalcStep.isUsable()) {
11144 CalcStepExpr = CalcStep.get();
11149 ColonLoc, EndLoc, Vars, Privates, Inits,
11150 StepExpr, CalcStepExpr,
11156 Expr *NumIterations,
Sema &SemaRef,
11157 Scope *S, DSAStackTy *Stack) {
11168 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
11169 bool HasErrors =
false;
11170 auto CurInit = Clause.inits().begin();
11171 auto CurPrivate = Clause.privates().begin();
11176 Expr *SimpleRefExpr = RefExpr;
11180 if (Res.second || !D) {
11181 Updates.push_back(
nullptr);
11182 Finals.push_back(
nullptr);
11186 auto &&Info = Stack->isLoopControlVariable(D);
11193 diag::err_omp_linear_distribute_var_non_loop_iteration);
11194 Updates.push_back(
nullptr);
11195 Finals.push_back(
nullptr);
11199 Expr *InitExpr = *CurInit;
11202 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11204 if (LinKind == OMPC_LINEAR_uval)
11205 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11209 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11217 InitExpr, IV,
Step,
false);
11219 Update = *CurPrivate;
11228 InitExpr, NumIterations,
Step,
false);
11230 Final = *CurPrivate;
11234 if (!Update.isUsable() || !Final.isUsable()) {
11235 Updates.push_back(
nullptr);
11236 Finals.push_back(
nullptr);
11239 Updates.push_back(Update.get());
11240 Finals.push_back(Final.get());
11245 Clause.setUpdates(Updates);
11246 Clause.setFinals(Finals);
11254 for (
Expr *RefExpr : VarList) {
11255 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11258 Expr *SimpleRefExpr = RefExpr;
11263 Vars.push_back(RefExpr);
11270 auto *VD = dyn_cast<
VarDecl>(D);
11276 const Type *Ty = QType.getTypePtrOrNull();
11278 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11279 << QType << getLangOpts().CPlusPlus << ERange;
11284 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11291 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11292 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11293 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11299 if (!VD && isOpenMPCapturedDecl(D))
11301 Vars.push_back(DefaultFunctionArrayConversion(
11302 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11311 if (Alignment !=
nullptr) {
11313 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11316 Alignment = AlignResult.
get();
11322 EndLoc, Vars, Alignment);
11333 for (
Expr *RefExpr : VarList) {
11334 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
11335 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11337 Vars.push_back(RefExpr);
11338 SrcExprs.push_back(
nullptr);
11339 DstExprs.push_back(
nullptr);
11340 AssignmentOps.push_back(
nullptr);
11350 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11351 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11352 << 0 << RefExpr->getSourceRange();
11356 Decl *D = DE->getDecl();
11357 auto *VD = cast<VarDecl>(D);
11360 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11362 Vars.push_back(DE);
11363 SrcExprs.push_back(
nullptr);
11364 DstExprs.push_back(
nullptr);
11365 AssignmentOps.push_back(
nullptr);
11371 if (!
DSAStack->isThreadPrivate(VD)) {
11372 Diag(ELoc, diag::err_omp_required_access)
11385 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11389 buildVarDecl(*
this, DE->getLocStart(), ElemType,
".copyin.dst",
11390 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11396 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11398 if (AssignmentOp.isInvalid())
11400 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11402 if (AssignmentOp.isInvalid())
11405 DSAStack->addDSA(VD, DE, OMPC_copyin);
11406 Vars.push_back(DE);
11407 SrcExprs.push_back(PseudoSrcExpr);
11408 DstExprs.push_back(PseudoDstExpr);
11409 AssignmentOps.push_back(AssignmentOp.get());
11416 SrcExprs, DstExprs, AssignmentOps);
11427 for (
Expr *RefExpr : VarList) {
11428 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11431 Expr *SimpleRefExpr = RefExpr;
11436 Vars.push_back(RefExpr);
11437 SrcExprs.push_back(
nullptr);
11438 DstExprs.push_back(
nullptr);
11439 AssignmentOps.push_back(
nullptr);
11446 auto *VD = dyn_cast<
VarDecl>(D);
11451 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
11452 DSAStackTy::DSAVarData DVar =
11454 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11456 Diag(ELoc, diag::err_omp_wrong_dsa)
11467 DVar =
DSAStack->getImplicitDSA(D,
false);
11468 if (DVar.CKind == OMPC_shared) {
11469 Diag(ELoc, diag::err_omp_required_access)
11471 <<
"threadprivate or private in the enclosing context";
11480 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11487 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11497 .getUnqualifiedType();
11499 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.src",
11503 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.dst",
11507 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
11510 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
11517 assert(VD || isOpenMPCapturedDecl(D));
11519 VD ? RefExpr->IgnoreParens()
11521 SrcExprs.push_back(PseudoSrcExpr);
11522 DstExprs.push_back(PseudoDstExpr);
11523 AssignmentOps.push_back(AssignmentOp.
get());
11530 Vars, SrcExprs, DstExprs, AssignmentOps);
11537 if (VarList.empty())
11548 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
11549 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11550 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11554 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
11556 DepKind == OMPC_DEPEND_sink)) {
11557 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11558 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11566 llvm::APSInt DepCounter(32);
11567 llvm::APSInt TotalDepCount(32);
11568 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
11569 if (
const Expr *OrderedCountExpr =
11570 DSAStack->getParentOrderedRegionParam().first) {
11571 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11572 TotalDepCount.setIsUnsigned(
true);
11575 for (
Expr *RefExpr : VarList) {
11576 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
11577 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11579 Vars.push_back(RefExpr);
11585 if (DepKind == OMPC_DEPEND_sink) {
11586 if (
DSAStack->getParentOrderedRegionParam().first &&
11587 DepCounter >= TotalDepCount) {
11588 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11600 if (CurContext->isDependentContext()) {
11602 Vars.push_back(RefExpr);
11608 Expr *LHS = SimpleExpr;
11609 Expr *RHS =
nullptr;
11610 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11612 OOLoc = BO->getOperatorLoc();
11615 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11616 OOK = OCE->getOperator();
11617 OOLoc = OCE->getOperatorLoc();
11620 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11621 OOK = MCE->getMethodDecl()
11624 .getCXXOverloadedOperator();
11625 OOLoc = MCE->getCallee()->getExprLoc();
11635 Vars.push_back(RefExpr);
11641 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
11642 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11646 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11647 RHS, OMPC_depend,
false);
11651 if (!CurContext->isDependentContext() &&
11652 DSAStack->getParentOrderedRegionParam().first &&
11653 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
11655 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
11657 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11660 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11663 OpsOffs.emplace_back(RHS, OOK);
11666 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11668 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
11669 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11670 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11671 << RefExpr->getSourceRange();
11674 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11675 getDiagnostics().setSuppressAllDiagnostics(
true);
11677 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
11678 getDiagnostics().setSuppressAllDiagnostics(Suppress);
11679 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11680 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11681 << RefExpr->getSourceRange();
11685 Vars.push_back(RefExpr->IgnoreParenImpCasts());
11688 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11689 TotalDepCount > VarList.size() &&
11690 DSAStack->getParentOrderedRegionParam().first &&
11691 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11692 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
11693 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11695 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11700 DepKind, DepLoc, ColonLoc, Vars,
11701 TotalDepCount.getZExtValue());
11702 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
11703 DSAStack->isParentOrderedRegion())
11704 DSAStack->addDoacrossDependClause(
C, OpsOffs);
11711 Expr *ValExpr = Device;
11712 Stmt *HelperValStmt =
nullptr;
11723 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
11724 ValExpr = MakeFullExpr(ValExpr).get();
11725 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11726 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11730 return new (Context)
OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
11731 StartLoc, LParenLoc, EndLoc);
11736 bool FullCheck =
true) {
11739 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
11744 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
11759 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11760 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
11761 return ATy->getSize().getSExtValue() != 1;
11766 assert(OASE &&
"Expecting array section if not an array subscript.");
11767 const Expr *LowerBound = OASE->getLowerBound();
11768 const Expr *Length = OASE->getLength();
11773 llvm::APSInt ConstLowerBound;
11776 if (ConstLowerBound.getSExtValue())
11795 llvm::APSInt ConstLength;
11799 return CATy->
getSize().getSExtValue() != ConstLength.getSExtValue();
11812 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11815 assert(OASE &&
"Expecting array section if not an array subscript.");
11816 const Expr *Length = OASE->getLength();
11822 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
11823 return ATy->getSize().getSExtValue() != 1;
11829 llvm::APSInt ConstLength;
11833 return ConstLength.getSExtValue() != 1;
11866 const Expr *RelevantExpr =
nullptr;
11885 bool AllowUnitySizeArraySection =
true;
11886 bool AllowWholeSizeArraySection =
true;
11888 while (!RelevantExpr) {
11891 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11892 if (!isa<VarDecl>(CurE->getDecl()))
11895 RelevantExpr = CurE;
11899 AllowUnitySizeArraySection =
false;
11900 AllowWholeSizeArraySection =
false;
11903 CurComponents.emplace_back(CurE, CurE->getDecl());
11904 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
11907 if (isa<CXXThisExpr>(BaseE))
11909 RelevantExpr = CurE;
11913 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11915 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11916 << CurE->getSourceRange();
11924 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11929 if (FD->isBitField()) {
11931 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11951 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
11952 << CurE->getSourceRange();
11965 AllowUnitySizeArraySection =
false;
11966 AllowWholeSizeArraySection =
false;
11969 CurComponents.emplace_back(CurE, FD);
11970 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11975 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
11976 << 0 << CurE->getSourceRange();
11987 AllowWholeSizeArraySection =
false;
11990 CurComponents.emplace_back(CurE,
nullptr);
11991 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11992 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
12007 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
12008 << 0 << CurE->getSourceRange();
12017 if (AllowWholeSizeArraySection) {
12024 if (NotWhole || IsPointer)
12025 AllowWholeSizeArraySection =
false;
12026 }
else if (AllowUnitySizeArraySection && NotUnity) {
12030 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12031 << CurE->getSourceRange();
12036 CurComponents.emplace_back(CurE,
nullptr);
12041 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12048 return RelevantExpr;
12055 bool CurrentRegionOnly,
12066 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
12067 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12068 "Map clause expression with unexpected base!");
12071 bool IsEnclosedByDataEnvironmentExpr =
false;
12072 const Expr *EnclosingExpr =
nullptr;
12074 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12075 VD, CurrentRegionOnly,
12076 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12077 ERange, CKind, &EnclosingExpr,
12081 assert(!StackComponents.empty() &&
12082 "Map clause expression with no components!");
12083 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12084 "Map clause expression with unexpected base!");
12088 const Expr *RE = StackComponents.front().getAssociatedExpression();
12094 auto CI = CurComponents.rbegin();
12095 auto CE = CurComponents.rend();
12096 auto SI = StackComponents.rbegin();
12097 auto SE = StackComponents.rend();
12098 for (; CI != CE && SI != SE; ++CI, ++SI) {
12103 if (CurrentRegionOnly &&
12104 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12105 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12106 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12107 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12108 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
12109 diag::err_omp_multiple_array_items_in_map_clause)
12110 << CI->getAssociatedExpression()->getSourceRange();
12111 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
12112 diag::note_used_here)
12113 << SI->getAssociatedExpression()->getSourceRange();
12118 if (CI->getAssociatedExpression()->getStmtClass() !=
12119 SI->getAssociatedExpression()->getStmtClass())
12123 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12129 for (; SI != SE; ++SI) {
12131 if (
const auto *ASE =
12132 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12133 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12134 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12135 SI->getAssociatedExpression())) {
12142 SemaRef, SI->getAssociatedExpression(), Type))
12152 if (CI == CE && SI == SE) {
12153 if (CurrentRegionOnly) {
12154 if (CKind == OMPC_map) {
12155 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12157 assert(CKind == OMPC_to || CKind == OMPC_from);
12158 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12161 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12162 << RE->getSourceRange();
12167 IsEnclosedByDataEnvironmentExpr =
true;
12172 std::prev(CI)->getAssociatedDeclaration()->getType();
12174 std::prev(CI)->getAssociatedExpression()->getExprLoc();
12193 if (CI == CE || SI == SE) {
12196 diag::err_omp_pointer_mapped_along_with_derived_section)
12198 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12199 << RE->getSourceRange();
12202 if (CI->getAssociatedExpression()->getStmtClass() !=
12203 SI->getAssociatedExpression()->getStmtClass() ||
12204 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12205 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12206 assert(CI != CE && SI != SE);
12207 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12209 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12210 << RE->getSourceRange();
12220 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12221 if (CKind == OMPC_map) {
12222 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12224 assert(CKind == OMPC_to || CKind == OMPC_from);
12225 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12228 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12229 << RE->getSourceRange();
12235 if (!CurrentRegionOnly && SI != SE)
12236 EnclosingExpr = RE;
12240 IsEnclosedByDataEnvironmentExpr |=
12241 (!CurrentRegionOnly && CI != CE && SI == SE);
12246 if (CurrentRegionOnly)
12260 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12262 diag::err_omp_original_storage_is_shared_and_does_not_contain)
12275 struct MappableVarListInfo {
12288 VarComponents.reserve(VarList.size());
12289 VarBaseDeclarations.reserve(VarList.size());
12304 bool IsMapTypeImplicit =
false) {
12306 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12307 "Unexpected clause kind with mappable expressions!");
12315 for (
Expr *RE : MVLI.VarList) {
12316 assert(RE &&
"Null expr in omp to/from/map clause");
12326 MVLI.ProcessedVarList.push_back(RE);
12334 diag::err_omp_expected_named_var_member_or_array_expression)
12345 SemaRef, SimpleExpr, CurComponents, CKind,
false);
12349 assert(!CurComponents.empty() &&
12350 "Invalid mappable expression information.");
12355 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12356 assert(CurDeclaration &&
"Null decl on map clause.");
12358 CurDeclaration->isCanonicalDecl() &&
12359 "Expecting components to have associated only canonical declarations.");
12361 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
12362 const auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
12364 assert((VD || FD) &&
"Only variables or fields are expected here!");
12371 if (VD && DSAS->isThreadPrivate(VD)) {
12372 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
12373 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12388 true, CurComponents, CKind))
12390 if (CKind == OMPC_map &&
12392 false, CurComponents, CKind))
12399 auto I = llvm::find_if(
12404 assert(I != CurComponents.end() &&
"Null decl on map clause.");
12406 I->getAssociatedDeclaration()->getType().getNonReferenceType();
12416 if (CKind == OMPC_map) {
12422 if (DKind == OMPD_target_enter_data &&
12423 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12424 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12425 << (IsMapTypeImplicit ? 1 : 0)
12435 if (DKind == OMPD_target_exit_data &&
12436 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12437 MapType == OMPC_MAP_delete)) {
12438 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12439 << (IsMapTypeImplicit ? 1 : 0)
12449 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
12451 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12462 MVLI.ProcessedVarList.push_back(RE);
12466 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12472 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12473 MVLI.VarComponents.back().append(CurComponents.begin(),
12474 CurComponents.end());
12475 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 12486 MappableVarListInfo MVLI(VarList);
12488 MapType, IsMapTypeImplicit);
12493 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12494 MVLI.VarComponents, MapTypeModifier, MapType,
12495 IsMapTypeImplicit, MapLoc);
12502 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
12503 if (ReductionType.isNull())
12510 if (ReductionType.hasQualifiers()) {
12511 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12515 if (ReductionType->isFunctionType()) {
12516 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12519 if (ReductionType->isReferenceType()) {
12520 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12523 if (ReductionType->isArrayType()) {
12524 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12527 return ReductionType;
12532 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12535 Decls.reserve(ReductionTypes.size());
12538 forRedeclarationInCurContext());
12543 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12545 bool InCompoundScope =
true;
12546 if (S !=
nullptr) {
12552 LookupName(Lookup, S);
12553 FilterLookupForScope(Lookup, DC, S,
false,
12555 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12558 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.
next());
12559 if (InCompoundScope) {
12560 auto I = UsedAsPrevious.find(PrevDecl);
12561 if (I == UsedAsPrevious.end())
12562 UsedAsPrevious[PrevDecl] =
false;
12564 UsedAsPrevious[D] =
true;
12566 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12567 PrevDecl->getLocation();
12570 if (InCompoundScope) {
12571 for (
const auto &PrevData : UsedAsPrevious) {
12572 if (!PrevData.second) {
12573 PrevDRD = PrevData.first;
12578 }
else if (PrevDeclInScope !=
nullptr) {
12579 auto *PrevDRDInScope = PrevDRD =
12580 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12582 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12584 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12585 }
while (PrevDRDInScope !=
nullptr);
12587 for (
const auto &TyData : ReductionTypes) {
12588 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12589 bool Invalid =
false;
12590 if (I != PreviousRedeclTypes.end()) {
12591 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12593 Diag(I->second, diag::note_previous_definition);
12596 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12598 Name, TyData.first, PrevDRD);
12600 DRD->setAccess(AS);
12601 Decls.push_back(DRD);
12603 DRD->setInvalidDecl();
12608 return DeclGroupPtrTy::make(
12613 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12616 PushFunctionScope();
12617 setFunctionHasBranchProtectedScope();
12618 getCurFunction()->setHasOMPDeclareReductionCombiner();
12621 PushDeclContext(S, DRD);
12625 PushExpressionEvaluationContext(
12626 ExpressionEvaluationContext::PotentiallyEvaluated);
12628 QualType ReductionType = DRD->getType();
12645 if (S !=
nullptr) {
12646 PushOnScopeChains(OmpInParm, S);
12647 PushOnScopeChains(OmpOutParm, S);
12649 DRD->addDecl(OmpInParm);
12650 DRD->addDecl(OmpOutParm);
12655 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12656 DiscardCleanupsInEvaluationContext();
12657 PopExpressionEvaluationContext();
12660 PopFunctionScopeInfo();
12662 if (Combiner !=
nullptr)
12663 DRD->setCombiner(Combiner);
12665 DRD->setInvalidDecl();
12669 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12672 PushFunctionScope();
12673 setFunctionHasBranchProtectedScope();
12676 PushDeclContext(S, DRD);
12680 PushExpressionEvaluationContext(
12681 ExpressionEvaluationContext::PotentiallyEvaluated);
12683 QualType ReductionType = DRD->getType();
12700 if (S !=
nullptr) {
12701 PushOnScopeChains(OmpPrivParm, S);
12702 PushOnScopeChains(OmpOrigParm, S);
12704 DRD->addDecl(OmpPrivParm);
12705 DRD->addDecl(OmpOrigParm);
12707 return OmpPrivParm;
12712 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12713 DiscardCleanupsInEvaluationContext();
12714 PopExpressionEvaluationContext();
12717 PopFunctionScopeInfo();
12719 if (Initializer !=
nullptr) {
12721 }
else if (OmpPrivParm->
hasInit()) {
12722 DRD->setInitializer(OmpPrivParm->
getInit(),
12727 DRD->setInvalidDecl();
12733 for (
Decl *D : DeclReductions.
get()) {
12736 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
12742 return DeclReductions;
12749 Expr *ValExpr = NumTeams;
12750 Stmt *HelperValStmt =
nullptr;
12761 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12762 ValExpr = MakeFullExpr(ValExpr).get();
12763 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12764 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12769 StartLoc, LParenLoc, EndLoc);
12776 Expr *ValExpr = ThreadLimit;
12777 Stmt *HelperValStmt =
nullptr;
12788 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12789 ValExpr = MakeFullExpr(ValExpr).get();
12790 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12791 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12796 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12803 Expr *ValExpr = Priority;
12818 Expr *ValExpr = Grainsize;
12834 Expr *ValExpr = NumTasks;
12852 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12855 return new (Context)
12864 std::string Values;
12868 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12872 Expr *ValExpr = ChunkSize;
12873 Stmt *HelperValStmt =
nullptr;
12880 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12884 ValExpr = Val.
get();
12891 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12892 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12897 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12899 !CurContext->isDependentContext()) {
12900 ValExpr = MakeFullExpr(ValExpr).get();
12901 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12902 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12908 return new (Context)
12910 Kind, ValExpr, HelperValStmt);
12918 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12922 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12924 OMPC_DEFAULTMAP_MODIFIER_tofrom);
12928 OMPC_DEFAULTMAP_scalar);
12932 Diag(Loc, diag::err_omp_unexpected_clause_value)
12936 DSAStack->setDefaultDMAToFromScalar(StartLoc);
12938 return new (Context)
12943 DeclContext *CurLexicalContext = getCurLexicalContext();
12947 !isa<CXXRecordDecl>(CurLexicalContext) &&
12948 !isa<ClassTemplateDecl>(CurLexicalContext) &&
12949 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12950 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12951 Diag(Loc, diag::err_omp_region_not_file_context);
12954 if (IsInOpenMPDeclareTargetContext) {
12955 Diag(Loc, diag::err_omp_enclosed_declare_target);
12959 IsInOpenMPDeclareTargetContext =
true;
12964 assert(IsInOpenMPDeclareTargetContext &&
12965 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12966 IsInOpenMPDeclareTargetContext =
false;
12972 OMPDeclareTargetDeclAttr::MapTypeTy MT,
12975 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
12983 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr,
12984 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
12985 CTK_ErrorRecovery)) {
12986 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12988 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
12997 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
13000 if (!ND->
hasAttr<OMPDeclareTargetDeclAttr>()) {
13001 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13004 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13005 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Id.
getLoc());
13006 }
else if (ND->
getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
13007 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
13019 const Decl *LD =
nullptr;
13020 if (isa<TagDecl>(D)) {
13022 }
else if (isa<VarDecl>(D)) {
13027 if (cast<VarDecl>(D)->isImplicit()) {
13028 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13029 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
13032 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13035 }
else if (
const auto *F = dyn_cast<FunctionDecl>(D)) {
13037 if (cast<FunctionDecl>(D)->hasBody(FD)) {
13043 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13044 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
13047 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13050 }
else if (F->isFunctionTemplateSpecialization() &&
13051 F->getTemplateSpecializationKind() ==
13056 if (FTD && FTD->
hasAttr<OMPDeclareTargetDeclAttr>())
13062 if (LD && !LD->
hasAttr<OMPDeclareTargetDeclAttr>() &&
13063 ((isa<VarDecl>(LD) && !isa<ParmVarDecl>(LD)) || isa<FunctionDecl>(LD))) {
13065 if (!isa<FunctionDecl>(LD)) {
13067 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
13068 SemaRef.
Diag(SL, diag::note_used_here) << SR;
13072 (!isa<FunctionDecl>(DC) ||
13073 !cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()))
13079 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
13080 SemaRef.
Diag(SL, diag::note_used_here) << SR;
13084 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13085 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
13088 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13093 Sema &SemaRef, DSAStackTy *Stack,
13095 return VD->
hasAttr<OMPDeclareTargetDeclAttr>() ||
13106 if (
auto *VD = dyn_cast<VarDecl>(D)) {
13108 if (VD->isLocalVarDeclOrParm())
13112 if (
DSAStack->isThreadPrivate(VD)) {
13113 Diag(SL, diag::err_omp_threadprivate_in_target);
13118 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
13124 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) ||
13125 isa<FunctionTemplateDecl>(VD)) {
13126 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13127 Context, OMPDeclareTargetDeclAttr::MT_To);
13130 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
13135 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13136 D = FTD->getTemplatedDecl();
13137 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
13138 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
13139 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
13140 OMPDeclareTargetDeclAttr::MT_Link)) {
13141 assert(IdLoc.
isValid() &&
"Source location is expected");
13142 Diag(IdLoc, diag::err_omp_function_in_link_clause);
13143 Diag(FD->getLocation(), diag::note_defined_here) << FD;
13149 if (!D->
hasAttr<OMPDeclareTargetDeclAttr>() &&
13150 (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13151 isa<FunctionTemplateDecl>(D))) {
13152 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13153 Context, OMPDeclareTargetDeclAttr::MT_To);
13156 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13167 MappableVarListInfo MVLI(VarList);
13169 if (MVLI.ProcessedVarList.empty())
13173 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13174 MVLI.VarComponents);
13181 MappableVarListInfo MVLI(VarList);
13183 if (MVLI.ProcessedVarList.empty())
13187 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13188 MVLI.VarComponents);
13195 MappableVarListInfo MVLI(VarList);
13199 for (
Expr *RefExpr : VarList) {
13200 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
13203 Expr *SimpleRefExpr = RefExpr;
13207 MVLI.ProcessedVarList.push_back(RefExpr);
13208 PrivateCopies.push_back(
nullptr);
13209 Inits.push_back(
nullptr);
13218 auto *VD = dyn_cast<
VarDecl>(D);
13222 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13223 << 0 << RefExpr->getSourceRange();
13231 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
13232 if (VDPrivate->isInvalidDecl())
13235 CurContext->addDecl(VDPrivate);
13237 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13241 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
13243 *
this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13244 AddInitializerToDecl(VDPrivate,
13245 DefaultLvalueConversion(VDInitRefExpr).
get(),
13253 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13254 PrivateCopies.push_back(VDPrivateRefExpr);
13255 Inits.push_back(VDInitRefExpr);
13260 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13264 MVLI.VarBaseDeclarations.push_back(D);
13265 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13266 MVLI.VarComponents.back().push_back(
13270 if (MVLI.ProcessedVarList.empty())
13274 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13275 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13282 MappableVarListInfo MVLI(VarList);
13283 for (
Expr *RefExpr : VarList) {
13284 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
13287 Expr *SimpleRefExpr = RefExpr;
13291 MVLI.ProcessedVarList.push_back(RefExpr);
13301 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13302 << 0 << RefExpr->getSourceRange();
13308 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
13310 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13318 const Expr *ConflictExpr;
13319 if (
DSAStack->checkMappableExprComponentListsForDecl(
13324 ConflictExpr = R.front().getAssociatedExpression();
13327 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13336 DSAStack->addMappableExpressionComponents(
13337 D, MC, OMPC_is_device_ptr);
13340 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13345 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13346 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13347 "Unexpected device pointer expression!");
13348 MVLI.VarBaseDeclarations.push_back(
13349 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
13350 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13351 MVLI.VarComponents.back().push_back(MC);
13354 if (MVLI.ProcessedVarList.empty())
13358 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13359 MVLI.VarBaseDeclarations, MVLI.VarComponents);
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
QualType withConst() const
Retrieves a version of this type with const applied.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
void setImplicit(bool I=true)
Represents a function declaration or definition.
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'task_reduction' clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
SourceLocation getLocEnd() const LLVM_READONLY
Returns the ending location of the clause.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. '#pragma omp declare target'.
A (possibly-)qualified type.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Simple class containing the result of Sema::CorrectTypo.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
ArrayRef< OMPClause * > clauses()
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
static Opcode getOpForCompoundAssignment(Opcode Opc)
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
static ClassTemplateDecl * getDefinition(ClassTemplateDecl *D)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
SourceLocation getLocStart() const LLVM_READONLY
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Filter makeFilter()
Create a filter for this result set.
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc...
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
static bool hasClauses(ArrayRef< OMPClause *> Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
static OMPUseDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents 'if' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
This represents 'priority' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
const TargetInfo & getTargetInfo() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
void setInitStyle(InitializationStyle Style)
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Represents a C++ constructor within a class.
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Retains information about a function, method, or block that is currently being parsed.
void setNothrow(bool Nothrow=true)
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
This represents 'read' clause in the '#pragma omp atomic' directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
bool isEnumeralType() const
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
const T * getAs() const
Member-template getAs<specific type>'.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Extra information about a function prototype.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isInvalidDecl() const
void setBegin(SourceLocation b)
static const Expr * getExprAsWritten(const Expr *E)
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
bool hasDefinition() const
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * LastIteration
Loop last iteration number.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void ActOnUninitializedDecl(Decl *dcl)
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
One of these records is kept for each identifier that is lexed.
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
This represents 'simd' clause in the '#pragma omp ...' directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Represents a member of a struct/union/class.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement...
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause *> Clauses)
End of OpenMP region.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
bool isReferenceType() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Defines some OpenMP-specific enums and functions.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
Expr * getSafelen() const
Return safe iteration space distance.
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl *> PreInits)
Build preinits statement for the given declarations.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp critical' directive.
void EndOpenMPClause()
End analysis of clauses.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
DeclClass * getAsSingle() const
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
Represents the results of name lookup.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct...
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
ValueDecl * getAssociatedDeclaration() const
Concrete class used by the front-end to report problems and issues.
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Look up the name of an OpenMP user-defined reduction operation.
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
This represents 'default' clause in the '#pragma omp ...' directive.
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Scope - A scope is a transient data structure that is used while parsing the program.
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses)
Creates directive with a list of Clauses.
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Represents a C++ nested-name-specifier or a global scope specifier.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
const LangOptions & getLangOpts() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
bool isScalarType() const
An ordinary object is located at an address in memory.
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
Represents the body of a CapturedStmt, and serves as its DeclContext.
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Expr * Cond
Loop condition.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
DiagnosticsEngine & getDiagnostics() const
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Expr * PreCond
Loop pre-condition.
OpenMP 4.0 [2.4, Array Sections].
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause *> Clauses)
ConditionalOperator - The ?: ternary operator.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
This represents 'threads' clause in the '#pragma omp ...' directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
Expr * getSimdlen() const
Return safe iteration space distance.
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * IterationVarRef
Loop iteration variable.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
VarDecl * isOpenMPCapturedDecl(ValueDecl *D) const
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Allow any unmodeled side effect.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
const T * castAs() const
Member-template castAs<specific type>.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
OpenMPClauseKind
OpenMP clauses.
bool isFileContext() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
SourceLocation getBeginLoc() const
DeclContext * getDeclContext()
bool isAnyComplexType() const
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is used in 'private' clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn't a simple identifier.
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'in_reduction' clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
This represents 'collapse' clause in the '#pragma omp ...' directive.
Represents a C++ conversion function within a class.
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
The result type of a method or function.
This template specialization was implicitly instantiated from a template.
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Expr * ST
Stride - local variable passed to runtime.
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
This captures a statement into a function.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
QualType getCanonicalType() const
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr *> Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
ASTContext & getASTContext() const
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
SourceLocation getOperatorLoc() const
This represents '#pragma omp declare reduction ...' directive.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Pseudo declaration for capturing expressions.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
This is a basic class for representing single OpenMP executable directive.
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents 'schedule' clause in the '#pragma omp ...' directive.
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
SourceLocation getLocStart() const LLVM_READONLY
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr *> PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
IdentifierTable & getIdentifierTable()
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getColonLoc() const
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
This file defines OpenMP nodes for declarative directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
This is a basic class for representing single OpenMP clause.
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const
Return true if the provided declaration VD should be captured by reference.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
bool isAnyPointerType() const
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
A class for iterating through a result set and possibly filtering out results.
This declaration is only a declaration.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
SourceLocation getLocStart() const LLVM_READONLY
Returns the starting location of the clause.
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
DefaultMapAttributes
Attributes of the defaultmap clause.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
QualType withRestrict() const
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
This represents 'device' clause in the '#pragma omp ...' directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
const Scope * getParent() const
getParent - Return the scope that this is nested in.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const Expr * getInit() const
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
bool shouldDiagnoseTargetSupportFromOpenMP() const
Return true if (un)supported features for the current target should be diagnosed if OpenMP (offloadin...
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'use_device_ptr' clause.
This represents clause 'linear' in the '#pragma omp ...' directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is captured by 'target' directive.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
static OMPFromClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
Class that represents a component of a mappable expression.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
Not an overloaded operator.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. '#pragme omp end declare target'.
Complex values, per C99 6.2.5p11.
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
This file defines OpenMP AST classes for executable directives and clauses.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
const llvm::APInt & getSize() const
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S'...
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'is_device_ptr' clause.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Expr * Inc
Loop increment.
DeclContext * getCurLexicalContext() const
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'to' clause.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
ImplicitParamDecl * getParam(unsigned i) const
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build 'VarRef = Start.
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
void addDecl(Decl *D)
Add the declaration D into this context.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
SourceLocation getExprLoc() const LLVM_READONLY
This represents 'write' clause in the '#pragma omp atomic' directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
const Type * getTypePtrOrNull() const
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isSet() const
Deprecated.
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
void Deallocate(void *Ptr) const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
This represents 'nowait' clause in the '#pragma omp ...' directive.
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the '#pragma omp declare target'.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
sema::FunctionScopeInfo * getCurFunction() const
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Do not present this diagnostic, ignore it.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed '#pragma omp threadprivate'.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
__DEVICE__ int max(int __a, int __b)
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct...
Stmt * PreInits
Init statement for all captured expressions.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
bool isStaticDataMember() const
Determines whether this is a static data member.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
bool empty() const
Return true if no decls were found.
An l-value expression is a reference to an object with independent storage.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'from' clause.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
static T filterLookupForUDR(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
bool isConstant(const ASTContext &Ctx) const
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
static OMPClauseWithPostUpdate * get(OMPClause *C)
Describes an entity that is being initialized.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of ':'.
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp threadprivate ...' directive.
VerifyDiagnosticConsumer::Directive Directive
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Represents the canonical version of C arrays with a specified constant size.
Declaration of a template function.
bool getSuppressAllDiagnostics() const
void clear()
Clears out any current state.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
SourceLocation getLocation() const
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
Expr * getLength()
Get length of array section.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].