31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang;
59 class DSAStackTy final {
61 struct DSAVarData final {
64 Expr *RefExpr =
nullptr;
67 DSAVarData() =
default;
70 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
71 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
77 struct DSAInfo final {
81 llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
84 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
85 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
86 typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
87 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
90 struct MappedExprComponentTy {
94 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
95 MappedExprComponentsTy;
96 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
98 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
100 struct ReductionData {
101 typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType;
103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104 ReductionData() =
default;
111 ReductionOp = RefExpr;
114 typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy;
116 struct SharingMapTy final {
117 DeclSAMapTy SharingMap;
118 DeclReductionMapTy ReductionMap;
119 AlignedMapTy AlignedMap;
120 MappedExprComponentsTy MappedExprComponents;
121 LoopControlVariablesMapTy LCVMap;
128 Scope *CurScope =
nullptr;
133 DoacrossDependMapTy DoacrossDepends;
137 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
138 bool NowaitRegion =
false;
139 bool CancelRegion =
false;
140 unsigned AssociatedLoops = 1;
143 Expr *TaskgroupReductionRef =
nullptr;
146 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
148 SharingMapTy() =
default;
154 DeclSAMapTy Threadprivates;
161 bool ForceCapturing =
false;
162 CriticalsWithHintsTy Criticals;
166 DSAVarData getDSA(StackTy::reverse_iterator &Iter,
ValueDecl *D);
169 bool isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter);
171 bool isStackEmpty()
const {
172 return Stack.empty() ||
173 Stack.back().second != CurrentNonCapturingFunctionScope ||
174 Stack.back().first.empty();
178 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
180 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
182 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
183 return ClauseKindMode;
187 bool isForceVarCapturing()
const {
return ForceCapturing; }
188 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
193 Stack.back().second != CurrentNonCapturingFunctionScope)
194 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
195 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
196 Stack.back().first.back().DefaultAttrLoc = Loc;
200 assert(!Stack.back().first.empty() &&
201 "Data-sharing attributes stack is empty!");
202 Stack.back().first.pop_back();
206 void pushFunction() {
208 assert(!isa<CapturingScopeInfo>(CurFnScope));
209 CurrentNonCapturingFunctionScope = CurFnScope;
213 if (!Stack.empty() && Stack.back().second == OldFSI) {
214 assert(Stack.back().first.empty());
217 CurrentNonCapturingFunctionScope =
nullptr;
219 if (!isa<CapturingScopeInfo>(FSI)) {
220 CurrentNonCapturingFunctionScope = FSI;
229 const std::pair<OMPCriticalDirective *, llvm::APSInt>
232 if (I != Criticals.end())
234 return std::make_pair(
nullptr, llvm::APSInt());
247 LCDeclInfo isLoopControlVariable(
ValueDecl *D);
252 LCDeclInfo isParentLoopControlVariable(
ValueDecl *D);
255 ValueDecl *getParentLoopControlVariable(
unsigned I);
268 const Expr *ReductionRef);
273 Expr *&TaskgroupDescriptor);
277 const Expr *&ReductionRef,
278 Expr *&TaskgroupDescriptor);
280 Expr *getTaskgroupReductionRef()
const {
281 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
282 "taskgroup reference expression requested for non taskgroup " 284 return Stack.back().first.back().TaskgroupReductionRef;
288 bool isTaskgroupReductionRef(
ValueDecl *VD,
unsigned Level)
const {
289 return Stack.back().first[
Level].TaskgroupReductionRef &&
290 cast<DeclRefExpr>(Stack.back().first[
Level].TaskgroupReductionRef)
296 DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
298 DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent);
319 unsigned Level,
bool NotLastprivate =
false);
323 bool hasExplicitDirective(
335 return isStackEmpty() ?
OMPD_unknown : Stack.back().first.back().Directive;
339 assert(!isStackEmpty() &&
"No directive at specified level.");
340 return Stack.back().first[
Level].Directive;
344 if (isStackEmpty() || Stack.back().first.size() == 1)
346 return std::next(Stack.back().first.rbegin())->
Directive;
351 assert(!isStackEmpty());
352 Stack.back().first.back().DefaultAttr = DSA_none;
353 Stack.back().first.back().DefaultAttrLoc = Loc;
357 assert(!isStackEmpty());
358 Stack.back().first.back().DefaultAttr = DSA_shared;
359 Stack.back().first.back().DefaultAttrLoc = Loc;
363 assert(!isStackEmpty());
364 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
365 Stack.back().first.back().DefaultMapAttrLoc = Loc;
369 return isStackEmpty() ? DSA_unspecified
370 : Stack.back().first.back().DefaultAttr;
374 : Stack.back().first.back().DefaultAttrLoc;
377 return isStackEmpty() ? DMA_unspecified
378 : Stack.back().first.back().DefaultMapAttr;
381 return Stack.back().first[
Level].DefaultMapAttr;
385 : Stack.back().first.back().DefaultMapAttrLoc;
389 bool isThreadPrivate(
VarDecl *D) {
390 DSAVarData DVar = getTopDSA(D,
false);
395 void setOrderedRegion(
bool IsOrdered,
Expr *Param) {
396 assert(!isStackEmpty());
397 Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
398 Stack.back().first.back().OrderedRegion.setPointer(Param);
402 bool isParentOrderedRegion()
const {
403 if (isStackEmpty() || Stack.back().first.size() == 1)
405 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
408 Expr *getParentOrderedRegionParam()
const {
409 if (isStackEmpty() || Stack.back().first.size() == 1)
411 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
414 void setNowaitRegion(
bool IsNowait =
true) {
415 assert(!isStackEmpty());
416 Stack.back().first.back().NowaitRegion = IsNowait;
420 bool isParentNowaitRegion()
const {
421 if (isStackEmpty() || Stack.back().first.size() == 1)
423 return std::next(Stack.back().first.rbegin())->NowaitRegion;
426 void setParentCancelRegion(
bool Cancel =
true) {
427 if (!isStackEmpty() && Stack.back().first.size() > 1) {
428 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
429 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
433 bool isCancelRegion()
const {
434 return isStackEmpty() ?
false : Stack.back().first.back().CancelRegion;
438 void setAssociatedLoops(
unsigned Val) {
439 assert(!isStackEmpty());
440 Stack.back().first.back().AssociatedLoops = Val;
443 unsigned getAssociatedLoops()
const {
444 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
450 if (!isStackEmpty() && Stack.back().first.size() > 1) {
451 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
456 bool hasInnerTeamsRegion()
const {
457 return getInnerTeamsRegionLoc().
isValid();
462 : Stack.back().first.back().InnerTeamsRegionLoc;
465 Scope *getCurScope()
const {
466 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
468 Scope *getCurScope() {
469 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
473 : Stack.back().first.back().ConstructLoc;
478 bool checkMappableExprComponentListsForDecl(
480 const llvm::function_ref<
485 auto SI = Stack.back().first.rbegin();
486 auto SE = Stack.back().first.rend();
491 if (CurrentRegionOnly) {
497 for (; SI != SE; ++SI) {
498 auto MI = SI->MappedExprComponents.find(VD);
499 if (MI != SI->MappedExprComponents.end())
500 for (
auto &L : MI->second.Components)
501 if (Check(L, MI->second.Kind))
509 bool checkMappableExprComponentListsForDeclAtLevel(
511 const llvm::function_ref<
517 auto StartI = Stack.back().first.begin();
518 auto EndI = Stack.back().first.end();
521 std::advance(StartI, Level);
523 auto MI = StartI->MappedExprComponents.find(VD);
524 if (MI != StartI->MappedExprComponents.end())
525 for (
auto &L : MI->second.Components)
526 if (Check(L, MI->second.Kind))
533 void addMappableExpressionComponents(
537 assert(!isStackEmpty() &&
538 "Not expecting to retrieve components from a empty stack!");
539 auto &MEC = Stack.back().first.back().MappedExprComponents[VD];
541 MEC.Components.resize(MEC.Components.size() + 1);
542 MEC.Components.back().append(Components.begin(), Components.end());
543 MEC.Kind = WhereFoundClauseKind;
546 unsigned getNestingLevel()
const {
547 assert(!isStackEmpty());
548 return Stack.back().first.size() - 1;
550 void addDoacrossDependClause(
OMPDependClause *
C, OperatorOffsetTy &OpsOffs) {
551 assert(!isStackEmpty() && Stack.back().first.size() > 1);
552 auto &StackElem = *std::next(Stack.back().first.rbegin());
554 StackElem.DoacrossDepends.insert({
C, OpsOffs});
556 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
557 getDoacrossDependClauses()
const {
558 assert(!isStackEmpty());
559 auto &StackElem = Stack.back().first.back();
561 auto &Ref = StackElem.DoacrossDepends;
562 return llvm::make_range(Ref.begin(), Ref.end());
564 return llvm::make_range(StackElem.DoacrossDepends.end(),
565 StackElem.DoacrossDepends.end());
575 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
576 E = ExprTemp->getSubExpr();
578 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
579 E = MTE->GetTemporaryExpr();
581 while (
auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
582 E = Binder->getSubExpr();
584 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E))
585 E = ICE->getSubExprAsWritten();
590 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
592 D = ME->getMemberDecl();
593 auto *VD = dyn_cast<
VarDecl>(D);
600 FD = FD->getCanonicalDecl();
606 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
609 auto *VD = dyn_cast<
VarDecl>(D);
612 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
618 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
619 DVar.CKind = OMPC_shared;
625 if (VD && VD->hasGlobalStorage())
626 DVar.CKind = OMPC_shared;
630 DVar.CKind = OMPC_shared;
639 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
640 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
641 DVar.CKind = OMPC_private;
645 DVar.DKind = Iter->Directive;
648 if (Iter->SharingMap.count(D)) {
649 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
650 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
651 DVar.CKind = Iter->SharingMap[D].Attributes;
652 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
660 switch (Iter->DefaultAttr) {
662 DVar.CKind = OMPC_shared;
663 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
667 case DSA_unspecified:
672 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
675 DVar.CKind = OMPC_shared;
686 auto I = Iter, E = Stack.back().first.rend();
694 DVarTemp = getDSA(I, D);
695 if (DVarTemp.CKind != OMPC_shared) {
696 DVar.RefExpr =
nullptr;
697 DVar.CKind = OMPC_firstprivate;
700 }
while (I != E && !isParallelOrTaskRegion(I->Directive));
702 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
711 return getDSA(++Iter, D);
715 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
717 auto &StackElem = Stack.back().first.back();
718 auto It = StackElem.AlignedMap.find(D);
719 if (It == StackElem.AlignedMap.end()) {
720 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
721 StackElem.AlignedMap[D] = NewDE;
724 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
731 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
733 auto &StackElem = Stack.back().first.back();
734 StackElem.LCVMap.insert(
735 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
738 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(
ValueDecl *D) {
739 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
741 auto &StackElem = Stack.back().first.back();
742 auto It = StackElem.LCVMap.find(D);
743 if (It != StackElem.LCVMap.end())
748 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(
ValueDecl *D) {
749 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
750 "Data-sharing attributes stack is empty");
752 auto &StackElem = *std::next(Stack.back().first.rbegin());
753 auto It = StackElem.LCVMap.find(D);
754 if (It != StackElem.LCVMap.end())
759 ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I) {
760 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
761 "Data-sharing attributes stack is empty");
762 auto &StackElem = *std::next(Stack.back().first.rbegin());
763 if (StackElem.LCVMap.size() < I)
765 for (
auto &Pair : StackElem.LCVMap)
766 if (Pair.second.first == I)
775 auto &Data = Threadprivates[D];
777 Data.RefExpr.setPointer(E);
778 Data.PrivateCopy =
nullptr;
780 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
781 auto &Data = Stack.back().first.back().SharingMap[D];
782 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
783 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
784 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
785 (isLoopControlVariable(D).first && A == OMPC_private));
786 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
787 Data.RefExpr.setInt(
true);
790 const bool IsLastprivate =
791 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
793 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
794 Data.PrivateCopy = PrivateCopy;
796 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->
getDecl()];
798 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
799 Data.PrivateCopy =
nullptr;
806 StringRef Name,
const AttrVec *Attrs =
nullptr) {
823 bool RefersToCapture =
false) {
834 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
836 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
837 "Additional reduction info may be specified only for reduction items.");
838 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
839 assert(ReductionData.ReductionRange.isInvalid() &&
840 Stack.back().first.back().Directive == OMPD_taskgroup &&
841 "Additional reduction info may be specified only once for reduction " 843 ReductionData.set(BOK, SR);
844 Expr *&TaskgroupReductionRef =
845 Stack.back().first.back().TaskgroupReductionRef;
846 if (!TaskgroupReductionRef) {
848 SemaRef.Context.VoidPtrTy,
".task_red.");
849 TaskgroupReductionRef =
855 const Expr *ReductionRef) {
857 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
859 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
860 "Additional reduction info may be specified only for reduction items.");
861 auto &ReductionData = Stack.back().first.back().ReductionMap[D];
862 assert(ReductionData.ReductionRange.isInvalid() &&
863 Stack.back().first.back().Directive == OMPD_taskgroup &&
864 "Additional reduction info may be specified only once for reduction " 866 ReductionData.set(ReductionRef, SR);
867 Expr *&TaskgroupReductionRef =
868 Stack.back().first.back().TaskgroupReductionRef;
869 if (!TaskgroupReductionRef) {
872 TaskgroupReductionRef =
877 DSAStackTy::DSAVarData
880 Expr *&TaskgroupDescriptor) {
882 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
883 if (Stack.back().first.empty())
885 for (
auto I = std::next(Stack.back().first.rbegin(), 1),
886 E = Stack.back().first.rend();
887 I != E; std::advance(I, 1)) {
888 auto &Data = I->SharingMap[D];
889 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
891 auto &ReductionData = I->ReductionMap[D];
892 if (!ReductionData.ReductionOp ||
893 ReductionData.ReductionOp.is<
const Expr *>())
895 SR = ReductionData.ReductionRange;
896 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
897 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 898 "expression for the descriptor is not " 900 TaskgroupDescriptor = I->TaskgroupReductionRef;
901 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
902 Data.PrivateCopy, I->DefaultAttrLoc);
907 DSAStackTy::DSAVarData
909 const Expr *&ReductionRef,
910 Expr *&TaskgroupDescriptor) {
912 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
913 if (Stack.back().first.empty())
915 for (
auto I = std::next(Stack.back().first.rbegin(), 1),
916 E = Stack.back().first.rend();
917 I != E; std::advance(I, 1)) {
918 auto &Data = I->SharingMap[D];
919 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
921 auto &ReductionData = I->ReductionMap[D];
922 if (!ReductionData.ReductionOp ||
923 !ReductionData.ReductionOp.is<
const Expr *>())
925 SR = ReductionData.ReductionRange;
926 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
927 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 928 "expression for the descriptor is not " 930 TaskgroupDescriptor = I->TaskgroupReductionRef;
931 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
932 Data.PrivateCopy, I->DefaultAttrLoc);
937 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter) {
939 if (!isStackEmpty() && Stack.back().first.size() > 1) {
940 reverse_iterator I = Iter, E = Stack.back().first.rend();
941 Scope *TopScope =
nullptr;
942 while (I != E && !isParallelOrTaskRegion(I->Directive))
946 TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
947 Scope *CurScope = getCurScope();
948 while (CurScope != TopScope && !CurScope->
isDeclScope(D))
950 return CurScope != TopScope;
955 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
bool FromParent) {
962 auto *VD = dyn_cast<
VarDecl>(D);
964 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
965 SemaRef.getLangOpts().OpenMPUseTLS &&
966 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
968 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
973 auto TI = Threadprivates.find(D);
974 if (TI != Threadprivates.end()) {
975 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
978 }
else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
981 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
998 if (VD && VD->isStaticDataMember()) {
999 DSAVarData DVarTemp = hasDSA(D,
isOpenMPPrivate, MatchesAlways, FromParent);
1000 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1003 DVar.CKind = OMPC_shared;
1008 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
1009 Type = SemaRef.getASTContext().getBaseElementType(Type);
1016 if (
auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1017 if (
auto *CTD = CTSD->getSpecializedTemplate())
1018 RD = CTD->getTemplatedDecl();
1020 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->
hasDefinition() &&
1024 DSAVarData DVarTemp = hasDSA(
1026 MatchesAlways, FromParent);
1027 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1030 DVar.CKind = OMPC_shared;
1036 auto I = Stack.back().first.rbegin();
1037 auto EndI = Stack.back().first.rend();
1038 if (FromParent && I != EndI)
1040 if (I->SharingMap.count(D)) {
1041 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
1042 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
1043 DVar.CKind = I->SharingMap[D].Attributes;
1044 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1045 DVar.DKind = I->Directive;
1051 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1053 if (isStackEmpty()) {
1054 StackTy::reverse_iterator I;
1055 return getDSA(I, D);
1058 auto StartI = Stack.back().first.rbegin();
1059 auto EndI = Stack.back().first.rend();
1060 if (FromParent && StartI != EndI)
1061 std::advance(StartI, 1);
1062 return getDSA(StartI, D);
1065 DSAStackTy::DSAVarData
1073 auto I = Stack.back().first.rbegin();
1074 auto EndI = Stack.back().first.rend();
1075 if (FromParent && I != EndI)
1077 for (; I != EndI; std::advance(I, 1)) {
1078 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1081 DSAVarData DVar = getDSA(NewI, D);
1082 if (I == NewI && CPred(DVar.CKind))
1088 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1095 auto StartI = Stack.back().first.rbegin();
1096 auto EndI = Stack.back().first.rend();
1097 if (FromParent && StartI != EndI)
1098 std::advance(StartI, 1);
1099 if (StartI == EndI || !DPred(StartI->Directive))
1102 DSAVarData DVar = getDSA(NewI, D);
1103 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1106 bool DSAStackTy::hasExplicitDSA(
1108 unsigned Level,
bool NotLastprivate) {
1112 auto StartI = Stack.back().first.begin();
1113 auto EndI = Stack.back().first.end();
1116 std::advance(StartI, Level);
1117 return (StartI->SharingMap.count(D) > 0) &&
1118 StartI->SharingMap[D].RefExpr.getPointer() &&
1119 CPred(StartI->SharingMap[D].Attributes) &&
1120 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
1123 bool DSAStackTy::hasExplicitDirective(
1128 auto StartI = Stack.back().first.begin();
1129 auto EndI = Stack.back().first.end();
1132 std::advance(StartI, Level);
1133 return DPred(StartI->Directive);
1136 bool DSAStackTy::hasDirective(
1144 auto StartI = std::next(Stack.back().first.rbegin());
1145 auto EndI = Stack.back().first.rend();
1146 if (FromParent && StartI != EndI)
1147 StartI = std::next(StartI);
1148 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
1149 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1155 void Sema::InitDataSharingAttributesStack() {
1156 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1159 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1161 void Sema::pushOpenMPFunctionRegion() {
1170 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1172 auto &Ctx = getASTContext();
1173 bool IsByRef =
true;
1234 if (Ty->isReferenceType())
1240 bool IsVariableUsedInMapClause =
false;
1241 bool IsVariableAssociatedWithSection =
false;
1243 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1250 if (WhereFoundClauseKind != OMPC_map)
1253 auto EI = MapExprComponents.rbegin();
1254 auto EE = MapExprComponents.rend();
1256 assert(EI != EE &&
"Invalid map expression!");
1258 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1259 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1265 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1266 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1267 isa<MemberExpr>(EI->getAssociatedExpression())) {
1268 IsVariableAssociatedWithSection =
true;
1277 if (IsVariableUsedInMapClause) {
1280 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1285 !Ty->isScalarType() ||
1286 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1292 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1300 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
1301 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1309 (Ctx.getTypeSizeInChars(Ty) >
1310 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1311 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1318 unsigned Sema::getOpenMPNestingLevel()
const {
1319 assert(getLangOpts().OpenMP);
1320 return DSAStack->getNestingLevel();
1325 !
DSAStack->isClauseParsingMode()) ||
1329 return isOpenMPTargetExecutionDirective(K);
1335 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1345 auto *VD = dyn_cast<
VarDecl>(D);
1346 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1350 (!
DSAStack->isClauseParsingMode() ||
1352 auto &&Info =
DSAStack->isLoopControlVariable(D);
1354 (VD && VD->hasLocalStorage() &&
1355 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
1356 (VD &&
DSAStack->isForceVarCapturing()))
1357 return VD ? VD : Info.second;
1358 auto DVarPrivate =
DSAStack->getTopDSA(D,
DSAStack->isClauseParsingMode());
1360 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1365 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1370 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
1371 unsigned Level)
const {
1374 FunctionScopesIndex -= Regions.size();
1378 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1382 (
DSAStack->isClauseParsingMode() &&
1383 DSAStack->getClauseParsingMode() == OMPC_private) ||
1389 DSAStack->isTaskgroupReductionRef(D, Level));
1393 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1396 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
1397 const unsigned NewLevel = I - 1;
1400 if (isOpenMPPrivate(K)) {
1408 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1417 OMPC = OMPC_firstprivate;
1422 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1426 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1429 auto *VD = dyn_cast<
VarDecl>(D);
1435 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1440 DSAStack->push(DKind, DirName, CurScope, Loc);
1441 PushExpressionEvaluationContext(
1442 ExpressionEvaluationContext::PotentiallyEvaluated);
1459 if (
auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1460 for (
auto *
C : D->clauses()) {
1461 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
1463 for (
auto *DE : Clause->varlists()) {
1464 if (DE->isValueDependent() || DE->isTypeDependent()) {
1465 PrivateCopies.push_back(
nullptr);
1468 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1469 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1471 auto DVar =
DSAStack->getTopDSA(VD,
false);
1472 if (DVar.CKind == OMPC_lastprivate) {
1479 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
1480 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
1481 ActOnUninitializedDecl(VDPrivate);
1482 if (VDPrivate->isInvalidDecl())
1485 *
this, VDPrivate, DE->getType(), DE->getExprLoc()));
1489 PrivateCopies.push_back(
nullptr);
1493 if (PrivateCopies.size() == Clause->varlist_size())
1494 Clause->setPrivateCopies(PrivateCopies);
1500 DiscardCleanupsInEvaluationContext();
1501 PopExpressionEvaluationContext();
1505 Expr *NumIterations,
Sema &SemaRef,
1506 Scope *S, DSAStackTy *Stack);
1515 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1516 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1518 if (
auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1519 return VD->hasGlobalStorage() &&
1532 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1533 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1535 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1549 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
1557 Id, LookupOrdinaryName, CurScope,
nullptr,
1558 llvm::make_unique<VarDeclFilterCCC>(*
this), CTK_ErrorRecovery)) {
1559 diagnoseTypo(Corrected,
1560 PDiag(Lookup.
empty()
1561 ? diag::err_undeclared_var_use_suggest
1562 : diag::err_omp_expected_var_arg_suggest)
1564 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1567 : diag::err_omp_expected_var_arg)
1583 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1588 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1594 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1599 !getCurLexicalContext()->isTranslationUnit()) {
1605 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1620 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1629 (!getCurLexicalContext()->isFileContext() ||
1630 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
1636 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1644 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1650 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1675 CurContext->addDecl(D);
1682 class LocalVarRefChecker :
public ConstStmtVisitor<LocalVarRefChecker, bool> {
1687 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1688 if (VD->hasLocalStorage()) {
1690 diag::err_omp_local_var_in_threadprivate_init)
1692 SemaRef.
Diag(VD->getLocation(), diag::note_defined_here)
1693 << VD << VD->getSourceRange();
1699 bool VisitStmt(
const Stmt *S) {
1701 if (Child && Visit(Child))
1706 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
1713 for (
auto &RefExpr : VarList) {
1719 VD->setReferenced();
1720 VD->markUsed(Context);
1731 if (RequireCompleteType(ILoc, VD->getType(),
1732 diag::err_omp_threadprivate_incomplete_type)) {
1738 if (VD->getType()->isReferenceType()) {
1739 Diag(ILoc, diag::err_omp_ref_type_arg)
1743 Diag(VD->getLocation(),
1744 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1752 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1753 getLangOpts().OpenMPUseTLS &&
1754 getASTContext().getTargetInfo().isTLSSupported())) ||
1755 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1756 !VD->isLocalVarDecl())) {
1757 Diag(ILoc, diag::err_omp_var_thread_local)
1761 Diag(VD->getLocation(),
1762 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1769 if (
auto Init = VD->getAnyInitializer()) {
1770 LocalVarRefChecker Checker(*
this);
1771 if (Checker.Visit(Init))
1775 Vars.push_back(RefExpr);
1777 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1780 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1783 if (!Vars.empty()) {
1792 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1793 bool IsLoopIterVar =
false) {
1795 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1800 PDSA_StaticMemberShared,
1801 PDSA_StaticLocalVarShared,
1802 PDSA_LoopIterVarPrivate,
1803 PDSA_LoopIterVarLinear,
1804 PDSA_LoopIterVarLastprivate,
1805 PDSA_ConstVarShared,
1806 PDSA_GlobalVarShared,
1807 PDSA_TaskVarFirstprivate,
1808 PDSA_LocalVarPrivate,
1810 } Reason = PDSA_Implicit;
1811 bool ReportHint =
false;
1813 auto *VD = dyn_cast<
VarDecl>(D);
1814 if (IsLoopIterVar) {
1815 if (DVar.CKind == OMPC_private)
1816 Reason = PDSA_LoopIterVarPrivate;
1817 else if (DVar.CKind == OMPC_lastprivate)
1818 Reason = PDSA_LoopIterVarLastprivate;
1820 Reason = PDSA_LoopIterVarLinear;
1822 DVar.CKind == OMPC_firstprivate) {
1823 Reason = PDSA_TaskVarFirstprivate;
1824 ReportLoc = DVar.ImplicitDSALoc;
1825 }
else if (VD && VD->isStaticLocal())
1826 Reason = PDSA_StaticLocalVarShared;
1827 else if (VD && VD->isStaticDataMember())
1828 Reason = PDSA_StaticMemberShared;
1829 else if (VD && VD->isFileVarDecl())
1830 Reason = PDSA_GlobalVarShared;
1832 Reason = PDSA_ConstVarShared;
1833 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1835 Reason = PDSA_LocalVarPrivate;
1837 if (Reason != PDSA_Implicit) {
1838 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1839 << Reason << ReportHint
1841 }
else if (DVar.ImplicitDSALoc.isValid()) {
1842 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1848 class DSAAttrChecker :
public StmtVisitor<DSAAttrChecker, void> {
1855 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1863 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1864 VD = VD->getCanonicalDecl();
1869 auto DVar = Stack->getTopDSA(VD,
false);
1871 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1879 auto DKind = Stack->getCurrentDirective();
1884 if (DVar.CKind ==
OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1885 isParallelOrTaskRegion(DKind) &&
1886 VarsWithInheritedDSA.count(VD) == 0) {
1887 VarsWithInheritedDSA[VD] = E;
1892 !Stack->isLoopControlVariable(VD).first) {
1893 if (!Stack->checkMappableExprComponentListsForDecl(
1900 return StackComponents.size() == 1 ||
1902 std::next(StackComponents.rbegin()),
1903 StackComponents.rend(),
1904 [](const OMPClauseMappableExprCommon::
1905 MappableComponent &MC) {
1906 return MC.getAssociatedDeclaration() ==
1908 (isa<OMPArraySectionExpr>(
1909 MC.getAssociatedExpression()) ||
1910 isa<ArraySubscriptExpr>(
1911 MC.getAssociatedExpression()));
1914 bool IsFirstprivate =
false;
1916 if (
const auto *RD =
1917 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1918 IsFirstprivate = RD->isLambda();
1921 (VD->getType().getNonReferenceType()->isScalarType() &&
1922 Stack->getDefaultDMA() != DMA_tofrom_scalar);
1924 ImplicitFirstprivate.emplace_back(E);
1926 ImplicitMap.emplace_back(E);
1935 DVar = Stack->hasInnermostDSA(
1944 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
1950 DVar = Stack->getImplicitDSA(VD,
false);
1952 !Stack->isLoopControlVariable(VD).first)
1953 ImplicitFirstprivate.push_back(E);
1965 auto DVar = Stack->getTopDSA(FD,
false);
1968 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1972 !Stack->isLoopControlVariable(FD).first &&
1973 !Stack->checkMappableExprComponentListsForDecl(
1978 return isa<CXXThisExpr>(
1980 StackComponents.back().getAssociatedExpression())
1987 if (FD->isBitField())
1989 ImplicitMap.emplace_back(E);
1998 DVar = Stack->hasInnermostDSA(
2007 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2013 DVar = Stack->getImplicitDSA(FD,
false);
2015 !Stack->isLoopControlVariable(FD).first)
2016 ImplicitFirstprivate.push_back(E);
2024 auto *VD = cast<ValueDecl>(
2025 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2026 if (!Stack->checkMappableExprComponentListsForDecl(
2032 auto CCI = CurComponents.rbegin();
2033 auto CCE = CurComponents.rend();
2034 for (const auto &SC : llvm::reverse(StackComponents)) {
2036 if (CCI->getAssociatedExpression()->getStmtClass() !=
2037 SC.getAssociatedExpression()->getStmtClass())
2038 if (!(isa<OMPArraySectionExpr>(
2039 SC.getAssociatedExpression()) &&
2040 isa<ArraySubscriptExpr>(
2041 CCI->getAssociatedExpression())))
2044 Decl *CCD = CCI->getAssociatedDeclaration();
2045 Decl *SCD = SC.getAssociatedDeclaration();
2046 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2047 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2050 std::advance(CCI, 1);
2067 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
2069 for (
auto *CC :
C->children()) {
2076 void VisitStmt(
Stmt *S) {
2078 if (
C && !isa<OMPExecutableDirective>(
C))
2083 bool isErrorFound() {
return ErrorFound; }
2085 return ImplicitFirstprivate;
2088 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2089 return VarsWithInheritedDSA;
2093 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
2100 case OMPD_parallel_for:
2101 case OMPD_parallel_for_simd:
2102 case OMPD_parallel_sections:
2104 case OMPD_teams_distribute:
2105 case OMPD_teams_distribute_simd: {
2110 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2111 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2112 std::make_pair(StringRef(),
QualType())
2118 case OMPD_target_teams:
2119 case OMPD_target_parallel:
2120 case OMPD_target_parallel_for:
2121 case OMPD_target_parallel_for_simd:
2122 case OMPD_target_teams_distribute:
2123 case OMPD_target_teams_distribute_simd: {
2125 std::make_pair(StringRef(),
QualType())
2134 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2135 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2136 std::make_pair(StringRef(),
QualType())
2141 ParamsTeamsOrParallel);
2152 case OMPD_taskgroup:
2153 case OMPD_distribute:
2154 case OMPD_distribute_simd:
2157 case OMPD_target_data:
2159 case OMPD_target_simd: {
2161 std::make_pair(StringRef(),
QualType())
2174 std::make_pair(
".global_tid.", KmpInt32Ty),
2177 std::make_pair(
".copy_fn.",
2180 std::make_pair(StringRef(),
QualType())
2186 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2187 AlwaysInlineAttr::CreateImplicit(
2188 Context, AlwaysInlineAttr::Keyword_forceinline,
SourceRange()));
2192 case OMPD_taskloop_simd: {
2204 std::make_pair(
".global_tid.", KmpInt32Ty),
2206 std::make_pair(
".privates.",
2212 std::make_pair(
".lb.", KmpUInt64Ty),
2213 std::make_pair(
".ub.", KmpUInt64Ty), std::make_pair(
".st.", KmpInt64Ty),
2214 std::make_pair(
".liter.", KmpInt32Ty),
2215 std::make_pair(
".reductions.",
2217 std::make_pair(StringRef(),
QualType())
2223 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2224 AlwaysInlineAttr::CreateImplicit(
2225 Context, AlwaysInlineAttr::Keyword_forceinline,
SourceRange()));
2228 case OMPD_distribute_parallel_for_simd:
2229 case OMPD_distribute_parallel_for:
2230 case OMPD_target_teams_distribute_parallel_for:
2231 case OMPD_target_teams_distribute_parallel_for_simd: {
2236 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2237 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2238 std::make_pair(
".previous.lb.", Context.
getSizeType()),
2239 std::make_pair(
".previous.ub.", Context.
getSizeType()),
2240 std::make_pair(StringRef(),
QualType())
2246 case OMPD_teams_distribute_parallel_for:
2247 case OMPD_teams_distribute_parallel_for_simd: {
2253 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2254 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2255 std::make_pair(StringRef(),
QualType())
2262 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2263 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2264 std::make_pair(
".previous.lb.", Context.
getSizeType()),
2265 std::make_pair(
".previous.ub.", Context.
getSizeType()),
2266 std::make_pair(StringRef(),
QualType())
2274 case OMPD_target_update:
2275 case OMPD_target_enter_data:
2276 case OMPD_target_exit_data: {
2283 std::make_pair(
".global_tid.", KmpInt32Ty),
2286 std::make_pair(
".copy_fn.",
2289 std::make_pair(StringRef(),
QualType())
2295 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2296 AlwaysInlineAttr::CreateImplicit(
2297 Context, AlwaysInlineAttr::Keyword_forceinline,
SourceRange()));
2300 case OMPD_threadprivate:
2301 case OMPD_taskyield:
2304 case OMPD_cancellation_point:
2307 case OMPD_declare_reduction:
2308 case OMPD_declare_simd:
2309 case OMPD_declare_target:
2310 case OMPD_end_declare_target:
2311 llvm_unreachable(
"OpenMP Directive is not allowed");
2313 llvm_unreachable(
"Unknown OpenMP directive");
2320 return CaptureRegions.size();
2324 Expr *CaptureExpr,
bool WithInit,
2325 bool AsExpression) {
2326 assert(CaptureExpr);
2356 CD = cast<OMPCapturedExprDecl>(VD);
2379 if (!Res.isUsable())
2394 class CaptureRegionUnwinderRAII {
2401 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
2403 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2404 ~CaptureRegionUnwinderRAII() {
2407 while (--ThisCaptureLevel >= 0)
2416 bool ErrorFound =
false;
2417 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2418 *
this, ErrorFound,
DSAStack->getCurrentDirective());
2431 for (
auto *Clause : Clauses) {
2436 auto *IRC = cast<OMPInReductionClause>(Clause);
2437 for (
auto *E : IRC->taskgroup_descriptors())
2439 MarkDeclarationsReferencedInExpr(E);
2443 (getLangOpts().OpenMPUseTLS &&
2444 getASTContext().getTargetInfo().isTLSSupported() &&
2448 for (
auto *VarRef : Clause->
children()) {
2449 if (
auto *E = cast_or_null<Expr>(VarRef)) {
2450 MarkDeclarationsReferencedInExpr(E);
2453 DSAStack->setForceVarCapturing(
false);
2454 }
else if (CaptureRegions.size() > 1 ||
2459 if (
auto *E =
C->getPostUpdateExpr())
2460 MarkDeclarationsReferencedInExpr(E);
2464 SC = cast<OMPScheduleClause>(Clause);
2466 OC = cast<OMPOrderedClause>(Clause);
2468 LCs.push_back(cast<OMPLinearClause>(Clause));
2476 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2481 diag::err_omp_schedule_nonmonotonic_ordered)
2482 <<
SourceRange(OC->getLocStart(), OC->getLocEnd());
2485 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2486 for (
auto *
C : LCs) {
2487 Diag(
C->getLocStart(), diag::err_omp_linear_ordered)
2488 <<
SourceRange(OC->getLocStart(), OC->getLocEnd());
2494 OC->getNumForLoops()) {
2495 Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2508 for (
auto *
C : PICs) {
2515 if (CaptureRegion == ThisCaptureRegion ||
2517 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
2518 for (
auto *D : DS->decls())
2519 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
2524 SR = ActOnCapturedRegionEnd(SR.
get());
2533 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2536 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2537 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2540 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2550 if (Stack->getCurScope()) {
2551 auto ParentRegion = Stack->getParentDirective();
2552 auto OffendingRegion = ParentRegion;
2553 bool NestingProhibited =
false;
2554 bool CloseNesting =
true;
2555 bool OrphanSeen =
false;
2558 ShouldBeInParallelRegion,
2559 ShouldBeInOrderedRegion,
2560 ShouldBeInTargetRegion,
2561 ShouldBeInTeamsRegion
2562 } Recommend = NoRecommend;
2572 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
2573 ? diag::err_omp_prohibited_region_simd
2574 : diag::warn_omp_nesting_simd);
2575 return CurrentRegion != OMPD_simd;
2577 if (ParentRegion == OMPD_atomic) {
2580 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2583 if (CurrentRegion == OMPD_section) {
2588 if (ParentRegion != OMPD_sections &&
2589 ParentRegion != OMPD_parallel_sections) {
2590 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2603 if (CurrentRegion == OMPD_cancellation_point ||
2604 CurrentRegion == OMPD_cancel) {
2617 !((CancelRegion == OMPD_parallel &&
2618 (ParentRegion == OMPD_parallel ||
2619 ParentRegion == OMPD_target_parallel)) ||
2620 (CancelRegion == OMPD_for &&
2621 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2622 ParentRegion == OMPD_target_parallel_for ||
2623 ParentRegion == OMPD_distribute_parallel_for ||
2624 ParentRegion == OMPD_teams_distribute_parallel_for ||
2625 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2626 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2627 (CancelRegion == OMPD_sections &&
2628 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2629 ParentRegion == OMPD_parallel_sections)));
2630 }
else if (CurrentRegion == OMPD_master) {
2636 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
2642 bool DeadLock = Stack->hasDirective(
2646 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
2647 PreviousCriticalLoc = Loc;
2654 SemaRef.
Diag(StartLoc,
2655 diag::err_omp_prohibited_region_critical_same_name)
2657 if (PreviousCriticalLoc.
isValid())
2658 SemaRef.
Diag(PreviousCriticalLoc,
2659 diag::note_omp_previous_critical_region);
2662 }
else if (CurrentRegion == OMPD_barrier) {
2668 ParentRegion == OMPD_master ||
2669 ParentRegion == OMPD_critical ||
2670 ParentRegion == OMPD_ordered;
2679 ParentRegion == OMPD_master ||
2680 ParentRegion == OMPD_critical ||
2681 ParentRegion == OMPD_ordered;
2682 Recommend = ShouldBeInParallelRegion;
2683 }
else if (CurrentRegion == OMPD_ordered) {
2692 NestingProhibited = ParentRegion == OMPD_critical ||
2695 Stack->isParentOrderedRegion());
2696 Recommend = ShouldBeInOrderedRegion;
2701 NestingProhibited = ParentRegion != OMPD_target;
2703 Recommend = ShouldBeInTargetRegion;
2705 if (!NestingProhibited &&
2708 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2715 Recommend = ShouldBeInParallelRegion;
2717 if (!NestingProhibited &&
2723 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2724 Recommend = ShouldBeInTeamsRegion;
2726 if (!NestingProhibited &&
2733 NestingProhibited = Stack->hasDirective(
2737 OffendingRegion = K;
2743 CloseNesting =
false;
2745 if (NestingProhibited) {
2747 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2750 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
2763 bool ErrorFound =
false;
2764 unsigned NamedModifiersNumber = 0;
2768 for (
const auto *
C : Clauses) {
2769 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
2773 if (FoundNameModifiers[CurNM]) {
2774 S.
Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
2779 NameModifierLoc.push_back(IC->getNameModifierLoc());
2780 ++NamedModifiersNumber;
2782 FoundNameModifiers[CurNM] = IC;
2789 bool MatchFound =
false;
2790 for (
auto NM : AllowedNameModifiers) {
2797 S.
Diag(IC->getNameModifierLoc(),
2798 diag::err_omp_wrong_if_directive_name_modifier)
2806 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
2807 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2809 diag::err_omp_no_more_if_clause);
2812 std::string Sep(
", ");
2813 unsigned AllowedCnt = 0;
2814 unsigned TotalAllowedNum =
2815 AllowedNameModifiers.size() - NamedModifiersNumber;
2816 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
2819 if (!FoundNameModifiers[NM]) {
2823 if (AllowedCnt + 2 == TotalAllowedNum)
2825 else if (AllowedCnt + 1 != TotalAllowedNum)
2831 diag::err_omp_unnamed_if_clause)
2832 << (TotalAllowedNum > 1) << Values;
2834 for (
auto Loc : NameModifierLoc) {
2835 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
2854 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2855 bool ErrorFound =
false;
2856 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2857 if (AStmt && !CurContext->isDependentContext()) {
2858 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
2861 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
2862 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2864 while (--ThisCaptureLevel >= 0)
2865 S = cast<CapturedStmt>(S)->getCapturedStmt();
2866 DSAChecker.Visit(S);
2867 if (DSAChecker.isErrorFound())
2870 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2873 DSAChecker.getImplicitFirstprivate().begin(),
2874 DSAChecker.getImplicitFirstprivate().end());
2876 DSAChecker.getImplicitMap().end());
2878 for (
auto *
C : Clauses) {
2879 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
2880 for (
auto *E : IRC->taskgroup_descriptors())
2882 ImplicitFirstprivates.emplace_back(E);
2885 if (!ImplicitFirstprivates.empty()) {
2886 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2889 ClausesWithImplicit.push_back(Implicit);
2890 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2891 ImplicitFirstprivates.size();
2895 if (!ImplicitMaps.empty()) {
2896 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
2900 ClausesWithImplicit.emplace_back(Implicit);
2902 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2911 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2913 AllowedNameModifiers.push_back(OMPD_parallel);
2916 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2917 VarsWithInheritedDSA);
2920 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2921 VarsWithInheritedDSA);
2924 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2925 EndLoc, VarsWithInheritedDSA);
2928 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2932 assert(ClausesWithImplicit.empty() &&
2933 "No clauses are allowed for 'omp section' directive");
2934 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2937 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2941 assert(ClausesWithImplicit.empty() &&
2942 "No clauses are allowed for 'omp master' directive");
2943 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2946 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2949 case OMPD_parallel_for:
2950 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2951 EndLoc, VarsWithInheritedDSA);
2952 AllowedNameModifiers.push_back(OMPD_parallel);
2954 case OMPD_parallel_for_simd:
2955 Res = ActOnOpenMPParallelForSimdDirective(
2956 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2957 AllowedNameModifiers.push_back(OMPD_parallel);
2959 case OMPD_parallel_sections:
2960 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2962 AllowedNameModifiers.push_back(OMPD_parallel);
2966 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2967 AllowedNameModifiers.push_back(OMPD_task);
2969 case OMPD_taskyield:
2970 assert(ClausesWithImplicit.empty() &&
2971 "No clauses are allowed for 'omp taskyield' directive");
2972 assert(AStmt ==
nullptr &&
2973 "No associated statement allowed for 'omp taskyield' directive");
2974 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2977 assert(ClausesWithImplicit.empty() &&
2978 "No clauses are allowed for 'omp barrier' directive");
2979 assert(AStmt ==
nullptr &&
2980 "No associated statement allowed for 'omp barrier' directive");
2981 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2984 assert(ClausesWithImplicit.empty() &&
2985 "No clauses are allowed for 'omp taskwait' directive");
2986 assert(AStmt ==
nullptr &&
2987 "No associated statement allowed for 'omp taskwait' directive");
2988 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2990 case OMPD_taskgroup:
2991 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2995 assert(AStmt ==
nullptr &&
2996 "No associated statement allowed for 'omp flush' directive");
2997 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3000 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3004 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3009 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3012 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3014 AllowedNameModifiers.push_back(OMPD_target);
3016 case OMPD_target_parallel:
3017 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3019 AllowedNameModifiers.push_back(OMPD_target);
3020 AllowedNameModifiers.push_back(OMPD_parallel);
3022 case OMPD_target_parallel_for:
3023 Res = ActOnOpenMPTargetParallelForDirective(
3024 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3025 AllowedNameModifiers.push_back(OMPD_target);
3026 AllowedNameModifiers.push_back(OMPD_parallel);
3028 case OMPD_cancellation_point:
3029 assert(ClausesWithImplicit.empty() &&
3030 "No clauses are allowed for 'omp cancellation point' directive");
3031 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp " 3032 "cancellation point' directive");
3033 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3036 assert(AStmt ==
nullptr &&
3037 "No associated statement allowed for 'omp cancel' directive");
3038 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3040 AllowedNameModifiers.push_back(OMPD_cancel);
3042 case OMPD_target_data:
3043 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3045 AllowedNameModifiers.push_back(OMPD_target_data);
3047 case OMPD_target_enter_data:
3048 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3050 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3052 case OMPD_target_exit_data:
3053 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3055 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3058 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3059 EndLoc, VarsWithInheritedDSA);
3060 AllowedNameModifiers.push_back(OMPD_taskloop);
3062 case OMPD_taskloop_simd:
3063 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3064 EndLoc, VarsWithInheritedDSA);
3065 AllowedNameModifiers.push_back(OMPD_taskloop);
3067 case OMPD_distribute:
3068 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3069 EndLoc, VarsWithInheritedDSA);
3071 case OMPD_target_update:
3072 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3074 AllowedNameModifiers.push_back(OMPD_target_update);
3076 case OMPD_distribute_parallel_for:
3077 Res = ActOnOpenMPDistributeParallelForDirective(
3078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3079 AllowedNameModifiers.push_back(OMPD_parallel);
3081 case OMPD_distribute_parallel_for_simd:
3082 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084 AllowedNameModifiers.push_back(OMPD_parallel);
3086 case OMPD_distribute_simd:
3087 Res = ActOnOpenMPDistributeSimdDirective(
3088 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3090 case OMPD_target_parallel_for_simd:
3091 Res = ActOnOpenMPTargetParallelForSimdDirective(
3092 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3093 AllowedNameModifiers.push_back(OMPD_target);
3094 AllowedNameModifiers.push_back(OMPD_parallel);
3096 case OMPD_target_simd:
3097 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3098 EndLoc, VarsWithInheritedDSA);
3099 AllowedNameModifiers.push_back(OMPD_target);
3101 case OMPD_teams_distribute:
3102 Res = ActOnOpenMPTeamsDistributeDirective(
3103 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3105 case OMPD_teams_distribute_simd:
3106 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3107 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3109 case OMPD_teams_distribute_parallel_for_simd:
3110 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3112 AllowedNameModifiers.push_back(OMPD_parallel);
3114 case OMPD_teams_distribute_parallel_for:
3115 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3116 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3117 AllowedNameModifiers.push_back(OMPD_parallel);
3119 case OMPD_target_teams:
3120 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3122 AllowedNameModifiers.push_back(OMPD_target);
3124 case OMPD_target_teams_distribute:
3125 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3126 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3127 AllowedNameModifiers.push_back(OMPD_target);
3129 case OMPD_target_teams_distribute_parallel_for:
3130 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3131 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3132 AllowedNameModifiers.push_back(OMPD_target);
3133 AllowedNameModifiers.push_back(OMPD_parallel);
3135 case OMPD_target_teams_distribute_parallel_for_simd:
3136 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3137 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3138 AllowedNameModifiers.push_back(OMPD_target);
3139 AllowedNameModifiers.push_back(OMPD_parallel);
3141 case OMPD_target_teams_distribute_simd:
3142 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3143 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3144 AllowedNameModifiers.push_back(OMPD_target);
3146 case OMPD_declare_target:
3147 case OMPD_end_declare_target:
3148 case OMPD_threadprivate:
3149 case OMPD_declare_reduction:
3150 case OMPD_declare_simd:
3151 llvm_unreachable(
"OpenMP Directive is not allowed");
3153 llvm_unreachable(
"Unknown OpenMP directive");
3156 for (
auto P : VarsWithInheritedDSA) {
3157 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3158 <<
P.first <<
P.second->getSourceRange();
3160 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3162 if (!AllowedNameModifiers.empty())
3163 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
3176 assert(Aligneds.size() == Alignments.size());
3177 assert(Linears.size() == LinModifiers.size());
3178 assert(Linears.size() == Steps.size());
3179 if (!DG || DG.
get().isNull())
3182 if (!DG.
get().isSingleDecl()) {
3183 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
3186 auto *ADecl = DG.
get().getSingleDecl();
3187 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3188 ADecl = FTD->getTemplatedDecl();
3192 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3201 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3208 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3209 Expr *UniformedLinearThis =
nullptr;
3210 for (
auto *E : Uniforms) {
3212 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3213 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3214 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3215 FD->getParamDecl(PVD->getFunctionScopeIndex())
3217 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3220 if (isa<CXXThisExpr>(E)) {
3221 UniformedLinearThis = E;
3225 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3235 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3236 Expr *AlignedThis =
nullptr;
3237 for (
auto *E : Aligneds) {
3239 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3240 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3241 auto *CanonPVD = PVD->getCanonicalDecl();
3242 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3243 FD->getParamDecl(PVD->getFunctionScopeIndex())
3247 if (AlignedArgs.count(CanonPVD) > 0) {
3250 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3251 diag::note_omp_explicit_dsa)
3255 AlignedArgs[CanonPVD] = E;
3257 .getNonReferenceType()
3258 .getUnqualifiedType()
3259 .getCanonicalType();
3262 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3264 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3269 if (isa<CXXThisExpr>(E)) {
3280 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3287 for (
auto *E : Alignments) {
3290 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3291 NewAligns.push_back(Align.
get());
3302 llvm::DenseMap<Decl *, Expr *> LinearArgs;
3303 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
3304 auto MI = LinModifiers.begin();
3305 for (
auto *E : Linears) {
3309 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
3310 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3311 auto *CanonPVD = PVD->getCanonicalDecl();
3312 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3313 FD->getParamDecl(PVD->getFunctionScopeIndex())
3317 if (LinearArgs.count(CanonPVD) > 0) {
3321 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3322 diag::note_omp_explicit_dsa)
3327 if (UniformedArgs.count(CanonPVD) > 0) {
3331 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3332 diag::note_omp_explicit_dsa)
3336 LinearArgs[CanonPVD] = E;
3341 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
3342 PVD->getOriginalType());
3346 if (isa<CXXThisExpr>(E)) {
3347 if (UniformedLinearThis) {
3352 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
3357 UniformedLinearThis = E;
3361 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
3366 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3369 Expr *NewStep =
nullptr;
3371 for (
auto *E : Steps) {
3373 if (Step == E || !E) {
3374 NewSteps.push_back(E ? NewStep :
nullptr);
3378 if (
auto *DRE = dyn_cast<DeclRefExpr>(Step))
3379 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3380 auto *CanonPVD = PVD->getCanonicalDecl();
3381 if (UniformedArgs.count(CanonPVD) == 0) {
3387 CanonPVD->getType()->hasIntegerRepresentation())
3388 NewSteps.push_back(Step);
3399 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(),
Step)
3402 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3404 NewSteps.push_back(NewStep);
3406 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3407 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
3408 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
3409 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
3410 const_cast<Expr **
>(Linears.data()), Linears.size(),
3411 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
3412 NewSteps.data(), NewSteps.size(), SR);
3413 ADecl->addAttr(NewAttr);
3414 return ConvertDeclToDeclGroup(ADecl);
3432 getCurFunction()->setHasBranchProtectedScope();
3442 class OpenMPIterationSpaceChecker {
3458 Expr *LCRef =
nullptr;
3470 bool TestIsLessOp =
false;
3472 bool TestIsStrictOp =
false;
3474 bool SubtractStep =
false;
3478 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3481 bool CheckInit(
Stmt *S,
bool EmitDiags =
true);
3484 bool CheckCond(
Expr *S);
3487 bool CheckInc(
Expr *S);
3489 ValueDecl *GetLoopDecl()
const {
return LCDecl; }
3491 Expr *GetLoopDeclRefExpr()
const {
return LCRef; }
3493 SourceRange GetInitSrcRange()
const {
return InitSrcRange; }
3495 SourceRange GetConditionSrcRange()
const {
return ConditionSrcRange; }
3497 SourceRange GetIncrementSrcRange()
const {
return IncrementSrcRange; }
3499 bool ShouldSubtractStep()
const {
return SubtractStep; }
3502 BuildNumIterations(
Scope *S,
const bool LimitedType,
3503 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3506 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3508 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3509 DSAStackTy &DSA)
const;
3512 Expr *BuildPrivateCounterVar()
const;
3516 Expr *BuildCounterStep()
const;
3518 bool Dependent()
const;
3523 bool CheckIncRHS(
Expr *RHS);
3530 bool SetStep(
Expr *NewStep,
bool Subtract);
3533 bool OpenMPIterationSpaceChecker::Dependent()
const {
3535 assert(!LB && !UB && !
Step);
3538 return LCDecl->getType()->isDependentType() ||
3539 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3540 (
Step &&
Step->isValueDependent());
3543 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(
ValueDecl *NewLCDecl,
3547 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
3548 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3549 if (!NewLCDecl || !NewLB)
3552 LCRef = NewLCRefExpr;
3553 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3555 if ((Ctor->isCopyOrMoveConstructor() ||
3556 Ctor->isConvertingConstructor(
false)) &&
3557 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3563 bool OpenMPIterationSpaceChecker::SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
3566 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
3567 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3571 TestIsLessOp = LessOp;
3572 TestIsStrictOp = StrictOp;
3573 ConditionSrcRange = SR;
3578 bool OpenMPIterationSpaceChecker::SetStep(
Expr *NewStep,
bool Subtract) {
3580 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
3590 NewStep = Val.
get();
3607 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3609 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3610 bool IsConstZero = IsConstant && !Result.getBoolValue();
3611 if (UB && (IsConstZero ||
3612 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3613 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3615 diag::err_omp_loop_incr_not_compatible)
3617 SemaRef.
Diag(ConditionLoc,
3618 diag::note_omp_loop_cond_requres_compatible_incr)
3619 << TestIsLessOp << ConditionSrcRange;
3622 if (TestIsLessOp == Subtract) {
3626 Subtract = !Subtract;
3631 SubtractStep = Subtract;
3635 bool OpenMPIterationSpaceChecker::CheckInit(
Stmt *S,
bool EmitDiags) {
3646 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3650 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3651 if (!ExprTemp->cleanupsHaveSideEffects())
3652 S = ExprTemp->getSubExpr();
3655 if (
Expr *E = dyn_cast<Expr>(S))
3657 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3658 if (BO->getOpcode() == BO_Assign) {
3660 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3661 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3663 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3664 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3666 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3667 if (ME->isArrow() &&
3668 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3669 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3672 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
3673 if (DS->isSingleDecl()) {
3674 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3675 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3679 diag::ext_omp_loop_not_canonical_init)
3681 return SetLCDeclAndLB(Var,
nullptr, Var->getInit());
3685 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3686 if (CE->getOperator() == OO_Equal) {
3687 auto *LHS = CE->getArg(0);
3688 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3689 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3691 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3692 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3694 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3695 if (ME->isArrow() &&
3696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3697 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3717 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3719 if ((Ctor->isCopyOrMoveConstructor() ||
3720 Ctor->isConvertingConstructor(
false)) &&
3721 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3723 if (
auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3724 if (
auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3727 if (
auto *ME = dyn_cast_or_null<MemberExpr>(E))
3728 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3733 bool OpenMPIterationSpaceChecker::CheckCond(
Expr *S) {
3741 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3746 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3747 if (BO->isRelationalOp()) {
3748 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3749 return SetUB(BO->getRHS(),
3750 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3751 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3752 BO->getSourceRange(), BO->getOperatorLoc());
3753 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3754 return SetUB(BO->getLHS(),
3755 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3756 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3757 BO->getSourceRange(), BO->getOperatorLoc());
3759 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3760 if (CE->getNumArgs() == 2) {
3761 auto Op = CE->getOperator();
3764 case OO_GreaterEqual:
3767 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3768 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3769 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3770 CE->getOperatorLoc());
3771 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3772 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3773 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3774 CE->getOperatorLoc());
3783 SemaRef.
Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3788 bool OpenMPIterationSpaceChecker::CheckIncRHS(
Expr *RHS) {
3795 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3796 if (BO->isAdditiveOp()) {
3797 bool IsAdd = BO->getOpcode() == BO_Add;
3798 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3799 return SetStep(BO->getRHS(), !IsAdd);
3800 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3801 return SetStep(BO->getLHS(),
false);
3803 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3804 bool IsAdd = CE->getOperator() == OO_Plus;
3805 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3806 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3807 return SetStep(CE->getArg(1), !IsAdd);
3808 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3809 return SetStep(CE->getArg(0),
false);
3814 SemaRef.
Diag(RHS->
getLocStart(), diag::err_omp_loop_not_canonical_incr)
3819 bool OpenMPIterationSpaceChecker::CheckInc(
Expr *S) {
3834 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3837 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3838 if (!ExprTemp->cleanupsHaveSideEffects())
3839 S = ExprTemp->getSubExpr();
3843 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
3844 if (UO->isIncrementDecrementOp() &&
3845 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3846 return SetStep(SemaRef
3847 .ActOnIntegerConstant(UO->getLocStart(),
3848 (UO->isDecrementOp() ? -1 : 1))
3851 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3852 switch (BO->getOpcode()) {
3855 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3856 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3859 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3860 return CheckIncRHS(BO->getRHS());
3865 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3866 switch (CE->getOperator()) {
3869 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3870 return SetStep(SemaRef
3871 .ActOnIntegerConstant(
3873 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3879 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3880 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3883 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3884 return CheckIncRHS(CE->getArg(1));
3898 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
3899 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3906 auto I = Captures.find(Capture);
3907 if (I != Captures.end())
3911 Captures[Capture] = Ref;
3916 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3917 Scope *S,
const bool LimitedType,
3918 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
3920 auto VarType = LCDecl->getType().getNonReferenceType();
3921 if (VarType->isIntegerType() || VarType->isPointerType() ||
3924 auto *UBExpr = TestIsLessOp ? UB : LB;
3925 auto *LBExpr = TestIsLessOp ? LB : UB;
3926 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3927 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3928 if (!Upper || !Lower)
3931 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3933 if (!Diff.
isUsable() && VarType->getAsCXXRecordDecl()) {
3948 S, DefaultLoc, BO_Sub, Diff.
get(),
3954 auto NewStep = tryBuildCapture(SemaRef,
Step, Captures);
3955 if (!NewStep.isUsable())
3957 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.get());
3967 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.get());
3974 bool UseVarType = VarType->hasIntegerRepresentation() &&
3975 C.getTypeSize(Type) >
C.getTypeSize(VarType);
3978 UseVarType ?
C.getTypeSize(VarType) :
C.getTypeSize(Type);
3979 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3981 Type =
C.getIntTypeForBitwidth(NewSize, IsSigned);
3990 unsigned NewSize = (
C.getTypeSize(Type) > 32) ? 64 : 32;
3991 if (NewSize !=
C.getTypeSize(Type)) {
3992 if (NewSize <
C.getTypeSize(Type)) {
3993 assert(NewSize == 64 &&
"incorrect loop var size");
3994 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3995 << InitSrcRange << ConditionSrcRange;
3997 QualType NewType =
C.getIntTypeForBitwidth(
3999 C.getTypeSize(Type) < NewSize);
4012 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4014 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
4019 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4020 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4021 if (!NewLB.isUsable() || !NewUB.isUsable())
4025 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4026 : (TestIsStrictOp ? BO_GT : BO_GE),
4027 NewLB.get(), NewUB.get());
4028 if (CondExpr.isUsable()) {
4037 return CondExpr.isUsable() ? CondExpr.get() : Cond;
4041 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4042 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA)
const {
4043 auto *VD = dyn_cast<
VarDecl>(LCDecl);
4047 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4048 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl,
false);
4052 Captures.insert(std::make_pair(LCRef, Ref));
4059 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar()
const {
4060 if (LCDecl && !LCDecl->isInvalidDecl()) {
4061 auto Type = LCDecl->getType().getNonReferenceType();
4064 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr);
4065 if (PrivateVar->isInvalidDecl())
4076 Expr *OpenMPIterationSpaceChecker::BuildCounterStep()
const {
return Step; }
4079 struct LoopIterationSpace final {
4081 Expr *PreCond =
nullptr;
4084 Expr *NumIterations =
nullptr;
4086 Expr *CounterVar =
nullptr;
4088 Expr *PrivateCounterVar =
nullptr;
4090 Expr *CounterInit =
nullptr;
4093 Expr *CounterStep =
nullptr;
4095 bool Subtract =
false;
4107 assert(getLangOpts().OpenMP &&
"OpenMP is not active.");
4108 assert(Init &&
"Expected loop in canonical form.");
4109 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
4110 if (AssociatedLoops > 0 &&
4112 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
4113 if (!ISC.CheckInit(Init,
false)) {
4114 if (
auto *D = ISC.GetLoopDecl()) {
4115 auto *VD = dyn_cast<
VarDecl>(D);
4117 if (
auto *Private = IsOpenMPCapturedDecl(D))
4120 auto *Ref =
buildCapture(*
this, D, ISC.GetLoopDeclRefExpr(),
4122 VD = cast<VarDecl>(Ref->getDecl());
4125 DSAStack->addLoopControlVariable(D, VD);
4128 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4136 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
4137 Expr *CollapseLoopCountExpr,
Expr *OrderedLoopCountExpr,
4138 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4139 LoopIterationSpace &ResultIterSpace,
4140 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4143 auto *For = dyn_cast_or_null<ForStmt>(S);
4146 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
4148 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4149 if (NestedLoopCount > 1) {
4150 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4151 SemaRef.
Diag(DSA.getConstructLoc(),
4152 diag::note_omp_collapse_ordered_expr)
4155 else if (CollapseLoopCountExpr)
4157 diag::note_omp_collapse_ordered_expr)
4161 diag::note_omp_collapse_ordered_expr)
4166 assert(For->getBody());
4168 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4171 auto Init = For->getInit();
4172 if (ISC.CheckInit(Init))
4175 bool HasErrors =
false;
4178 if (
auto *LCDecl = ISC.GetLoopDecl()) {
4179 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4186 auto VarType = LCDecl->getType().getNonReferenceType();
4187 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4188 !VarType->isPointerType() &&
4189 !(SemaRef.
getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4190 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4204 VarsWithImplicitDSA.erase(LCDecl);
4214 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl,
false);
4217 auto PredeterminedCKind =
4219 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4222 DVar.CKind != PredeterminedCKind) ||
4226 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4227 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
4228 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4231 if (DVar.RefExpr ==
nullptr)
4232 DVar.CKind = PredeterminedCKind;
4235 }
else if (LoopDeclRefExpr !=
nullptr) {
4244 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4250 HasErrors |= ISC.CheckCond(For->getCond());
4253 HasErrors |= ISC.CheckInc(For->getInc());
4260 ResultIterSpace.PreCond =
4261 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4262 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4267 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4268 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4269 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4270 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4271 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4272 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4273 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4274 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4276 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
4277 ResultIterSpace.NumIterations ==
nullptr ||
4278 ResultIterSpace.CounterVar ==
nullptr ||
4279 ResultIterSpace.PrivateCounterVar ==
nullptr ||
4280 ResultIterSpace.CounterInit ==
nullptr ||
4281 ResultIterSpace.CounterStep ==
nullptr);
4290 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4292 auto NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
4293 if (!NewStart.isUsable())
4296 VarRef.
get()->getType())) {
4300 if (!NewStart.isUsable())
4305 SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), NewStart.get());
4314 llvm::MapVector<Expr *, DeclRefExpr *> *Captures =
nullptr) {
4323 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
4335 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
4342 if (VarRef.
get()->getType()->isOverloadableType() ||
4343 NewStart.
get()->getType()->isOverloadableType() ||
4344 Update.
get()->getType()->isOverloadableType()) {
4351 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4352 VarRef.
get(), SavedUpdate.
get());
4363 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4364 NewStart.
get(), SavedUpdate.
get());
4369 VarRef.
get()->getType())) {
4376 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
4388 unsigned HasBits =
C.getTypeSize(OldType);
4389 if (HasBits >= Bits)
4392 QualType NewType =
C.getIntTypeForBitwidth(Bits,
true);
4404 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4411 if (!PreInits.empty()) {
4422 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4423 if (!Captures.empty()) {
4425 for (
auto &Pair : Captures)
4426 PreInits.push_back(Pair.second->getDecl());
4434 Expr *PostUpdate =
nullptr;
4435 if (!PostUpdates.empty()) {
4436 for (
auto *E : PostUpdates) {
4442 PostUpdate = PostUpdate
4457 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
4459 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4461 unsigned NestedLoopCount = 1;
4462 if (CollapseLoopCountExpr) {
4466 NestedLoopCount = Result.getLimitedValue();
4468 if (OrderedLoopCountExpr) {
4472 if (Result.getLimitedValue() < NestedLoopCount) {
4474 diag::err_omp_wrong_ordered_loop_count)
4477 diag::note_collapse_loop_count)
4480 NestedLoopCount = Result.getLimitedValue();
4485 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4487 IterSpaces.resize(NestedLoopCount);
4489 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4491 NestedLoopCount, CollapseLoopCountExpr,
4492 OrderedLoopCountExpr, VarsWithImplicitDSA,
4493 IterSpaces[Cnt], Captures))
4503 Built.
clear( NestedLoopCount);
4506 return NestedLoopCount;
4539 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
4540 auto N0 = IterSpaces[0].NumIterations;
4543 .PerformImplicitConversion(
4544 N0->IgnoreImpCasts(), N0->getType(),
4550 .PerformImplicitConversion(
4551 N0->IgnoreImpCasts(), N0->getType(),
4556 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
4557 return NestedLoopCount;
4560 bool AllCountsNeedLessThan32Bits =
C.getTypeSize(N0->getType()) < 32;
4562 Scope *CurScope = DSA.getCurScope();
4563 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4564 if (PreCond.isUsable()) {
4566 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4567 PreCond.get(), IterSpaces[Cnt].PreCond);
4569 auto N = IterSpaces[Cnt].NumIterations;
4571 AllCountsNeedLessThan32Bits &=
C.getTypeSize(N->getType()) < 32;
4574 CurScope, Loc, BO_Mul, LastIteration32.
get(),
4580 if (LastIteration64.isUsable())
4582 CurScope, Loc, BO_Mul, LastIteration64.get(),
4593 C.getTypeSize(LastIteration32.
get()->getType()) == 32 &&
4594 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4597 LastIteration32.
get()->getType()->hasSignedIntegerRepresentation(),
4598 LastIteration64.get(), SemaRef)))
4599 LastIteration = LastIteration32;
4617 CurScope, LastIteration.
get()->getExprLoc(), BO_Sub,
4618 LastIteration.
get(),
4628 LastIteration.
get()->isIntegerConstantExpr(Result, SemaRef.
Context);
4632 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
4633 LastIteration = SaveRef;
4637 CurScope, SaveRef.
get()->getExprLoc(), BO_Add, SaveRef.
get(),
4646 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4673 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
4682 UB.
get(), LastIteration.
get());
4684 InitLoc, InitLoc, IsUBGreater.
get(), LastIteration.
get(), UB.
get());
4685 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
4711 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
4714 LastIteration.
get(), CombUB.
get());
4715 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
4719 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4722 assert(CD->getNumParams() >= 4 &&
4723 "Unexpected number of parameters in loop combined directive");
4727 auto *PrevLBDecl = CD->getParam(2);
4728 auto *PrevUBDecl = CD->getParam(3);
4750 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4761 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4771 ? SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get())
4772 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4773 NumIterations.
get());
4777 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.
get());
4782 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4786 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
4795 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4824 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
4835 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
4850 DistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get());
4851 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
4854 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
4855 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
4856 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4859 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
4867 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
4868 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
4874 bool HasErrors =
false;
4875 Built.
Counters.resize(NestedLoopCount);
4876 Built.
Inits.resize(NestedLoopCount);
4877 Built.
Updates.resize(NestedLoopCount);
4878 Built.
Finals.resize(NestedLoopCount);
4883 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4884 LoopIterationSpace &IS = IterSpaces[Cnt];
4891 SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.
get());
4894 assert((Cnt == (
int)NestedLoopCount - 1) &&
4895 "unusable div expected on first iteration only");
4899 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.
get(),
4907 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4909 IS.CounterVar->getExprLoc(),
4912 IS.CounterInit, Captures);
4913 if (!Init.isUsable()) {
4918 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4919 IS.CounterStep, IS.Subtract, &Captures);
4927 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4928 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4937 Div = IS.NumIterations;
4939 Div = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.
get(),
4944 Div = tryBuildCapture(SemaRef, Div.
get(), Captures);
4949 LoopMultipliers.push_back(Div.
get());
4956 Built.
Counters[Cnt] = IS.CounterVar;
4958 Built.
Inits[Cnt] = Init.get();
4973 Built.
PreCond = PreCond.get();
4978 Built.
LB = LB.
get();
4979 Built.
UB = UB.
get();
4980 Built.
IL = IL.
get();
4981 Built.
ST = ST.
get();
4983 Built.
NLB = NextLB.
get();
4984 Built.
NUB = NextUB.
get();
4999 for (
auto Pair : DSA.getDoacrossDependClauses()) {
5000 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5001 Pair.first->setCounterValue(CounterVal);
5003 if (NestedLoopCount != Pair.second.size() ||
5004 NestedLoopCount != LoopMultipliers.size() + 1) {
5006 Pair.first->setCounterValue(CounterVal);
5009 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5010 auto I = Pair.second.rbegin();
5011 auto IS = IterSpaces.rbegin();
5012 auto ILM = LoopMultipliers.rbegin();
5013 Expr *UpCounterVal = CounterVal;
5014 Expr *Multiplier =
nullptr;
5015 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5017 assert(IS->CounterStep);
5018 Expr *NormalizedOffset =
5020 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5021 I->first, IS->CounterStep)
5026 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5027 NormalizedOffset, Multiplier)
5030 assert(I->second == OO_Plus || I->second == OO_Minus);
5032 UpCounterVal = SemaRef
5033 .
BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5034 UpCounterVal, NormalizedOffset)
5042 Pair.first->setCounterValue(UpCounterVal);
5046 return NestedLoopCount;
5050 auto CollapseClauses =
5051 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5052 if (CollapseClauses.begin() != CollapseClauses.end())
5053 return (*CollapseClauses.begin())->getNumForLoops();
5058 auto OrderedClauses =
5059 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5060 if (OrderedClauses.begin() != OrderedClauses.end())
5061 return (*OrderedClauses.begin())->getNumForLoops();
5070 for (
auto *Clause : Clauses) {
5072 Safelen = cast<OMPSafelenClause>(Clause);
5074 Simdlen = cast<OMPSimdlenClause>(Clause);
5075 if (Safelen && Simdlen)
5079 if (Simdlen && Safelen) {
5080 llvm::APSInt SimdlenRes, SafelenRes;
5083 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5084 SimdlenLength->isInstantiationDependent() ||
5085 SimdlenLength->containsUnexpandedParameterPack())
5087 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5088 SafelenLength->isInstantiationDependent() ||
5089 SafelenLength->containsUnexpandedParameterPack())
5092 SafelenLength->EvaluateAsInt(SafelenRes, S.
Context);
5097 if (SimdlenRes > SafelenRes) {
5098 S.
Diag(SimdlenLength->getExprLoc(),
5099 diag::err_omp_wrong_simdlen_safelen_values)
5100 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5110 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5114 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5120 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5121 if (NestedLoopCount == 0)
5124 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5125 "omp simd loop exprs were not built");
5127 if (!CurContext->isDependentContext()) {
5129 for (
auto C : Clauses) {
5130 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5141 getCurFunction()->setHasBranchProtectedScope();
5149 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5153 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5159 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5160 if (NestedLoopCount == 0)
5163 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5164 "omp for loop exprs were not built");
5166 if (!CurContext->isDependentContext()) {
5168 for (
auto C : Clauses) {
5169 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5177 getCurFunction()->setHasBranchProtectedScope();
5179 Clauses, AStmt, B,
DSAStack->isCancelRegion());
5185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5189 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5193 unsigned NestedLoopCount =
5196 VarsWithImplicitDSA, B);
5197 if (NestedLoopCount == 0)
5200 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5201 "omp for simd loop exprs were not built");
5203 if (!CurContext->isDependentContext()) {
5205 for (
auto C : Clauses) {
5206 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5217 getCurFunction()->setHasBranchProtectedScope();
5229 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5230 auto BaseStmt = AStmt;
5231 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5233 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5234 auto S =
C->children();
5235 if (S.begin() == S.end())
5239 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5240 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5242 Diag(SectionStmt->getLocStart(),
5243 diag::err_omp_sections_substmt_not_section);
5246 cast<OMPSectionDirective>(SectionStmt)
5247 ->setHasCancel(
DSAStack->isCancelRegion());
5254 getCurFunction()->setHasBranchProtectedScope();
5266 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5268 getCurFunction()->setHasBranchProtectedScope();
5282 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5284 getCurFunction()->setHasBranchProtectedScope();
5290 for (
auto *Clause : Clauses) {
5294 Copyprivate = Clause;
5295 if (Copyprivate && Nowait) {
5297 diag::err_omp_single_copyprivate_with_nowait);
5312 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5314 getCurFunction()->setHasBranchProtectedScope();
5325 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5327 bool ErrorFound =
false;
5330 bool DependentHint =
false;
5331 for (
auto *
C : Clauses) {
5332 if (
C->getClauseKind() == OMPC_hint) {
5334 Diag(
C->getLocStart(), diag::err_omp_hint_clause_no_name);
5337 Expr *E = cast<OMPHintClause>(
C)->getHint();
5340 DependentHint =
true;
5343 HintLoc =
C->getLocStart();
5349 auto Pair =
DSAStack->getCriticalWithHint(DirName);
5350 if (Pair.first && DirName.
getName() && !DependentHint) {
5351 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5352 Diag(StartLoc, diag::err_omp_critical_with_hint);
5354 Diag(HintLoc, diag::note_omp_critical_hint_here)
5355 << 0 << Hint.toString(10,
false);
5357 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5359 Diag(
C->getLocStart(), diag::note_omp_critical_hint_here)
5361 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
5364 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5368 getCurFunction()->setHasBranchProtectedScope();
5372 if (!Pair.first && DirName.
getName() && !DependentHint)
5373 DSAStack->addCriticalWithHint(Dir, Hint);
5380 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5395 unsigned NestedLoopCount =
5398 VarsWithImplicitDSA, B);
5399 if (NestedLoopCount == 0)
5402 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5403 "omp parallel for loop exprs were not built");
5405 if (!CurContext->isDependentContext()) {
5407 for (
auto C : Clauses) {
5408 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5416 getCurFunction()->setHasBranchProtectedScope();
5418 NestedLoopCount, Clauses, AStmt, B,
5425 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5440 unsigned NestedLoopCount =
5443 VarsWithImplicitDSA, B);
5444 if (NestedLoopCount == 0)
5447 if (!CurContext->isDependentContext()) {
5449 for (
auto C : Clauses) {
5450 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5461 getCurFunction()->setHasBranchProtectedScope();
5463 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5473 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5474 auto BaseStmt = AStmt;
5475 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5477 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5478 auto S =
C->children();
5479 if (S.begin() == S.end())
5483 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5484 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5486 Diag(SectionStmt->getLocStart(),
5487 diag::err_omp_parallel_sections_substmt_not_section);
5490 cast<OMPSectionDirective>(SectionStmt)
5491 ->setHasCancel(
DSAStack->isCancelRegion());
5495 diag::err_omp_parallel_sections_not_compound_stmt);
5499 getCurFunction()->setHasBranchProtectedScope();
5502 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
5511 auto *CS = cast<CapturedStmt>(AStmt);
5519 getCurFunction()->setHasBranchProtectedScope();
5547 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5549 getCurFunction()->setHasBranchProtectedScope();
5553 DSAStack->getTaskgroupReductionRef());
5559 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
5568 OMPClause *DependSourceClause =
nullptr;
5570 bool ErrorFound =
false;
5573 for (
auto *
C : Clauses) {
5574 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
5576 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5577 if (DependSourceClause) {
5578 Diag(
C->getLocStart(), diag::err_omp_more_one_clause)
5583 DependSourceClause =
C;
5584 if (DependSinkClause) {
5585 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5589 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5590 if (DependSourceClause) {
5591 Diag(
C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5595 DependSinkClause =
C;
5597 }
else if (
C->getClauseKind() == OMPC_threads)
5598 TC = cast<OMPThreadsClause>(
C);
5599 else if (
C->getClauseKind() == OMPC_simd)
5600 SC = cast<OMPSIMDClause>(
C);
5602 if (!ErrorFound && !SC &&
5607 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5609 }
else if (DependFound && (TC || SC)) {
5610 Diag(DependFound->
getLocStart(), diag::err_omp_depend_clause_thread_simd)
5613 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam()) {
5615 diag::err_omp_ordered_directive_without_param);
5617 }
else if (TC || Clauses.empty()) {
5618 if (
auto *Param =
DSAStack->getParentOrderedRegionParam()) {
5620 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5622 Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5626 if ((!AStmt && !DependFound) || ErrorFound)
5630 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5632 getCurFunction()->setHasBranchProtectedScope();
5641 class OpenMPAtomicUpdateChecker {
5643 enum ExprAnalysisErrorCode {
5647 NotABinaryOrUnaryExpression,
5649 NotAnUnaryIncDecExpression,
5655 NotABinaryExpression,
5661 NotAnUpdateExpression,
5679 bool IsXLHSInRHSPart;
5684 bool IsPostfixUpdate;
5687 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
5688 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
5689 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
5697 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
5699 Expr *getX()
const {
return X; }
5701 Expr *getExpr()
const {
return E; }
5705 Expr *getUpdateExpr()
const {
return UpdateExpr; }
5708 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
5712 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
5715 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
5716 unsigned NoteId = 0);
5720 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5722 ExprAnalysisErrorCode ErrorFound = NoError;
5728 if (AtomicBinOp->
getOpcode() == BO_Assign) {
5730 if (
auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5732 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5733 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5734 AtomicInnerBinOp->isBitwiseOp()) {
5735 Op = AtomicInnerBinOp->getOpcode();
5736 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5737 auto *LHS = AtomicInnerBinOp->getLHS();
5738 auto *RHS = AtomicInnerBinOp->getRHS();
5739 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5742 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.
getASTContext(),
5744 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.
getASTContext(),
5748 IsXLHSInRHSPart =
true;
5749 }
else if (XId == RHSId) {
5751 IsXLHSInRHSPart =
false;
5753 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5754 ErrorRange = AtomicInnerBinOp->getSourceRange();
5755 NoteLoc =
X->getExprLoc();
5756 NoteRange =
X->getSourceRange();
5757 ErrorFound = NotAnUpdateExpression;
5760 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5761 ErrorRange = AtomicInnerBinOp->getSourceRange();
5762 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5764 ErrorFound = NotABinaryOperator;
5769 ErrorFound = NotABinaryExpression;
5776 ErrorFound = NotAnAssignmentOp;
5778 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5779 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
5780 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5783 E =
X = UpdateExpr =
nullptr;
5784 return ErrorFound != NoError;
5787 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
5789 ExprAnalysisErrorCode ErrorFound = NoError;
5800 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
5801 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5802 if (AtomicBody->getType()->isScalarType() ||
5803 AtomicBody->isInstantiationDependent()) {
5804 if (
auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5805 AtomicBody->IgnoreParenImpCasts())) {
5808 AtomicCompAssignOp->getOpcode());
5809 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5810 E = AtomicCompAssignOp->getRHS();
5811 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5812 IsXLHSInRHSPart =
true;
5813 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5814 AtomicBody->IgnoreParenImpCasts())) {
5816 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5818 }
else if (
auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5819 AtomicBody->IgnoreParenImpCasts())) {
5821 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5822 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5823 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5824 OpLoc = AtomicUnaryOp->getOperatorLoc();
5825 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5827 IsXLHSInRHSPart =
true;
5829 ErrorFound = NotAnUnaryIncDecExpression;
5830 ErrorLoc = AtomicUnaryOp->getExprLoc();
5831 ErrorRange = AtomicUnaryOp->getSourceRange();
5832 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5835 }
else if (!AtomicBody->isInstantiationDependent()) {
5836 ErrorFound = NotABinaryOrUnaryExpression;
5837 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5838 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5841 ErrorFound = NotAScalarType;
5842 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5843 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5846 ErrorFound = NotAnExpression;
5848 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5850 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5851 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
5852 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5855 E =
X = UpdateExpr =
nullptr;
5856 if (ErrorFound == NoError && E &&
X) {
5866 IsXLHSInRHSPart ? OVEExpr : OVEX);
5873 UpdateExpr =
Update.get();
5875 return ErrorFound != NoError;
5885 auto *CS = cast<CapturedStmt>(AStmt);
5893 for (
auto *
C : Clauses) {
5894 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
5895 C->getClauseKind() == OMPC_update ||
5896 C->getClauseKind() == OMPC_capture) {
5898 Diag(
C->getLocStart(), diag::err_omp_atomic_several_clauses)
5900 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5903 AtomicKind =
C->getClauseKind();
5904 AtomicKindLoc =
C->getLocStart();
5910 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5911 Body = EWC->getSubExpr();
5917 bool IsXLHSInRHSPart =
false;
5918 bool IsPostfixUpdate =
false;
5941 if (AtomicKind == OMPC_read) {
5948 } ErrorFound = NoError;
5953 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
5956 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
5962 auto NotLValueExpr = X->
isLValue() ? V :
X;
5963 ErrorFound = NotAnLValue;
5966 NoteLoc = NotLValueExpr->getExprLoc();
5967 NoteRange = NotLValueExpr->getSourceRange();
5971 auto NotScalarExpr =
5975 ErrorFound = NotAScalarType;
5978 NoteLoc = NotScalarExpr->getExprLoc();
5979 NoteRange = NotScalarExpr->getSourceRange();
5981 }
else if (!AtomicBody->isInstantiationDependent()) {
5982 ErrorFound = NotAnAssignmentOp;
5983 ErrorLoc = AtomicBody->getExprLoc();
5984 ErrorRange = AtomicBody->getSourceRange();
5986 : AtomicBody->getExprLoc();
5988 : AtomicBody->getSourceRange();
5991 ErrorFound = NotAnExpression;
5992 NoteLoc = ErrorLoc = Body->getLocStart();
5993 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5995 if (ErrorFound != NoError) {
5996 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5998 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6001 }
else if (CurContext->isDependentContext())
6003 }
else if (AtomicKind == OMPC_write) {
6010 } ErrorFound = NoError;
6015 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
6018 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6019 X = AtomicBinOp->
getLHS();
6020 E = AtomicBinOp->
getRHS();
6024 ErrorFound = NotAnLValue;
6032 auto NotScalarExpr =
6036 ErrorFound = NotAScalarType;
6039 NoteLoc = NotScalarExpr->getExprLoc();
6040 NoteRange = NotScalarExpr->getSourceRange();
6042 }
else if (!AtomicBody->isInstantiationDependent()) {
6043 ErrorFound = NotAnAssignmentOp;
6044 ErrorLoc = AtomicBody->getExprLoc();
6045 ErrorRange = AtomicBody->getSourceRange();
6047 : AtomicBody->getExprLoc();
6049 : AtomicBody->getSourceRange();
6052 ErrorFound = NotAnExpression;
6053 NoteLoc = ErrorLoc = Body->getLocStart();
6054 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6056 if (ErrorFound != NoError) {
6057 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6059 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6062 }
else if (CurContext->isDependentContext())
6064 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
6073 OpenMPAtomicUpdateChecker Checker(*
this);
6074 if (Checker.checkStatement(
6075 Body, (AtomicKind == OMPC_update)
6076 ? diag::err_omp_atomic_update_not_expression_statement
6077 : diag::err_omp_atomic_not_expression_statement,
6078 diag::note_omp_atomic_update))
6080 if (!CurContext->isDependentContext()) {
6081 E = Checker.getExpr();
6083 UE = Checker.getUpdateExpr();
6084 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6086 }
else if (AtomicKind == OMPC_capture) {
6089 NotACompoundStatement,
6090 NotTwoSubstatements,
6091 NotASpecificExpression,
6093 } ErrorFound = NoError;
6096 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
6107 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6108 V = AtomicBinOp->
getLHS();
6110 OpenMPAtomicUpdateChecker Checker(*
this);
6111 if (Checker.checkStatement(
6112 Body, diag::err_omp_atomic_capture_not_expression_statement,
6113 diag::note_omp_atomic_update))
6115 E = Checker.getExpr();
6117 UE = Checker.getUpdateExpr();
6118 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6119 IsPostfixUpdate = Checker.isPostfixUpdate();
6120 }
else if (!AtomicBody->isInstantiationDependent()) {
6121 ErrorLoc = AtomicBody->getExprLoc();
6122 ErrorRange = AtomicBody->getSourceRange();
6124 : AtomicBody->getExprLoc();
6126 : AtomicBody->getSourceRange();
6127 ErrorFound = NotAnAssignmentOp;
6129 if (ErrorFound != NoError) {
6130 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6132 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6134 }
else if (CurContext->isDependentContext()) {
6135 UE = V = E = X =
nullptr;
6154 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
6156 if (CS->size() == 2) {
6157 auto *First = CS->body_front();
6158 auto *Second = CS->body_back();
6159 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
6160 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6161 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6162 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6164 OpenMPAtomicUpdateChecker Checker(*
this);
6165 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6167 if (IsUpdateExprFound) {
6169 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6171 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6181 llvm::FoldingSetNodeID XId, PossibleXId;
6182 Checker.getX()->Profile(XId, Context,
true);
6183 PossibleX->Profile(PossibleXId, Context,
true);
6184 IsUpdateExprFound = XId == PossibleXId;
6185 if (IsUpdateExprFound) {
6188 E = Checker.getExpr();
6189 UE = Checker.getUpdateExpr();
6190 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6191 IsPostfixUpdate =
true;
6194 if (!IsUpdateExprFound) {
6195 IsUpdateExprFound = !Checker.checkStatement(First);
6197 if (IsUpdateExprFound) {
6199 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6201 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6211 llvm::FoldingSetNodeID XId, PossibleXId;
6212 Checker.getX()->Profile(XId, Context,
true);
6213 PossibleX->Profile(PossibleXId, Context,
true);
6214 IsUpdateExprFound = XId == PossibleXId;
6215 if (IsUpdateExprFound) {
6218 E = Checker.getExpr();
6219 UE = Checker.getUpdateExpr();
6220 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6221 IsPostfixUpdate =
false;
6225 if (!IsUpdateExprFound) {
6227 auto *FirstExpr = dyn_cast<
Expr>(First);
6228 auto *SecondExpr = dyn_cast<
Expr>(Second);
6229 if (!FirstExpr || !SecondExpr ||
6230 !(FirstExpr->isInstantiationDependent() ||
6231 SecondExpr->isInstantiationDependent())) {
6233 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6234 ErrorFound = NotAnAssignmentOp;
6235 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6236 : First->getLocStart();
6237 NoteRange = ErrorRange = FirstBinOp
6238 ? FirstBinOp->getSourceRange()
6242 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6243 ErrorFound = NotAnAssignmentOp;
6244 NoteLoc = ErrorLoc = SecondBinOp
6245 ? SecondBinOp->getOperatorLoc()
6246 : Second->getLocStart();
6247 NoteRange = ErrorRange =
6248 SecondBinOp ? SecondBinOp->getSourceRange()
6251 auto *PossibleXRHSInFirst =
6252 FirstBinOp->getRHS()->IgnoreParenImpCasts();
6253 auto *PossibleXLHSInSecond =
6254 SecondBinOp->getLHS()->IgnoreParenImpCasts();
6255 llvm::FoldingSetNodeID X1Id, X2Id;
6256 PossibleXRHSInFirst->Profile(X1Id, Context,
6258 PossibleXLHSInSecond->Profile(X2Id, Context,
6260 IsUpdateExprFound = X1Id == X2Id;
6261 if (IsUpdateExprFound) {
6262 V = FirstBinOp->getLHS();
6263 X = SecondBinOp->getLHS();
6264 E = SecondBinOp->getRHS();
6266 IsXLHSInRHSPart =
false;
6267 IsPostfixUpdate =
true;
6269 ErrorFound = NotASpecificExpression;
6270 ErrorLoc = FirstBinOp->getExprLoc();
6271 ErrorRange = FirstBinOp->getSourceRange();
6272 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6273 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6280 NoteLoc = ErrorLoc = Body->getLocStart();
6281 NoteRange = ErrorRange =
6282 SourceRange(Body->getLocStart(), Body->getLocStart());
6283 ErrorFound = NotTwoSubstatements;
6286 NoteLoc = ErrorLoc = Body->getLocStart();
6287 NoteRange = ErrorRange =
6288 SourceRange(Body->getLocStart(), Body->getLocStart());
6289 ErrorFound = NotACompoundStatement;
6291 if (ErrorFound != NoError) {
6292 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6294 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6296 }
else if (CurContext->isDependentContext()) {
6297 UE = V = E = X =
nullptr;
6302 getCurFunction()->setHasBranchProtectedScope();
6305 X, V, E, UE, IsXLHSInRHSPart,
6328 if (
DSAStack->hasInnerTeamsRegion()) {
6330 bool OMPTeamsFound =
true;
6331 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
6332 auto I = CS->body_begin();
6333 while (I != CS->body_end()) {
6336 OMPTeamsFound =
false;
6341 assert(I != CS->body_end() &&
"Not found statement");
6347 if (!OMPTeamsFound) {
6348 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6350 diag::note_omp_nested_teams_construct_here);
6352 << isa<OMPExecutableDirective>(S);
6357 getCurFunction()->setHasBranchProtectedScope();
6377 getCurFunction()->setHasBranchProtectedScope();
6386 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6397 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6398 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6411 unsigned NestedLoopCount =
6414 VarsWithImplicitDSA, B);
6415 if (NestedLoopCount == 0)
6418 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6419 "omp target parallel for loop exprs were not built");
6421 if (!CurContext->isDependentContext()) {
6423 for (
auto C : Clauses) {
6424 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6432 getCurFunction()->setHasBranchProtectedScope();
6434 NestedLoopCount, Clauses, AStmt,
6441 return llvm::any_of(
6445 template <
typename... Params>
6447 const Params... ClauseTypes) {
6458 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6462 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6463 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6464 <<
"'map' or 'use_device_ptr'" 6469 getCurFunction()->setHasBranchProtectedScope();
6489 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6490 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6503 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6526 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6527 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6540 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6563 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6564 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6574 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
6575 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6596 getCurFunction()->setHasBranchProtectedScope();
6598 DSAStack->setParentTeamsRegionLoc(StartLoc);
6607 if (
DSAStack->isParentNowaitRegion()) {
6608 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6611 if (
DSAStack->isParentOrderedRegion()) {
6612 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6623 if (
DSAStack->isParentNowaitRegion()) {
6624 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6627 if (
DSAStack->isParentOrderedRegion()) {
6628 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6631 DSAStack->setParentCancelRegion(
true);
6639 bool ErrorFound =
false;
6640 for (
auto *
C : Clauses) {
6641 if (
C->getClauseKind() == OMPC_grainsize ||
6642 C->getClauseKind() == OMPC_num_tasks) {
6646 S.
Diag(
C->getLocStart(),
6647 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6651 diag::note_omp_previous_grainsize_num_tasks)
6664 for (
auto *
C : Clauses) {
6665 if (
C->getClauseKind() == OMPC_reduction) {
6666 ReductionClause =
C;
6671 if (
C->getClauseKind() == OMPC_nogroup) {
6673 if (ReductionClause)
6678 if (ReductionClause && NogroupClause) {
6679 S.
Diag(ReductionClause->
getLocStart(), diag::err_omp_reduction_with_nogroup)
6690 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6694 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6698 unsigned NestedLoopCount =
6701 VarsWithImplicitDSA, B);
6702 if (NestedLoopCount == 0)
6705 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6706 "omp for loop exprs were not built");
6719 getCurFunction()->setHasBranchProtectedScope();
6721 NestedLoopCount, Clauses, AStmt, B);
6727 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6731 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6735 unsigned NestedLoopCount =
6738 VarsWithImplicitDSA, B);
6739 if (NestedLoopCount == 0)
6742 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6743 "omp for loop exprs were not built");
6745 if (!CurContext->isDependentContext()) {
6747 for (
auto C : Clauses) {
6748 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6769 getCurFunction()->setHasBranchProtectedScope();
6771 NestedLoopCount, Clauses, AStmt, B);
6777 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6781 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6785 unsigned NestedLoopCount =
6788 *
this, *
DSAStack, VarsWithImplicitDSA, B);
6789 if (NestedLoopCount == 0)
6792 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6793 "omp for loop exprs were not built");
6795 getCurFunction()->setHasBranchProtectedScope();
6797 NestedLoopCount, Clauses, AStmt, B);
6803 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6814 for (
int ThisCaptureLevel =
6815 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6816 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6832 VarsWithImplicitDSA, B);
6833 if (NestedLoopCount == 0)
6836 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6837 "omp for loop exprs were not built");
6839 getCurFunction()->setHasBranchProtectedScope();
6841 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6848 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6859 for (
int ThisCaptureLevel =
6860 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6861 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6877 VarsWithImplicitDSA, B);
6878 if (NestedLoopCount == 0)
6881 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6882 "omp for loop exprs were not built");
6884 if (!CurContext->isDependentContext()) {
6886 for (
auto C : Clauses) {
6887 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6898 getCurFunction()->setHasBranchProtectedScope();
6900 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6906 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6917 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
6918 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6931 unsigned NestedLoopCount =
6933 nullptr , CS, *
this,
6934 *
DSAStack, VarsWithImplicitDSA, B);
6935 if (NestedLoopCount == 0)
6938 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6939 "omp for loop exprs were not built");
6941 if (!CurContext->isDependentContext()) {
6943 for (
auto C : Clauses) {
6944 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6955 getCurFunction()->setHasBranchProtectedScope();
6957 NestedLoopCount, Clauses, AStmt, B);
6963 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6974 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6975 ThisCaptureLevel > 1; --ThisCaptureLevel) {
6991 VarsWithImplicitDSA, B);
6992 if (NestedLoopCount == 0)
6995 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6996 "omp target parallel for simd loop exprs were not built");
6998 if (!CurContext->isDependentContext()) {
7000 for (
auto C : Clauses) {
7001 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7011 getCurFunction()->setHasBranchProtectedScope();
7013 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7019 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7030 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7031 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7044 unsigned NestedLoopCount =
7047 VarsWithImplicitDSA, B);
7048 if (NestedLoopCount == 0)
7051 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7052 "omp target simd loop exprs were not built");
7054 if (!CurContext->isDependentContext()) {
7056 for (
auto C : Clauses) {
7057 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7068 getCurFunction()->setHasBranchProtectedScope();
7070 NestedLoopCount, Clauses, AStmt, B);
7076 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7087 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7088 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7101 unsigned NestedLoopCount =
7103 nullptr , CS, *
this,
7104 *
DSAStack, VarsWithImplicitDSA, B);
7105 if (NestedLoopCount == 0)
7108 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7109 "omp teams distribute loop exprs were not built");
7111 getCurFunction()->setHasBranchProtectedScope();
7113 DSAStack->setParentTeamsRegionLoc(StartLoc);
7116 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7122 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7133 for (
int ThisCaptureLevel =
7134 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7135 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7152 VarsWithImplicitDSA, B);
7154 if (NestedLoopCount == 0)
7157 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7158 "omp teams distribute simd loop exprs were not built");
7160 if (!CurContext->isDependentContext()) {
7162 for (
auto C : Clauses) {
7163 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7174 getCurFunction()->setHasBranchProtectedScope();
7176 DSAStack->setParentTeamsRegionLoc(StartLoc);
7179 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7197 for (
int ThisCaptureLevel =
7198 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7199 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7215 VarsWithImplicitDSA, B);
7217 if (NestedLoopCount == 0)
7220 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7221 "omp for loop exprs were not built");
7223 if (!CurContext->isDependentContext()) {
7225 for (
auto C : Clauses) {
7226 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7237 getCurFunction()->setHasBranchProtectedScope();
7239 DSAStack->setParentTeamsRegionLoc(StartLoc);
7242 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7248 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7260 for (
int ThisCaptureLevel =
7261 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7262 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7278 VarsWithImplicitDSA, B);
7280 if (NestedLoopCount == 0)
7283 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7284 "omp for loop exprs were not built");
7286 getCurFunction()->setHasBranchProtectedScope();
7288 DSAStack->setParentTeamsRegionLoc(StartLoc);
7291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7310 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7311 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7320 getCurFunction()->setHasBranchProtectedScope();
7329 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7340 for (
int ThisCaptureLevel =
7341 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7342 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7358 VarsWithImplicitDSA, B);
7359 if (NestedLoopCount == 0)
7362 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7363 "omp target teams distribute loop exprs were not built");
7365 getCurFunction()->setHasBranchProtectedScope();
7367 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7373 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7389 OMPD_target_teams_distribute_parallel_for,
7392 VarsWithImplicitDSA, B);
7393 if (NestedLoopCount == 0)
7396 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7397 "omp target teams distribute parallel for loop exprs were not built");
7399 getCurFunction()->setHasBranchProtectedScope();
7401 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7408 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7424 OMPD_target_teams_distribute_parallel_for_simd,
7427 VarsWithImplicitDSA, B);
7428 if (NestedLoopCount == 0)
7431 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7432 "omp target teams distribute parallel for simd loop exprs were not " 7435 if (!CurContext->isDependentContext()) {
7437 for (
auto C : Clauses) {
7438 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7449 getCurFunction()->setHasBranchProtectedScope();
7451 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7457 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7461 auto *CS = cast<CapturedStmt>(AStmt);
7468 for (
int ThisCaptureLevel =
7469 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7470 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7486 VarsWithImplicitDSA, B);
7487 if (NestedLoopCount == 0)
7490 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7491 "omp target teams distribute simd loop exprs were not built");
7493 if (!CurContext->isDependentContext()) {
7495 for (
auto C : Clauses) {
7496 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7507 getCurFunction()->setHasBranchProtectedScope();
7509 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7519 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7521 case OMPC_num_threads:
7522 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7525 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7528 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7531 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7534 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7537 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7539 case OMPC_num_teams:
7540 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7542 case OMPC_thread_limit:
7543 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7546 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7548 case OMPC_grainsize:
7549 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7551 case OMPC_num_tasks:
7552 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7555 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7559 case OMPC_proc_bind:
7562 case OMPC_firstprivate:
7563 case OMPC_lastprivate:
7565 case OMPC_reduction:
7566 case OMPC_task_reduction:
7567 case OMPC_in_reduction:
7571 case OMPC_copyprivate:
7574 case OMPC_mergeable:
7587 case OMPC_dist_schedule:
7588 case OMPC_defaultmap:
7593 case OMPC_use_device_ptr:
7594 case OMPC_is_device_ptr:
7595 llvm_unreachable(
"Clause is not allowed.");
7612 case OMPD_target_parallel:
7613 case OMPD_target_parallel_for:
7614 case OMPD_target_parallel_for_simd:
7615 case OMPD_target_teams_distribute_parallel_for:
7616 case OMPD_target_teams_distribute_parallel_for_simd:
7619 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
7620 CaptureRegion = OMPD_target;
7622 case OMPD_teams_distribute_parallel_for:
7623 case OMPD_teams_distribute_parallel_for_simd:
7624 CaptureRegion = OMPD_teams;
7626 case OMPD_target_update:
7627 case OMPD_target_enter_data:
7628 case OMPD_target_exit_data:
7629 CaptureRegion = OMPD_task;
7633 case OMPD_parallel_sections:
7634 case OMPD_parallel_for:
7635 case OMPD_parallel_for_simd:
7637 case OMPD_target_simd:
7638 case OMPD_target_teams:
7639 case OMPD_target_teams_distribute:
7640 case OMPD_target_teams_distribute_simd:
7641 case OMPD_distribute_parallel_for:
7642 case OMPD_distribute_parallel_for_simd:
7645 case OMPD_taskloop_simd:
7646 case OMPD_target_data:
7649 case OMPD_threadprivate:
7650 case OMPD_taskyield:
7653 case OMPD_cancellation_point:
7655 case OMPD_declare_reduction:
7656 case OMPD_declare_simd:
7657 case OMPD_declare_target:
7658 case OMPD_end_declare_target:
7668 case OMPD_taskgroup:
7669 case OMPD_distribute:
7672 case OMPD_distribute_simd:
7673 case OMPD_teams_distribute:
7674 case OMPD_teams_distribute_simd:
7675 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
7677 llvm_unreachable(
"Unknown OpenMP directive");
7680 case OMPC_num_threads:
7682 case OMPD_target_parallel:
7683 case OMPD_target_parallel_for:
7684 case OMPD_target_parallel_for_simd:
7685 case OMPD_target_teams_distribute_parallel_for:
7686 case OMPD_target_teams_distribute_parallel_for_simd:
7687 CaptureRegion = OMPD_target;
7689 case OMPD_teams_distribute_parallel_for:
7690 case OMPD_teams_distribute_parallel_for_simd:
7691 CaptureRegion = OMPD_teams;
7694 case OMPD_parallel_sections:
7695 case OMPD_parallel_for:
7696 case OMPD_parallel_for_simd:
7697 case OMPD_distribute_parallel_for:
7698 case OMPD_distribute_parallel_for_simd:
7701 case OMPD_target_data:
7702 case OMPD_target_enter_data:
7703 case OMPD_target_exit_data:
7704 case OMPD_target_update:
7706 case OMPD_target_simd:
7707 case OMPD_target_teams:
7708 case OMPD_target_teams_distribute:
7709 case OMPD_target_teams_distribute_simd:
7713 case OMPD_taskloop_simd:
7714 case OMPD_threadprivate:
7715 case OMPD_taskyield:
7718 case OMPD_cancellation_point:
7720 case OMPD_declare_reduction:
7721 case OMPD_declare_simd:
7722 case OMPD_declare_target:
7723 case OMPD_end_declare_target:
7733 case OMPD_taskgroup:
7734 case OMPD_distribute:
7737 case OMPD_distribute_simd:
7738 case OMPD_teams_distribute:
7739 case OMPD_teams_distribute_simd:
7740 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
7742 llvm_unreachable(
"Unknown OpenMP directive");
7745 case OMPC_num_teams:
7747 case OMPD_target_teams:
7748 case OMPD_target_teams_distribute:
7749 case OMPD_target_teams_distribute_simd:
7750 case OMPD_target_teams_distribute_parallel_for:
7751 case OMPD_target_teams_distribute_parallel_for_simd:
7752 CaptureRegion = OMPD_target;
7754 case OMPD_teams_distribute_parallel_for:
7755 case OMPD_teams_distribute_parallel_for_simd:
7757 case OMPD_teams_distribute:
7758 case OMPD_teams_distribute_simd:
7761 case OMPD_distribute_parallel_for:
7762 case OMPD_distribute_parallel_for_simd:
7765 case OMPD_taskloop_simd:
7766 case OMPD_target_data:
7767 case OMPD_target_enter_data:
7768 case OMPD_target_exit_data:
7769 case OMPD_target_update:
7772 case OMPD_parallel_sections:
7773 case OMPD_parallel_for:
7774 case OMPD_parallel_for_simd:
7776 case OMPD_target_simd:
7777 case OMPD_target_parallel:
7778 case OMPD_target_parallel_for:
7779 case OMPD_target_parallel_for_simd:
7780 case OMPD_threadprivate:
7781 case OMPD_taskyield:
7784 case OMPD_cancellation_point:
7786 case OMPD_declare_reduction:
7787 case OMPD_declare_simd:
7788 case OMPD_declare_target:
7789 case OMPD_end_declare_target:
7798 case OMPD_taskgroup:
7799 case OMPD_distribute:
7802 case OMPD_distribute_simd:
7803 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
7805 llvm_unreachable(
"Unknown OpenMP directive");
7808 case OMPC_thread_limit:
7810 case OMPD_target_teams:
7811 case OMPD_target_teams_distribute:
7812 case OMPD_target_teams_distribute_simd:
7813 case OMPD_target_teams_distribute_parallel_for:
7814 case OMPD_target_teams_distribute_parallel_for_simd:
7815 CaptureRegion = OMPD_target;
7817 case OMPD_teams_distribute_parallel_for:
7818 case OMPD_teams_distribute_parallel_for_simd:
7820 case OMPD_teams_distribute:
7821 case OMPD_teams_distribute_simd:
7824 case OMPD_distribute_parallel_for:
7825 case OMPD_distribute_parallel_for_simd:
7828 case OMPD_taskloop_simd:
7829 case OMPD_target_data:
7830 case OMPD_target_enter_data:
7831 case OMPD_target_exit_data:
7832 case OMPD_target_update:
7835 case OMPD_parallel_sections:
7836 case OMPD_parallel_for:
7837 case OMPD_parallel_for_simd:
7839 case OMPD_target_simd:
7840 case OMPD_target_parallel:
7841 case OMPD_target_parallel_for:
7842 case OMPD_target_parallel_for_simd:
7843 case OMPD_threadprivate:
7844 case OMPD_taskyield:
7847 case OMPD_cancellation_point:
7849 case OMPD_declare_reduction:
7850 case OMPD_declare_simd:
7851 case OMPD_declare_target:
7852 case OMPD_end_declare_target:
7861 case OMPD_taskgroup:
7862 case OMPD_distribute:
7865 case OMPD_distribute_simd:
7866 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
7868 llvm_unreachable(
"Unknown OpenMP directive");
7873 case OMPD_target_parallel_for:
7874 case OMPD_target_parallel_for_simd:
7875 case OMPD_target_teams_distribute_parallel_for:
7876 case OMPD_target_teams_distribute_parallel_for_simd:
7877 CaptureRegion = OMPD_target;
7879 case OMPD_teams_distribute_parallel_for:
7880 case OMPD_teams_distribute_parallel_for_simd:
7881 CaptureRegion = OMPD_teams;
7883 case OMPD_parallel_for:
7884 case OMPD_parallel_for_simd:
7885 case OMPD_distribute_parallel_for:
7886 case OMPD_distribute_parallel_for_simd:
7887 CaptureRegion = OMPD_parallel;
7895 case OMPD_taskloop_simd:
7896 case OMPD_target_data:
7897 case OMPD_target_enter_data:
7898 case OMPD_target_exit_data:
7899 case OMPD_target_update:
7901 case OMPD_teams_distribute:
7902 case OMPD_teams_distribute_simd:
7903 case OMPD_target_teams_distribute:
7904 case OMPD_target_teams_distribute_simd:
7906 case OMPD_target_simd:
7907 case OMPD_target_parallel:
7910 case OMPD_parallel_sections:
7911 case OMPD_threadprivate:
7912 case OMPD_taskyield:
7915 case OMPD_cancellation_point:
7917 case OMPD_declare_reduction:
7918 case OMPD_declare_simd:
7919 case OMPD_declare_target:
7920 case OMPD_end_declare_target:
7927 case OMPD_taskgroup:
7928 case OMPD_distribute:
7931 case OMPD_distribute_simd:
7932 case OMPD_target_teams:
7933 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
7935 llvm_unreachable(
"Unknown OpenMP directive");
7938 case OMPC_dist_schedule:
7940 case OMPD_teams_distribute_parallel_for:
7941 case OMPD_teams_distribute_parallel_for_simd:
7942 case OMPD_teams_distribute:
7943 case OMPD_teams_distribute_simd:
7944 CaptureRegion = OMPD_teams;
7946 case OMPD_target_teams_distribute_parallel_for:
7947 case OMPD_target_teams_distribute_parallel_for_simd:
7948 case OMPD_target_teams_distribute:
7949 case OMPD_target_teams_distribute_simd:
7950 CaptureRegion = OMPD_target;
7952 case OMPD_distribute_parallel_for:
7953 case OMPD_distribute_parallel_for_simd:
7954 CaptureRegion = OMPD_parallel;
7956 case OMPD_distribute:
7957 case OMPD_distribute_simd:
7960 case OMPD_parallel_for:
7961 case OMPD_parallel_for_simd:
7962 case OMPD_target_parallel_for_simd:
7963 case OMPD_target_parallel_for:
7966 case OMPD_taskloop_simd:
7967 case OMPD_target_data:
7968 case OMPD_target_enter_data:
7969 case OMPD_target_exit_data:
7970 case OMPD_target_update:
7973 case OMPD_target_simd:
7974 case OMPD_target_parallel:
7977 case OMPD_parallel_sections:
7978 case OMPD_threadprivate:
7979 case OMPD_taskyield:
7982 case OMPD_cancellation_point:
7984 case OMPD_declare_reduction:
7985 case OMPD_declare_simd:
7986 case OMPD_declare_target:
7987 case OMPD_end_declare_target:
7996 case OMPD_taskgroup:
7999 case OMPD_target_teams:
8000 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8002 llvm_unreachable(
"Unknown OpenMP directive");
8007 case OMPD_target_update:
8008 case OMPD_target_enter_data:
8009 case OMPD_target_exit_data:
8010 CaptureRegion = OMPD_task;
8012 case OMPD_target_teams:
8013 case OMPD_target_teams_distribute:
8014 case OMPD_target_teams_distribute_simd:
8015 case OMPD_target_teams_distribute_parallel_for:
8016 case OMPD_target_teams_distribute_parallel_for_simd:
8017 case OMPD_target_data:
8019 case OMPD_target_simd:
8020 case OMPD_target_parallel:
8021 case OMPD_target_parallel_for:
8022 case OMPD_target_parallel_for_simd:
8025 case OMPD_teams_distribute_parallel_for:
8026 case OMPD_teams_distribute_parallel_for_simd:
8028 case OMPD_teams_distribute:
8029 case OMPD_teams_distribute_simd:
8030 case OMPD_distribute_parallel_for:
8031 case OMPD_distribute_parallel_for_simd:
8034 case OMPD_taskloop_simd:
8037 case OMPD_parallel_sections:
8038 case OMPD_parallel_for:
8039 case OMPD_parallel_for_simd:
8040 case OMPD_threadprivate:
8041 case OMPD_taskyield:
8044 case OMPD_cancellation_point:
8046 case OMPD_declare_reduction:
8047 case OMPD_declare_simd:
8048 case OMPD_declare_target:
8049 case OMPD_end_declare_target:
8058 case OMPD_taskgroup:
8059 case OMPD_distribute:
8062 case OMPD_distribute_simd:
8063 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8065 llvm_unreachable(
"Unknown OpenMP directive");
8068 case OMPC_firstprivate:
8069 case OMPC_lastprivate:
8070 case OMPC_reduction:
8071 case OMPC_task_reduction:
8072 case OMPC_in_reduction:
8075 case OMPC_proc_bind:
8084 case OMPC_copyprivate:
8088 case OMPC_mergeable:
8101 case OMPC_grainsize:
8103 case OMPC_num_tasks:
8105 case OMPC_defaultmap:
8110 case OMPC_use_device_ptr:
8111 case OMPC_is_device_ptr:
8112 llvm_unreachable(
"Unexpected OpenMP clause.");
8114 return CaptureRegion;
8123 Expr *ValExpr = Condition;
8124 Stmt *HelperValStmt =
nullptr;
8129 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8133 ValExpr = Val.
get();
8138 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8139 ValExpr = MakeFullExpr(ValExpr).get();
8140 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8141 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8146 return new (Context)
8147 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8148 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8155 Expr *ValExpr = Condition;
8159 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8163 ValExpr = MakeFullExpr(Val.
get()).
get();
8166 return new (Context)
OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8175 IntConvertDiagnoser()
8179 return S.
Diag(Loc, diag::err_omp_not_integral) <<
T;
8183 return S.
Diag(Loc, diag::err_omp_incomplete_type) <<
T;
8188 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8197 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) <<
T;
8206 llvm_unreachable(
"conversion functions are permitted");
8209 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8214 bool StrictlyPositive) {
8223 ValExpr = Value.
get();
8227 Result.isSigned() &&
8228 !((!StrictlyPositive && Result.isNonNegative()) ||
8229 (StrictlyPositive && Result.isStrictlyPositive()))) {
8230 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
8243 Expr *ValExpr = NumThreads;
8244 Stmt *HelperValStmt =
nullptr;
8255 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8256 ValExpr = MakeFullExpr(ValExpr).get();
8257 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8258 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8263 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8268 bool StrictlyPositive) {
8275 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8278 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8279 (!StrictlyPositive && !Result.isNonNegative())) {
8280 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
8285 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8290 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
8291 DSAStack->setAssociatedLoops(Result.getExtValue());
8292 else if (CKind == OMPC_ordered)
8293 DSAStack->setAssociatedLoops(Result.getExtValue());
8303 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8306 return new (Context)
8316 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8319 return new (Context)
8333 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8336 return new (Context)
8343 Expr *NumForLoops) {
8349 if (NumForLoops && LParenLoc.
isValid()) {
8351 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8354 NumForLoops = NumForLoopsResult.
get();
8356 NumForLoops =
nullptr;
8357 DSAStack->setOrderedRegion(
true, NumForLoops);
8358 return new (Context)
8369 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8370 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8372 case OMPC_proc_bind:
8373 Res = ActOnOpenMPProcBindClause(
8374 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8379 case OMPC_num_threads:
8385 case OMPC_firstprivate:
8386 case OMPC_lastprivate:
8388 case OMPC_reduction:
8389 case OMPC_task_reduction:
8390 case OMPC_in_reduction:
8394 case OMPC_copyprivate:
8398 case OMPC_mergeable:
8411 case OMPC_num_teams:
8412 case OMPC_thread_limit:
8414 case OMPC_grainsize:
8416 case OMPC_num_tasks:
8418 case OMPC_dist_schedule:
8419 case OMPC_defaultmap:
8424 case OMPC_use_device_ptr:
8425 case OMPC_is_device_ptr:
8426 llvm_unreachable(
"Clause is not allowed.");
8435 unsigned Bound = Last >= 2 ? Last - 2 : 0;
8436 unsigned Skipped = Exclude.size();
8437 auto S = Exclude.begin(), E = Exclude.end();
8438 for (
unsigned i = First; i <
Last; ++i) {
8439 if (std::find(S, E, i) != E) {
8446 if (i == Bound - Skipped)
8448 else if (i != Bound + 1 - Skipped)
8461 "OMPC_DEFAULT_unknown not greater than 0");
8462 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8469 case OMPC_DEFAULT_none:
8470 DSAStack->setDefaultDSANone(KindKwLoc);
8472 case OMPC_DEFAULT_shared:
8473 DSAStack->setDefaultDSAShared(KindKwLoc);
8476 llvm_unreachable(
"Clause kind is not allowed.");
8479 return new (Context)
8489 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8495 return new (Context)
8507 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8508 assert(Argument.size() == NumberOfElements &&
8509 ArgumentLoc.size() == NumberOfElements);
8510 Res = ActOnOpenMPScheduleClause(
8511 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8512 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8513 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8514 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8515 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8518 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8519 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8520 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8523 case OMPC_dist_schedule:
8524 Res = ActOnOpenMPDistScheduleClause(
8525 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8526 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8528 case OMPC_defaultmap:
8530 Res = ActOnOpenMPDefaultmapClause(
8531 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
8532 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8533 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8537 case OMPC_num_threads:
8542 case OMPC_proc_bind:
8544 case OMPC_firstprivate:
8545 case OMPC_lastprivate:
8547 case OMPC_reduction:
8548 case OMPC_task_reduction:
8549 case OMPC_in_reduction:
8553 case OMPC_copyprivate:
8557 case OMPC_mergeable:
8570 case OMPC_num_teams:
8571 case OMPC_thread_limit:
8573 case OMPC_grainsize:
8575 case OMPC_num_tasks:
8581 case OMPC_use_device_ptr:
8582 case OMPC_is_device_ptr:
8583 llvm_unreachable(
"Clause is not allowed.");
8594 Excluded.push_back(M2);
8595 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8596 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8597 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8598 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8599 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8622 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8623 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8624 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8625 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8626 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8642 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8649 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
8650 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
8651 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
8652 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
8653 diag::err_omp_schedule_nonmonotonic_static);
8656 Expr *ValExpr = ChunkSize;
8657 Stmt *HelperValStmt =
nullptr;
8664 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
8668 ValExpr = Val.
get();
8675 if (Result.isSigned() && !Result.isStrictlyPositive()) {
8676 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
8681 DSAStack->getCurrentDirective(), OMPC_schedule) !=
8683 !CurContext->isDependentContext()) {
8684 ValExpr = MakeFullExpr(ValExpr).get();
8685 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8686 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8692 return new (Context)
8694 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
8703 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
8706 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
8709 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
8711 case OMPC_mergeable:
8712 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
8715 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
8718 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
8721 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
8724 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
8727 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
8730 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
8733 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
8736 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
8740 case OMPC_num_threads:
8746 case OMPC_firstprivate:
8747 case OMPC_lastprivate:
8749 case OMPC_reduction:
8750 case OMPC_task_reduction:
8751 case OMPC_in_reduction:
8755 case OMPC_copyprivate:
8757 case OMPC_proc_bind:
8763 case OMPC_num_teams:
8764 case OMPC_thread_limit:
8766 case OMPC_grainsize:
8767 case OMPC_num_tasks:
8769 case OMPC_dist_schedule:
8770 case OMPC_defaultmap:
8775 case OMPC_use_device_ptr:
8776 case OMPC_is_device_ptr:
8777 llvm_unreachable(
"Clause is not allowed.");
8849 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8851 case OMPC_firstprivate:
8852 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8854 case OMPC_lastprivate:
8855 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8858 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
8860 case OMPC_reduction:
8861 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8862 EndLoc, ReductionIdScopeSpec, ReductionId);
8864 case OMPC_task_reduction:
8865 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8866 EndLoc, ReductionIdScopeSpec,
8869 case OMPC_in_reduction:
8871 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8872 EndLoc, ReductionIdScopeSpec, ReductionId);
8875 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
8876 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8879 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
8883 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
8885 case OMPC_copyprivate:
8886 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8889 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
8892 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
8893 StartLoc, LParenLoc, EndLoc);
8896 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
8897 DepLinMapLoc, ColonLoc, VarList, StartLoc,
8901 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
8904 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
8906 case OMPC_use_device_ptr:
8907 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8909 case OMPC_is_device_ptr:
8910 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8914 case OMPC_num_threads:
8919 case OMPC_proc_bind:
8924 case OMPC_mergeable:
8934 case OMPC_num_teams:
8935 case OMPC_thread_limit:
8937 case OMPC_grainsize:
8939 case OMPC_num_tasks:
8941 case OMPC_dist_schedule:
8942 case OMPC_defaultmap:
8945 llvm_unreachable(
"Clause is not allowed.");
8956 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
8957 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
8962 Res = DefaultLvalueConversion(Res.
get());
8969 static std::pair<ValueDecl *, bool>
8971 SourceRange &ERange,
bool AllowArraySection =
false) {
8974 return std::make_pair(
nullptr,
true);
8986 } IsArrayExpr = NoArrayExpr;
8987 if (AllowArraySection) {
8988 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8989 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
8990 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8991 Base = TempASE->getBase()->IgnoreParenImpCasts();
8993 IsArrayExpr = ArraySubscript;
8994 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8995 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
8996 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
8997 Base = TempOASE->getBase()->IgnoreParenImpCasts();
8998 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8999 Base = TempASE->getBase()->IgnoreParenImpCasts();
9001 IsArrayExpr = OMPArraySection;
9007 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9008 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9009 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9011 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9012 !isa<FieldDecl>(ME->getMemberDecl()))) {
9013 if (IsArrayExpr != NoArrayExpr)
9014 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9019 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9020 : diag::err_omp_expected_var_name_member_expr)
9023 return std::make_pair(
nullptr,
false);
9025 return std::make_pair(
9035 for (
auto &RefExpr : VarList) {
9036 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
9039 Expr *SimpleRefExpr = RefExpr;
9043 Vars.push_back(RefExpr);
9044 PrivateCopies.push_back(
nullptr);
9051 auto *VD = dyn_cast<
VarDecl>(D);
9056 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9067 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9068 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
9075 auto CurrDir =
DSAStack->getCurrentDirective();
9079 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9086 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9094 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
9095 CurrDir == OMPD_target_teams ||
9096 CurrDir == OMPD_target_teams_distribute ||
9097 CurrDir == OMPD_target_teams_distribute_parallel_for ||
9098 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
9099 CurrDir == OMPD_target_teams_distribute_simd ||
9100 CurrDir == OMPD_target_parallel_for_simd ||
9101 CurrDir == OMPD_target_parallel_for) {
9103 if (
DSAStack->checkMappableExprComponentListsForDecl(
9107 ConflictKind = WhereFoundClauseKind;
9110 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9131 ActOnUninitializedDecl(VDPrivate);
9132 if (VDPrivate->isInvalidDecl())
9135 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9138 if (!VD && !CurContext->isDependentContext())
9140 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9141 Vars.push_back((VD || CurContext->isDependentContext())
9142 ? RefExpr->IgnoreParens()
9144 PrivateCopies.push_back(VDPrivateRefExpr);
9155 class DiagsUninitializedSeveretyRAII {
9164 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9166 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
9170 ~DiagsUninitializedSeveretyRAII() {
9185 bool IsImplicitClause =
9187 auto ImplicitClauseLoc =
DSAStack->getConstructLoc();
9189 for (
auto &RefExpr : VarList) {
9190 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
9193 Expr *SimpleRefExpr = RefExpr;
9197 Vars.push_back(RefExpr);
9198 PrivateCopies.push_back(
nullptr);
9199 Inits.push_back(
nullptr);
9205 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9207 auto *VD = dyn_cast<
VarDecl>(D);
9212 if (RequireCompleteType(ELoc, Type,
9213 diag::err_omp_firstprivate_incomplete_type))
9224 DSAStackTy::DSAVarData TopDVar;
9225 if (!IsImplicitClause) {
9226 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9229 bool IsConstant = ElemType.isConstant(Context);
9237 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9239 DVar.CKind != OMPC_lastprivate) &&
9241 Diag(ELoc, diag::err_omp_wrong_dsa)
9259 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9260 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
9261 Diag(ELoc, diag::err_omp_wrong_dsa)
9287 DVar =
DSAStack->getImplicitDSA(D,
true);
9288 if (DVar.CKind != OMPC_shared &&
9292 Diag(ELoc, diag::err_omp_required_access)
9319 if (DVar.CKind == OMPC_reduction &&
9323 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9335 if (
DSAStack->checkMappableExprComponentListsForDecl(
9339 ConflictKind = WhereFoundClauseKind;
9342 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9355 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9362 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9375 Expr *VDInitRefExpr =
nullptr;
9382 auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
9383 ElemType = ElemType.getUnqualifiedType();
9384 auto *VDInitTemp =
buildVarDecl(*
this, RefExpr->getExprLoc(), ElemType,
9385 ".firstprivate.temp");
9393 VDPrivate->setInvalidDecl();
9395 VDPrivate->setInit(Result.
getAs<
Expr>());
9399 auto *VDInit =
buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
9400 ".firstprivate.temp");
9402 RefExpr->getExprLoc());
9403 AddInitializerToDecl(VDPrivate,
9404 DefaultLvalueConversion(VDInitRefExpr).
get(),
9407 if (VDPrivate->isInvalidDecl()) {
9408 if (IsImplicitClause) {
9409 Diag(RefExpr->getExprLoc(),
9410 diag::note_omp_task_predetermined_firstprivate_here);
9414 CurContext->addDecl(VDPrivate);
9416 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9417 RefExpr->getExprLoc());
9419 if (!VD && !CurContext->isDependentContext()) {
9420 if (TopDVar.CKind == OMPC_lastprivate)
9421 Ref = TopDVar.PrivateCopy;
9424 if (!IsOpenMPCapturedDecl(D))
9425 ExprCaptures.push_back(Ref->getDecl());
9428 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9429 Vars.push_back((VD || CurContext->isDependentContext())
9430 ? RefExpr->IgnoreParens()
9432 PrivateCopies.push_back(VDPrivateRefExpr);
9433 Inits.push_back(VDInitRefExpr);
9440 Vars, PrivateCopies, Inits,
9454 for (
auto &RefExpr : VarList) {
9455 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
9458 Expr *SimpleRefExpr = RefExpr;
9462 Vars.push_back(RefExpr);
9463 SrcExprs.push_back(
nullptr);
9464 DstExprs.push_back(
nullptr);
9465 AssignmentOps.push_back(
nullptr);
9472 auto *VD = dyn_cast<
VarDecl>(D);
9477 if (RequireCompleteType(ELoc, Type,
9478 diag::err_omp_lastprivate_incomplete_type))
9491 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9492 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9494 DVar.CKind != OMPC_firstprivate) &&
9495 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
9496 Diag(ELoc, diag::err_omp_wrong_dsa)
9509 DSAStackTy::DSAVarData TopDVar = DVar;
9513 DVar =
DSAStack->getImplicitDSA(D,
true);
9514 if (DVar.CKind != OMPC_shared) {
9515 Diag(ELoc, diag::err_omp_required_access)
9535 auto *PseudoSrcExpr =
9543 auto AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
9544 PseudoDstExpr, PseudoSrcExpr);
9545 if (AssignmentOp.isInvalid())
9547 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9549 if (AssignmentOp.isInvalid())
9553 if (!VD && !CurContext->isDependentContext()) {
9554 if (TopDVar.CKind == OMPC_firstprivate)
9555 Ref = TopDVar.PrivateCopy;
9558 if (!IsOpenMPCapturedDecl(D))
9559 ExprCaptures.push_back(Ref->
getDecl());
9561 if (TopDVar.CKind == OMPC_firstprivate ||
9562 (!IsOpenMPCapturedDecl(D) &&
9564 ExprResult RefRes = DefaultLvalueConversion(Ref);
9568 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9572 ExprPostUpdates.push_back(
9573 IgnoredValueConversions(PostUpdateRes.
get()).
get());
9576 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9577 Vars.push_back((VD || CurContext->isDependentContext())
9578 ? RefExpr->IgnoreParens()
9580 SrcExprs.push_back(PseudoSrcExpr);
9581 DstExprs.push_back(PseudoDstExpr);
9582 AssignmentOps.push_back(AssignmentOp.get());
9589 Vars, SrcExprs, DstExprs, AssignmentOps,
9599 for (
auto &RefExpr : VarList) {
9600 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
9603 Expr *SimpleRefExpr = RefExpr;
9607 Vars.push_back(RefExpr);
9613 auto *VD = dyn_cast<
VarDecl>(D);
9621 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9622 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
9631 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9633 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9634 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9635 ? RefExpr->IgnoreParens()
9646 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
9652 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
9653 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
9657 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
9666 bool VisitStmt(
Stmt *S) {
9668 if (Child && Visit(Child))
9673 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
9680 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
9687 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
9693 return CapturedExpr;
9695 return BaseTransform::TransformMemberExpr(E);
9697 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
9701 template <
typename T>
9703 const llvm::function_ref<
T(
ValueDecl *)> &Gen) {
9704 for (
auto &Set : Lookups) {
9705 for (
auto *D : Set) {
9706 if (
auto Res = Gen(cast<ValueDecl>(D)))
9732 Lookups.back().append(Lookup.
begin(), Lookup.
end());
9735 }
else if (
auto *ULE =
9736 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
9738 Decl *PrevD =
nullptr;
9739 for (
auto *D : ULE->decls()) {
9742 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
9743 Lookups.back().addDecl(DRD);
9750 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) ->
bool {
9757 for (
auto &Set : Lookups) {
9758 ResSet.
append(Set.begin(), Set.end());
9760 ResSet.
addDecl(Set[Set.size() - 1]);
9765 true,
true, ResSet.
begin(), ResSet.
end());
9767 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
9775 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
9787 VD->getType().getUnqualifiedType()))) {
9797 if (ReductionIdScopeSpec.
isSet()) {
9798 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
9806 struct ReductionData {
9824 ReductionData() =
delete;
9826 ReductionData(
unsigned Size) {
9828 Privates.reserve(Size);
9831 ReductionOps.reserve(Size);
9832 TaskgroupDescriptors.reserve(Size);
9833 ExprCaptures.reserve(Size);
9834 ExprPostUpdates.reserve(Size);
9838 void push(
Expr *Item,
Expr *ReductionOp) {
9839 Vars.emplace_back(Item);
9840 Privates.emplace_back(
nullptr);
9841 LHSs.emplace_back(
nullptr);
9842 RHSs.emplace_back(
nullptr);
9843 ReductionOps.emplace_back(ReductionOp);
9844 TaskgroupDescriptors.emplace_back(
nullptr);
9848 Expr *TaskgroupDescriptor) {
9849 Vars.emplace_back(Item);
9850 Privates.emplace_back(Private);
9851 LHSs.emplace_back(LHS);
9852 RHSs.emplace_back(RHS);
9853 ReductionOps.emplace_back(ReductionOp);
9854 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
9863 if (Length ==
nullptr) {
9870 SingleElement =
true;
9871 ArraySizes.push_back(llvm::APSInt::get(1));
9873 llvm::APSInt ConstantLengthValue;
9877 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
9878 ArraySizes.push_back(ConstantLengthValue);
9886 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
9887 Length = TempOASE->getLength();
9888 if (Length ==
nullptr) {
9895 ArraySizes.push_back(llvm::APSInt::get(1));
9897 llvm::APSInt ConstantLengthValue;
9899 ConstantLengthValue.getSExtValue() != 1)
9902 ArraySizes.push_back(ConstantLengthValue);
9908 if (!SingleElement) {
9909 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
9911 ArraySizes.push_back(llvm::APSInt::get(1));
9927 auto DN = ReductionId.
getName();
9965 case OO_Array_Delete:
9974 case OO_GreaterEqual:
9979 case OO_PercentEqual:
9984 case OO_GreaterGreater:
9985 case OO_LessLessEqual:
9986 case OO_GreaterGreaterEqual:
9988 case OO_ExclaimEqual:
9997 case OO_Conditional:
10000 llvm_unreachable(
"Unexpected reduction identifier");
10002 if (
auto *II = DN.getAsIdentifierInfo()) {
10003 if (II->isStr(
"max"))
10005 else if (II->isStr(
"min"))
10011 if (ReductionIdScopeSpec.
isValid())
10017 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10018 bool FirstIter =
true;
10019 for (
auto RefExpr : VarList) {
10020 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
10028 if (!FirstIter && IR != ER)
10033 Expr *SimpleRefExpr = RefExpr;
10042 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10043 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10044 Expr *ReductionOp =
nullptr;
10046 (DeclareReductionRef.
isUnset() ||
10047 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
10048 ReductionOp = DeclareReductionRef.
get();
10050 RD.push(RefExpr, ReductionOp);
10056 Expr *TaskgroupDescriptor =
nullptr;
10061 Type = ASE->getType().getNonReferenceType();
10064 if (
auto *ATy = BaseType->getAsArrayTypeUnsafe())
10065 Type = ATy->getElementType();
10071 auto *VD = dyn_cast<
VarDecl>(D);
10077 diag::err_omp_reduction_incomplete_type))
10083 S.
Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10084 if (!ASE && !OASE) {
10085 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10088 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10096 if (!ASE && !OASE && VD) {
10098 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
10099 DSARefChecker Check(Stack);
10100 if (Check.Visit(VDDef->
getInit())) {
10101 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10120 DSAStackTy::DSAVarData DVar;
10121 DVar = Stack->getTopDSA(D,
false);
10122 if (DVar.CKind == OMPC_reduction) {
10123 S.
Diag(ELoc, diag::err_omp_once_referenced)
10126 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10129 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
10144 DVar = Stack->getImplicitDSA(D,
true);
10145 if (DVar.CKind != OMPC_shared) {
10146 S.
Diag(ELoc, diag::err_omp_required_access)
10158 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10159 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10163 (DeclareReductionRef.
isUnset() ||
10164 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
10165 RD.push(RefExpr, DeclareReductionRef.
get());
10168 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
10170 S.
Diag(ReductionId.getLocStart(),
10171 diag::err_omp_unknown_reduction_identifier)
10172 << Type << ReductionIdRange;
10184 if (DeclareReductionRef.
isUnset()) {
10185 if ((BOK == BO_GT || BOK == BO_LT) &&
10186 !(Type->isScalarType() ||
10187 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10188 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10190 if (!ASE && !OASE) {
10191 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10194 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10199 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10200 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
10201 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10203 if (!ASE && !OASE) {
10204 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10207 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10214 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10215 auto *LHSVD =
buildVarDecl(S, ELoc, Type,
".reduction.lhs",
10219 auto PrivateTy = Type;
10223 bool ConstantLengthOASE =
false;
10225 bool SingleElement;
10228 Context, OASE, SingleElement, ArraySizes);
10231 if (ConstantLengthOASE && !SingleElement) {
10232 for (
auto &Size : ArraySizes) {
10239 if ((OASE && !ConstantLengthOASE) ||
10244 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10245 S.
Diag(ELoc, diag::note_vla_unsupported);
10257 }
else if (!ASE && !OASE &&
10264 Expr *Init =
nullptr;
10267 if (DeclareReductionRef.
isUsable()) {
10269 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10270 if (DRD->getInitializer()) {
10272 RHSVD->setInit(DRDRef);
10282 if (Type->isScalarType() || Type->isAnyComplexType())
10287 if (Type->isScalarType() || Type->isAnyComplexType()) {
10296 Type = ComplexTy->getElementType();
10297 if (Type->isRealFloatingType()) {
10298 llvm::APFloat InitValue =
10299 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
10303 }
else if (Type->isScalarType()) {
10306 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10323 if (Type->isIntegerType() || Type->isPointerType()) {
10328 llvm::APInt InitValue =
10329 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10330 : llvm::APInt::getMinValue(Size)
10331 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10332 : llvm::APInt::getMaxValue(Size);
10334 if (Type->isPointerType()) {
10342 }
else if (Type->isRealFloatingType()) {
10343 llvm::APFloat InitValue = llvm::APFloat::getLargest(
10374 llvm_unreachable(
"Unexpected reduction operation");
10377 if (Init && DeclareReductionRef.
isUnset())
10381 if (RHSVD->isInvalidDecl())
10383 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
10384 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10385 << Type << ReductionIdRange;
10386 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10389 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10395 PrivateVD->setInit(RHSVD->getInit());
10396 PrivateVD->setInitStyle(RHSVD->getInitStyle());
10399 if (DeclareReductionRef.
isUsable()) {
10400 QualType RedTy = DeclareReductionRef.
get()->getType();
10404 if (!BasePath.empty()) {
10408 CK_UncheckedDerivedToBase, LHS.
get(),
10409 &BasePath, LHS.
get()->getValueKind());
10411 CK_UncheckedDerivedToBase, RHS.get(),
10412 &BasePath, RHS.get()->getValueKind());
10415 QualType Params[] = {PtrRedTy, PtrRedTy};
10421 ReductionOp =
new (Context)
10425 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10427 if (BOK != BO_LT && BOK != BO_GT) {
10429 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10430 BO_Assign, LHSDRE, ReductionOp.
get());
10432 auto *ConditionalOp =
new (Context)
10436 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10437 BO_Assign, LHSDRE, ConditionalOp);
10453 if (ClauseKind == OMPC_in_reduction) {
10456 const Expr *ParentReductionOp;
10457 Expr *ParentBOKTD, *ParentReductionOpTD;
10458 DSAStackTy::DSAVarData ParentBOKDSA =
10459 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10461 DSAStackTy::DSAVarData ParentReductionOpDSA =
10462 Stack->getTopMostTaskgroupReductionData(
10463 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10464 bool IsParentBOK = ParentBOKDSA.DKind !=
OMPD_unknown;
10465 bool IsParentReductionOp = ParentReductionOpDSA.DKind !=
OMPD_unknown;
10466 if (!IsParentBOK && !IsParentReductionOp) {
10467 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10470 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
10471 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
10472 IsParentReductionOp) {
10473 bool EmitError =
true;
10474 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
10475 llvm::FoldingSetNodeID RedId, ParentRedId;
10476 ParentReductionOp->
Profile(ParentRedId, Context,
true);
10477 DeclareReductionRef.
get()->Profile(RedId, Context,
10479 EmitError = RedId != ParentRedId;
10482 S.
Diag(ReductionId.getLocStart(),
10483 diag::err_omp_reduction_identifier_mismatch)
10484 << ReductionIdRange << RefExpr->getSourceRange();
10486 diag::note_omp_previous_reduction_identifier)
10488 << (IsParentBOK ? ParentBOKDSA.RefExpr
10489 : ParentReductionOpDSA.RefExpr)
10490 ->getSourceRange();
10494 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10495 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
10502 TransformExprToCaptures RebuildToCapture(S, D);
10504 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
10505 Ref = RebuildToCapture.getCapturedExpr();
10507 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
10510 RD.ExprCaptures.emplace_back(Ref->
getDecl());
10516 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10521 Stack->getCurrentDirective() == OMPD_taskgroup) {
10522 S.
Diag(RefExpr->getExprLoc(),
10523 diag::err_omp_reduction_non_addressable_expression)
10524 << RefExpr->getSourceRange();
10527 RD.ExprPostUpdates.emplace_back(
10534 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10535 if (CurrDir == OMPD_taskgroup) {
10536 if (DeclareReductionRef.
isUsable())
10537 Stack->addTaskgroupReductionData(D, ReductionIdRange,
10538 DeclareReductionRef.
get());
10540 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10542 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
10543 TaskgroupDescriptor);
10545 return RD.Vars.empty();
10553 ReductionData RD(VarList.size());
10556 StartLoc, LParenLoc, ColonLoc, EndLoc,
10557 ReductionIdScopeSpec, ReductionId,
10558 UnresolvedReductions, RD))
10562 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10564 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10574 ReductionData RD(VarList.size());
10577 VarList, StartLoc, LParenLoc, ColonLoc,
10578 EndLoc, ReductionIdScopeSpec, ReductionId,
10579 UnresolvedReductions, RD))
10583 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10585 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10595 ReductionData RD(VarList.size());
10598 StartLoc, LParenLoc, ColonLoc, EndLoc,
10599 ReductionIdScopeSpec, ReductionId,
10600 UnresolvedReductions, RD))
10604 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10606 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10613 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10615 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10624 auto *VD = dyn_cast_or_null<VarDecl>(D);
10626 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10628 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10630 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10638 Diag(ELoc, diag::err_omp_const_variable)
10645 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10654 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
10655 !Ty->isPointerType())) {
10656 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
10662 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10679 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
10680 LinKind = OMPC_LINEAR_val;
10681 for (
auto &RefExpr : VarList) {
10682 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
10685 Expr *SimpleRefExpr = RefExpr;
10690 Vars.push_back(RefExpr);
10691 Privates.push_back(
nullptr);
10692 Inits.push_back(
nullptr);
10699 auto *VD = dyn_cast<
VarDecl>(D);
10705 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10706 if (DVar.RefExpr) {
10713 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
10725 if (!VD && !CurContext->isDependentContext()) {
10727 if (!IsOpenMPCapturedDecl(D)) {
10728 ExprCaptures.push_back(Ref->
getDecl());
10730 ExprResult RefRes = DefaultLvalueConversion(Ref);
10734 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
10735 SimpleRefExpr, RefRes.
get());
10738 ExprPostUpdates.push_back(
10739 IgnoredValueConversions(PostUpdateRes.
get()).
get());
10743 if (LinKind == OMPC_LINEAR_uval)
10744 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
10746 InitExpr = VD ? SimpleRefExpr : Ref;
10747 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
10751 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
10752 Vars.push_back((VD || CurContext->isDependentContext())
10753 ? RefExpr->IgnoreParens()
10755 Privates.push_back(PrivateRef);
10756 Inits.push_back(InitRef);
10763 Expr *CalcStepExpr =
nullptr;
10768 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
10771 StepExpr = Val.
get();
10779 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
10780 CalcStep = ActOnFinishFullExpr(CalcStep.get());
10786 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
10787 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
10788 << (Vars.size() > 1);
10789 if (!IsConstant && CalcStep.isUsable()) {
10792 CalcStepExpr = CalcStep.get();
10797 ColonLoc, EndLoc, Vars, Privates, Inits,
10798 StepExpr, CalcStepExpr,
10804 Expr *NumIterations,
Sema &SemaRef,
10805 Scope *S, DSAStackTy *Stack) {
10813 if (Step ==
nullptr)
10815 else if (CalcStep) {
10816 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
10818 bool HasErrors =
false;
10819 auto CurInit = Clause.inits().begin();
10820 auto CurPrivate = Clause.privates().begin();
10821 auto LinKind = Clause.getModifier();
10822 for (
auto &RefExpr : Clause.
varlists()) {
10825 Expr *SimpleRefExpr = RefExpr;
10829 if (Res.second || !D) {
10830 Updates.push_back(
nullptr);
10831 Finals.push_back(
nullptr);
10835 auto &&Info = Stack->isLoopControlVariable(D);
10842 diag::err_omp_linear_distribute_var_non_loop_iteration);
10843 Updates.push_back(
nullptr);
10844 Finals.push_back(
nullptr);
10848 Expr *InitExpr = *CurInit;
10851 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
10853 if (LinKind == OMPC_LINEAR_uval)
10854 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
10858 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
10866 InitExpr, IV,
Step,
false);
10868 Update = *CurPrivate;
10876 InitExpr, NumIterations,
Step,
10879 Final = *CurPrivate;
10883 if (!Update.isUsable() || !Final.isUsable()) {
10884 Updates.push_back(
nullptr);
10885 Finals.push_back(
nullptr);
10888 Updates.push_back(Update.get());
10889 Finals.push_back(Final.get());
10894 Clause.setUpdates(Updates);
10895 Clause.setFinals(Finals);
10904 for (
auto &RefExpr : VarList) {
10905 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
10908 Expr *SimpleRefExpr = RefExpr;
10913 Vars.push_back(RefExpr);
10920 auto *VD = dyn_cast<
VarDecl>(D);
10926 const Type *Ty = QType.getTypePtrOrNull();
10928 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
10929 << QType << getLangOpts().CPlusPlus << ERange;
10934 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10941 if (
Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
10942 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
10943 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
10949 if (!VD && IsOpenMPCapturedDecl(D))
10951 Vars.push_back(DefaultFunctionArrayConversion(
10952 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
10961 if (Alignment !=
nullptr) {
10963 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
10966 Alignment = AlignResult.
get();
10972 EndLoc, Vars, Alignment);
10983 for (
auto &RefExpr : VarList) {
10984 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
10985 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10987 Vars.push_back(RefExpr);
10988 SrcExprs.push_back(
nullptr);
10989 DstExprs.push_back(
nullptr);
10990 AssignmentOps.push_back(
nullptr);
11000 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
11001 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11002 << 0 << RefExpr->getSourceRange();
11007 VarDecl *VD = cast<VarDecl>(D);
11010 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11012 Vars.push_back(DE);
11013 SrcExprs.push_back(
nullptr);
11014 DstExprs.push_back(
nullptr);
11015 AssignmentOps.push_back(
nullptr);
11021 if (!
DSAStack->isThreadPrivate(VD)) {
11022 Diag(ELoc, diag::err_omp_required_access)
11037 *
this, SrcVD, ElemType.getUnqualifiedType(), DE->
getExprLoc());
11041 auto *PseudoDstExpr =
11045 auto AssignmentOp = BuildBinOp(
nullptr, DE->
getExprLoc(), BO_Assign,
11046 PseudoDstExpr, PseudoSrcExpr);
11047 if (AssignmentOp.isInvalid())
11049 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->
getExprLoc(),
11051 if (AssignmentOp.isInvalid())
11054 DSAStack->addDSA(VD, DE, OMPC_copyin);
11055 Vars.push_back(DE);
11056 SrcExprs.push_back(PseudoSrcExpr);
11057 DstExprs.push_back(PseudoDstExpr);
11058 AssignmentOps.push_back(AssignmentOp.get());
11065 SrcExprs, DstExprs, AssignmentOps);
11076 for (
auto &RefExpr : VarList) {
11077 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11080 Expr *SimpleRefExpr = RefExpr;
11085 Vars.push_back(RefExpr);
11086 SrcExprs.push_back(
nullptr);
11087 DstExprs.push_back(
nullptr);
11088 AssignmentOps.push_back(
nullptr);
11095 auto *VD = dyn_cast<
VarDecl>(D);
11100 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
11101 auto DVar =
DSAStack->getTopDSA(D,
false);
11102 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11104 Diag(ELoc, diag::err_omp_wrong_dsa)
11115 DVar =
DSAStack->getImplicitDSA(D,
false);
11116 if (DVar.CKind == OMPC_shared) {
11117 Diag(ELoc, diag::err_omp_required_access)
11119 <<
"threadprivate or private in the enclosing context";
11128 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11135 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11145 .getUnqualifiedType();
11147 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.src",
11151 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.dst",
11154 auto AssignmentOp = BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
11155 PseudoDstExpr, PseudoSrcExpr);
11156 if (AssignmentOp.isInvalid())
11158 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11160 if (AssignmentOp.isInvalid())
11165 assert(VD || IsOpenMPCapturedDecl(D));
11167 VD ? RefExpr->IgnoreParens()
11169 SrcExprs.push_back(PseudoSrcExpr);
11170 DstExprs.push_back(PseudoDstExpr);
11171 AssignmentOps.push_back(AssignmentOp.get());
11178 Vars, SrcExprs, DstExprs, AssignmentOps);
11185 if (VarList.empty())
11196 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
11197 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11198 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11202 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
11204 DepKind == OMPC_DEPEND_sink)) {
11205 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11206 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11214 llvm::APSInt DepCounter(32);
11215 llvm::APSInt TotalDepCount(32);
11216 if (DepKind == OMPC_DEPEND_sink) {
11217 if (
auto *OrderedCountExpr =
DSAStack->getParentOrderedRegionParam()) {
11218 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11219 TotalDepCount.setIsUnsigned(
true);
11222 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
11223 DSAStack->getParentOrderedRegionParam()) {
11224 for (
auto &RefExpr : VarList) {
11225 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
11226 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11228 Vars.push_back(RefExpr);
11233 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
11234 if (DepKind == OMPC_DEPEND_sink) {
11235 if (DepCounter >= TotalDepCount) {
11236 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11248 if (CurContext->isDependentContext()) {
11250 Vars.push_back(RefExpr);
11253 SimpleExpr = SimpleExpr->IgnoreImplicit();
11256 Expr *LHS = SimpleExpr;
11257 Expr *RHS =
nullptr;
11258 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11260 OOLoc = BO->getOperatorLoc();
11263 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11264 OOK = OCE->getOperator();
11265 OOLoc = OCE->getOperatorLoc();
11268 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11269 OOK = MCE->getMethodDecl()
11272 .getCXXOverloadedOperator();
11273 OOLoc = MCE->getCallee()->getExprLoc();
11283 Vars.push_back(RefExpr);
11289 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
11290 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11294 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11295 RHS, OMPC_depend,
false);
11299 if (!CurContext->isDependentContext() &&
11300 DSAStack->getParentOrderedRegionParam() &&
11301 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
11303 DepCounter.getZExtValue());
11305 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11308 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11312 OpsOffs.push_back({RHS, OOK});
11315 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11319 .getNonReferenceType()
11320 ->isPointerType() &&
11321 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11322 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11323 << RefExpr->getSourceRange();
11326 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11327 getDiagnostics().setSuppressAllDiagnostics(
true);
11328 ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
11329 RefExpr->IgnoreParenImpCasts());
11330 getDiagnostics().setSuppressAllDiagnostics(Suppress);
11331 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11332 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11333 << RefExpr->getSourceRange();
11337 Vars.push_back(RefExpr->IgnoreParenImpCasts());
11340 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11341 TotalDepCount > VarList.size() &&
11342 DSAStack->getParentOrderedRegionParam() &&
11343 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11344 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
11345 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11347 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11352 DepKind, DepLoc, ColonLoc, Vars);
11353 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
11354 DSAStack->addDoacrossDependClause(
C, OpsOffs);
11361 Expr *ValExpr = Device;
11362 Stmt *HelperValStmt =
nullptr;
11373 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
11374 ValExpr = MakeFullExpr(ValExpr).get();
11375 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11376 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11380 return new (Context)
11381 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc);
11385 DSAStackTy *Stack,
QualType QTy) {
11388 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
11405 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11406 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
11407 return ATy->getSize().getSExtValue() != 1;
11412 assert(OASE &&
"Expecting array section if not an array subscript.");
11413 auto *LowerBound = OASE->getLowerBound();
11414 auto *Length = OASE->getLength();
11419 llvm::APSInt ConstLowerBound;
11420 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.
getASTContext()))
11422 if (ConstLowerBound.getSExtValue())
11441 llvm::APSInt ConstLength;
11442 if (!Length->EvaluateAsInt(ConstLength, SemaRef.
getASTContext()))
11445 return CATy->
getSize().getSExtValue() != ConstLength.getSExtValue();
11458 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11461 assert(OASE &&
"Expecting array section if not an array subscript.");
11462 auto *Length = OASE->getLength();
11468 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
11469 return ATy->getSize().getSExtValue() != 1;
11475 llvm::APSInt ConstLength;
11476 if (!Length->EvaluateAsInt(ConstLength, SemaRef.
getASTContext()))
11479 return ConstLength.getSExtValue() != 1;
11512 Expr *RelevantExpr =
nullptr;
11531 bool AllowUnitySizeArraySection =
true;
11532 bool AllowWholeSizeArraySection =
true;
11534 while (!RelevantExpr) {
11537 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11538 if (!isa<VarDecl>(CurE->getDecl()))
11541 RelevantExpr = CurE;
11545 AllowUnitySizeArraySection =
false;
11546 AllowWholeSizeArraySection =
false;
11549 CurComponents.emplace_back(CurE, CurE->getDecl());
11550 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
11553 if (isa<CXXThisExpr>(BaseE))
11555 RelevantExpr = CurE;
11559 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11561 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11562 << CurE->getSourceRange();
11570 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11575 if (FD->isBitField()) {
11577 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11589 QualType CurType = BaseE->getType().getNonReferenceType();
11596 if (RT->isUnionType()) {
11598 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
11599 << CurE->getSourceRange();
11613 AllowUnitySizeArraySection =
false;
11614 AllowWholeSizeArraySection =
false;
11617 CurComponents.emplace_back(CurE, FD);
11618 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11623 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
11624 << 0 << CurE->getSourceRange();
11635 AllowWholeSizeArraySection =
false;
11638 CurComponents.emplace_back(CurE,
nullptr);
11639 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11640 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
11655 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
11656 << 0 << CurE->getSourceRange();
11665 if (AllowWholeSizeArraySection) {
11672 if (NotWhole || IsPointer)
11673 AllowWholeSizeArraySection =
false;
11674 }
else if (AllowUnitySizeArraySection && NotUnity) {
11678 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
11679 << CurE->getSourceRange();
11684 CurComponents.emplace_back(CurE,
nullptr);
11689 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
11696 return RelevantExpr;
11703 bool CurrentRegionOnly,
11714 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
11715 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
11716 "Map clause expression with unexpected base!");
11719 bool IsEnclosedByDataEnvironmentExpr =
false;
11720 const Expr *EnclosingExpr =
nullptr;
11722 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
11723 VD, CurrentRegionOnly,
11728 assert(!StackComponents.empty() &&
11729 "Map clause expression with no components!");
11730 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
11731 "Map clause expression with unexpected base!");
11734 auto *RE = StackComponents.front().getAssociatedExpression();
11740 auto CI = CurComponents.rbegin();
11741 auto CE = CurComponents.rend();
11742 auto SI = StackComponents.rbegin();
11743 auto SE = StackComponents.rend();
11744 for (; CI != CE && SI != SE; ++CI, ++SI) {
11749 if (CurrentRegionOnly &&
11750 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
11751 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
11752 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
11753 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
11754 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
11755 diag::err_omp_multiple_array_items_in_map_clause)
11756 << CI->getAssociatedExpression()->getSourceRange();
11757 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
11758 diag::note_used_here)
11759 << SI->getAssociatedExpression()->getSourceRange();
11764 if (CI->getAssociatedExpression()->getStmtClass() !=
11765 SI->getAssociatedExpression()->getStmtClass())
11769 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
11775 for (; SI != SE; ++SI) {
11778 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
11779 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
11780 }
else if (
auto *OASE = dyn_cast<OMPArraySectionExpr>(
11781 SI->getAssociatedExpression())) {
11788 SemaRef, SI->getAssociatedExpression(), Type))
11798 if (CI == CE && SI == SE) {
11799 if (CurrentRegionOnly) {
11800 if (CKind == OMPC_map)
11801 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11803 assert(CKind == OMPC_to || CKind == OMPC_from);
11804 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11807 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
11808 << RE->getSourceRange();
11813 IsEnclosedByDataEnvironmentExpr =
true;
11819 std::prev(CI)->getAssociatedDeclaration()->getType();
11821 std::prev(CI)->getAssociatedExpression()->getExprLoc();
11840 if (CI == CE || SI == SE) {
11843 diag::err_omp_pointer_mapped_along_with_derived_section)
11846 assert(CI != CE && SI != SE);
11847 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
11850 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
11851 << RE->getSourceRange();
11860 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
11861 if (CKind == OMPC_map)
11862 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11864 assert(CKind == OMPC_to || CKind == OMPC_from);
11865 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11868 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
11869 << RE->getSourceRange();
11875 if (!CurrentRegionOnly && SI != SE)
11876 EnclosingExpr = RE;
11880 IsEnclosedByDataEnvironmentExpr |=
11881 (!CurrentRegionOnly && CI != CE && SI == SE);
11886 if (CurrentRegionOnly)
11900 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
11902 diag::err_omp_original_storage_is_shared_and_does_not_contain)
11915 struct MappableVarListInfo final {
11928 VarComponents.reserve(VarList.size());
11929 VarBaseDeclarations.reserve(VarList.size());
11944 bool IsMapTypeImplicit =
false) {
11946 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
11947 "Unexpected clause kind with mappable expressions!");
11955 for (
auto &RE : MVLI.VarList) {
11956 assert(RE &&
"Null expr in omp to/from/map clause");
11959 auto *VE = RE->IgnoreParenLValueCasts();
11961 if (VE->isValueDependent() || VE->isTypeDependent() ||
11962 VE->isInstantiationDependent() ||
11963 VE->containsUnexpandedParameterPack()) {
11966 MVLI.ProcessedVarList.push_back(RE);
11970 auto *SimpleExpr = RE->IgnoreParenCasts();
11972 if (!RE->IgnoreParenImpCasts()->isLValue()) {
11974 diag::err_omp_expected_named_var_member_or_array_expression)
11975 << RE->getSourceRange();
11989 assert(!CurComponents.empty() &&
11990 "Invalid mappable expression information.");
11995 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
11996 assert(CurDeclaration &&
"Null decl on map clause.");
11998 CurDeclaration->isCanonicalDecl() &&
11999 "Expecting components to have associated only canonical declarations.");
12001 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
12002 auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
12004 assert((VD || FD) &&
"Only variables or fields are expected here!");
12011 if (VD && DSAS->isThreadPrivate(VD)) {
12012 auto DVar = DSAS->getTopDSA(VD,
false);
12013 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12028 true, CurComponents, CKind))
12030 if (CKind == OMPC_map &&
12032 false, CurComponents, CKind))
12039 QualType Type = CurDeclaration->getType().getNonReferenceType();
12049 if (CKind == OMPC_map) {
12055 if (DKind == OMPD_target_enter_data &&
12056 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12057 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12058 << (IsMapTypeImplicit ? 1 : 0)
12068 if (DKind == OMPD_target_exit_data &&
12069 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12070 MapType == OMPC_MAP_delete)) {
12071 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12072 << (IsMapTypeImplicit ? 1 : 0)
12081 if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
12082 DKind == OMPD_target_teams_distribute ||
12083 DKind == OMPD_target_teams_distribute_parallel_for ||
12084 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
12085 DKind == OMPD_target_teams_distribute_simd) && VD) {
12086 auto DVar = DSAS->getTopDSA(VD,
false);
12088 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12099 MVLI.ProcessedVarList.push_back(RE);
12103 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12110 MVLI.VarComponents.back().append(CurComponents.begin(),
12111 CurComponents.end());
12112 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 12123 MappableVarListInfo MVLI(VarList);
12125 MapType, IsMapTypeImplicit);
12130 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12131 MVLI.VarComponents, MapTypeModifier, MapType,
12132 IsMapTypeImplicit, MapLoc);
12139 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
12140 if (ReductionType.isNull())
12147 if (ReductionType.hasQualifiers()) {
12148 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12152 if (ReductionType->isFunctionType()) {
12153 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12156 if (ReductionType->isReferenceType()) {
12157 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12160 if (ReductionType->isArrayType()) {
12161 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12164 return ReductionType;
12169 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12172 Decls.reserve(ReductionTypes.size());
12175 forRedeclarationInCurContext());
12180 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12182 bool InCompoundScope =
true;
12183 if (S !=
nullptr) {
12189 LookupName(Lookup, S);
12190 FilterLookupForScope(Lookup, DC, S,
false,
12192 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12194 while (Filter.hasNext()) {
12195 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12196 if (InCompoundScope) {
12197 auto I = UsedAsPrevious.find(PrevDecl);
12198 if (I == UsedAsPrevious.end())
12199 UsedAsPrevious[PrevDecl] =
false;
12200 if (
auto *D = PrevDecl->getPrevDeclInScope())
12201 UsedAsPrevious[D] =
true;
12203 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12204 PrevDecl->getLocation();
12207 if (InCompoundScope) {
12208 for (
auto &PrevData : UsedAsPrevious) {
12209 if (!PrevData.second) {
12210 PrevDRD = PrevData.first;
12215 }
else if (PrevDeclInScope !=
nullptr) {
12216 auto *PrevDRDInScope = PrevDRD =
12217 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12219 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12221 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12222 }
while (PrevDRDInScope !=
nullptr);
12224 for (
auto &TyData : ReductionTypes) {
12225 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12226 bool Invalid =
false;
12227 if (I != PreviousRedeclTypes.end()) {
12228 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12230 Diag(I->second, diag::note_previous_definition);
12233 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12235 Name, TyData.first, PrevDRD);
12237 DRD->setAccess(AS);
12238 Decls.push_back(DRD);
12240 DRD->setInvalidDecl();
12245 return DeclGroupPtrTy::make(
12250 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12253 PushFunctionScope();
12254 getCurFunction()->setHasBranchProtectedScope();
12255 getCurFunction()->setHasOMPDeclareReductionCombiner();
12258 PushDeclContext(S, DRD);
12262 PushExpressionEvaluationContext(
12263 ExpressionEvaluationContext::PotentiallyEvaluated);
12265 QualType ReductionType = DRD->getType();
12282 if (S !=
nullptr) {
12283 PushOnScopeChains(OmpInParm, S);
12284 PushOnScopeChains(OmpOutParm, S);
12286 DRD->addDecl(OmpInParm);
12287 DRD->addDecl(OmpOutParm);
12292 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12293 DiscardCleanupsInEvaluationContext();
12294 PopExpressionEvaluationContext();
12297 PopFunctionScopeInfo();
12299 if (Combiner !=
nullptr)
12300 DRD->setCombiner(Combiner);
12302 DRD->setInvalidDecl();
12306 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12309 PushFunctionScope();
12310 getCurFunction()->setHasBranchProtectedScope();
12313 PushDeclContext(S, DRD);
12317 PushExpressionEvaluationContext(
12318 ExpressionEvaluationContext::PotentiallyEvaluated);
12320 QualType ReductionType = DRD->getType();
12327 auto *OmpPrivParm =
12335 auto *OmpOrigParm =
12337 if (S !=
nullptr) {
12338 PushOnScopeChains(OmpPrivParm, S);
12339 PushOnScopeChains(OmpOrigParm, S);
12341 DRD->addDecl(OmpPrivParm);
12342 DRD->addDecl(OmpOrigParm);
12344 return OmpPrivParm;
12349 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12350 DiscardCleanupsInEvaluationContext();
12351 PopExpressionEvaluationContext();
12354 PopFunctionScopeInfo();
12356 if (Initializer !=
nullptr) {
12358 }
else if (OmpPrivParm->
hasInit()) {
12359 DRD->setInitializer(OmpPrivParm->
getInit(),
12364 DRD->setInvalidDecl();
12370 for (
auto *D : DeclReductions.
get()) {
12372 auto *DRD = cast<OMPDeclareReductionDecl>(D);
12374 PushOnScopeChains(DRD, S,
false);
12378 return DeclReductions;
12385 Expr *ValExpr = NumTeams;
12386 Stmt *HelperValStmt =
nullptr;
12397 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12398 ValExpr = MakeFullExpr(ValExpr).get();
12399 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12400 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12405 StartLoc, LParenLoc, EndLoc);
12412 Expr *ValExpr = ThreadLimit;
12413 Stmt *HelperValStmt =
nullptr;
12424 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12425 ValExpr = MakeFullExpr(ValExpr).get();
12426 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12427 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12432 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12439 Expr *ValExpr = Priority;
12454 Expr *ValExpr = Grainsize;
12470 Expr *ValExpr = NumTasks;
12488 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12491 return new (Context)
12500 std::string Values;
12504 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12508 Expr *ValExpr = ChunkSize;
12509 Stmt *HelperValStmt =
nullptr;
12516 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12520 ValExpr = Val.
get();
12527 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12528 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12533 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12535 !CurContext->isDependentContext()) {
12536 ValExpr = MakeFullExpr(ValExpr).get();
12537 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12538 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12544 return new (Context)
12546 Kind, ValExpr, HelperValStmt);
12554 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12558 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12560 OMPC_DEFAULTMAP_MODIFIER_tofrom);
12564 OMPC_DEFAULTMAP_scalar);
12568 Diag(Loc, diag::err_omp_unexpected_clause_value)
12572 DSAStack->setDefaultDMAToFromScalar(StartLoc);
12574 return new (Context)
12579 DeclContext *CurLexicalContext = getCurLexicalContext();
12583 !isa<CXXRecordDecl>(CurLexicalContext) &&
12584 !isa<ClassTemplateDecl>(CurLexicalContext) &&
12585 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12586 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12587 Diag(Loc, diag::err_omp_region_not_file_context);
12590 if (IsInOpenMPDeclareTargetContext) {
12591 Diag(Loc, diag::err_omp_enclosed_declare_target);
12595 IsInOpenMPDeclareTargetContext =
true;
12600 assert(IsInOpenMPDeclareTargetContext &&
12601 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12603 IsInOpenMPDeclareTargetContext =
false;
12609 OMPDeclareTargetDeclAttr::MapTypeTy MT,
12612 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
12620 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr,
12621 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
12622 CTK_ErrorRecovery)) {
12623 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12625 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
12634 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12638 if (!ND->
hasAttr<OMPDeclareTargetDeclAttr>()) {
12639 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
12642 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
12643 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Id.
getLoc());
12644 }
else if (ND->
getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
12645 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
12656 Decl *LD =
nullptr;
12657 if (isa<TagDecl>(D)) {
12659 }
else if (isa<VarDecl>(D)) {
12664 if (cast<VarDecl>(D)->isImplicit()) {
12665 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12666 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
12669 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12673 }
else if (isa<FunctionDecl>(D)) {
12675 if (cast<FunctionDecl>(D)->hasBody(FD))
12682 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12683 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
12686 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12692 if (LD && !LD->
hasAttr<OMPDeclareTargetDeclAttr>() &&
12693 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
12696 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
12697 SemaRef.
Diag(SL, diag::note_used_here) << SR;
12701 if (isa<FunctionDecl>(DC) &&
12702 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
12710 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
12711 SemaRef.
Diag(SL, diag::note_used_here) << SR;
12714 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12715 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
12718 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12723 Sema &SemaRef, DSAStackTy *Stack,
12725 if (VD->
hasAttr<OMPDeclareTargetDeclAttr>())
12739 if (
VarDecl *VD = dyn_cast<VarDecl>(D)) {
12740 if (
DSAStack->isThreadPrivate(VD)) {
12741 Diag(SL, diag::err_omp_threadprivate_in_target);
12746 if (
ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
12752 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
12753 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12754 Context, OMPDeclareTargetDeclAttr::MT_To);
12757 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
12763 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12764 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12765 OMPDeclareTargetDeclAttr::MT_Link)) {
12766 assert(IdLoc.
isValid() &&
"Source location is expected");
12767 Diag(IdLoc, diag::err_omp_function_in_link_clause);
12768 Diag(FD->getLocation(), diag::note_defined_here) << FD;
12774 if (!D->
hasAttr<OMPDeclareTargetDeclAttr>() &&
12775 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
12776 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12777 Context, OMPDeclareTargetDeclAttr::MT_To);
12780 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12791 MappableVarListInfo MVLI(VarList);
12793 if (MVLI.ProcessedVarList.empty())
12797 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12798 MVLI.VarComponents);
12805 MappableVarListInfo MVLI(VarList);
12807 if (MVLI.ProcessedVarList.empty())
12811 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12812 MVLI.VarComponents);
12819 MappableVarListInfo MVLI(VarList);
12823 for (
auto &RefExpr : VarList) {
12824 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
12827 Expr *SimpleRefExpr = RefExpr;
12831 MVLI.ProcessedVarList.push_back(RefExpr);
12832 PrivateCopies.push_back(
nullptr);
12833 Inits.push_back(
nullptr);
12842 auto *VD = dyn_cast<
VarDecl>(D);
12846 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
12847 << 0 << RefExpr->getSourceRange();
12854 if (VDPrivate->isInvalidDecl())
12857 CurContext->addDecl(VDPrivate);
12859 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12863 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
12865 RefExpr->getExprLoc());
12866 AddInitializerToDecl(VDPrivate,
12867 DefaultLvalueConversion(VDInitRefExpr).
get(),
12875 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
12876 PrivateCopies.push_back(VDPrivateRefExpr);
12877 Inits.push_back(VDInitRefExpr);
12882 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12886 MVLI.VarBaseDeclarations.push_back(D);
12887 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12888 MVLI.VarComponents.back().push_back(
12892 if (MVLI.ProcessedVarList.empty())
12896 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12897 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
12904 MappableVarListInfo MVLI(VarList);
12905 for (
auto &RefExpr : VarList) {
12906 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
12909 Expr *SimpleRefExpr = RefExpr;
12913 MVLI.ProcessedVarList.push_back(RefExpr);
12923 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
12924 << 0 << RefExpr->getSourceRange();
12930 auto DVar =
DSAStack->getTopDSA(D,
false);
12932 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12940 Expr *ConflictExpr;
12941 if (
DSAStack->checkMappableExprComponentListsForDecl(
12946 ConflictExpr = R.front().getAssociatedExpression();
12949 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
12958 DSAStack->addMappableExpressionComponents(
12959 D, MC, OMPC_is_device_ptr);
12962 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
12967 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
12968 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
12969 "Unexpected device pointer expression!");
12970 MVLI.VarBaseDeclarations.push_back(
12971 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
12972 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12973 MVLI.VarComponents.back().push_back(MC);
12976 if (MVLI.ProcessedVarList.empty())
12980 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12981 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 sheduled '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 sheduled 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)
An instance of this class is created to represent 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.
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.
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)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
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 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.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
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...
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.
ActionResult< Expr * > ExprResult
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 isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is captured by 'target' directive.
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
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...
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
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.
bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
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.
QualType withConst() const
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.
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.
static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
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 unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
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>'.
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...
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)
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
static const NamedDecl * getDefinition(const Decl *D)
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
static Expr * CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
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
getIdentifier - 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.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
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.
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.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
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...
static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
VerifyDiagnosticConsumer::Directive Directive
DeclClass * getAsSingle() const
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
Represents the results of name lookup.
bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level)
Return true if the provided declaration VD should be captured by reference.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' 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.
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.
static ValueDecl * getCanonicalDecl(ValueDecl *D)
SourceLocation getLocStart() const
Returns the starting location of the clause.
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)
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
Concrete class used by the front-end to report problems and issues.
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
SmallVector< MappableComponent, 8 > MappableExprComponentList
This represents 'default' clause in the '#pragma omp ...' directive.
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...
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
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'.
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.
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.
static T filterLookupForUDR(SmallVectorImpl< UnresolvedSet< 8 >> &Lookups, const llvm::function_ref< T(ValueDecl *)> &Gen)
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.
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)
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
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 sheduled 'omp for' loops.
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
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.
static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
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 OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
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.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
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
hasLocalStorage - 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.
const FunctionProtoType * T
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 isOpenMPPrivateDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is used in 'private' clause.
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.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
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.
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
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
SourceLocation getBeginLoc() const
DeclContext * getDeclContext()
void setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
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.
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.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
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.
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...
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
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.
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 sheduled omp loops for outer loop in combined constructs (e...
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
The result type of a method or function.
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.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
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.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement...
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
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...
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)...
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< Expr *, DeclRefExpr *> &Captures)
Build 'VarRef = Start.
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...
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
ASTContext & getASTContext() const
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
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.
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.
VarDecl * IsOpenMPCapturedDecl(ValueDecl *D)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents 'schedule' clause in the '#pragma omp ...' directive.
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.
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()
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.
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.
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< Expr *, DeclRefExpr *> *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
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 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)
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.
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...
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement...
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)
SourceLocation getLocStart() const LLVM_READONLY
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.
SourceLocation getLocEnd() const
Returns the ending location of the clause.
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
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)
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
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 CheckOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
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.
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...
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 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'.
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 bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
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.
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'.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
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.
static Expr * getExprAsWritten(Expr *E)
bool isStaticLocal() const
isStaticLocal - 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.
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.
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)
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
void addDecl(Decl *D)
Add the declaration D into this context.
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)
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
const Type * getTypePtrOrNull() const
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...
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...
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.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
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'.
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.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
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)...
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...
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
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
getName - Get the name of identifier for this declaration as a StringRef.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
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 OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
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.
NamedDecl - This represents a decl with a name.
static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
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 getLocStart() const LLVM_READONLY
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.
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.
bool getSuppressAllDiagnostics() const
void clear()
Clears out any current state.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Attr - This represents one attribute.
SourceLocation getLocation() const
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.
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].