32 #include "llvm/ADT/PointerEmbeddedInt.h" 33 using namespace clang;
65 const Expr *RefExpr =
nullptr;
68 DSAVarData() =
default;
72 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
73 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
75 using OperatorOffsetTy =
77 using DoacrossDependMapTy =
78 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
85 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
88 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
89 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
90 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
91 using LoopControlVariablesMapTy =
92 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
95 struct MappedExprComponentTy {
99 using MappedExprComponentsTy =
100 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
101 using CriticalsWithHintsTy =
102 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
103 struct ReductionData {
104 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
106 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
107 ReductionData() =
default;
114 ReductionOp = RefExpr;
117 using DeclReductionMapTy =
118 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
120 struct SharingMapTy {
121 DeclSAMapTy SharingMap;
122 DeclReductionMapTy ReductionMap;
123 AlignedMapTy AlignedMap;
124 MappedExprComponentsTy MappedExprComponents;
125 LoopControlVariablesMapTy LCVMap;
132 Scope *CurScope =
nullptr;
137 DoacrossDependMapTy DoacrossDepends;
142 unsigned AssociatedLoops = 1;
143 const Decl *PossiblyLoopCounter =
nullptr;
144 bool NowaitRegion =
false;
145 bool CancelRegion =
false;
146 bool LoopStart =
false;
149 Expr *TaskgroupReductionRef =
nullptr;
153 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
155 SharingMapTy() =
default;
161 DeclSAMapTy Threadprivates;
168 bool ForceCapturing =
false;
171 bool ForceCaptureByReferenceInTargetExecutable =
false;
172 CriticalsWithHintsTy Criticals;
174 using iterator = StackTy::const_reverse_iterator;
176 DSAVarData getDSA(iterator &Iter,
ValueDecl *D)
const;
179 bool isOpenMPLocal(
VarDecl *D, iterator Iter)
const;
181 bool isStackEmpty()
const {
182 return Stack.empty() ||
183 Stack.back().second != CurrentNonCapturingFunctionScope ||
184 Stack.back().first.empty();
191 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
193 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
195 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
196 return ClauseKindMode;
200 bool isForceVarCapturing()
const {
return ForceCapturing; }
201 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
203 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
204 ForceCaptureByReferenceInTargetExecutable = V;
206 bool isForceCaptureByReferenceInTargetExecutable()
const {
207 return ForceCaptureByReferenceInTargetExecutable;
213 Stack.back().second != CurrentNonCapturingFunctionScope)
214 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
215 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
216 Stack.back().first.back().DefaultAttrLoc = Loc;
220 assert(!Stack.back().first.empty() &&
221 "Data-sharing attributes stack is empty!");
222 Stack.back().first.pop_back();
228 "Expected loop-based directive.");
229 Stack.back().first.back().LoopStart =
true;
234 "Expected loop-based directive.");
235 Stack.back().first.back().LoopStart =
false;
238 bool isLoopStarted()
const {
240 "Expected loop-based directive.");
241 return !Stack.back().first.back().LoopStart;
244 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
245 Stack.back().first.back().PossiblyLoopCounter =
249 const Decl *getPossiblyLoopCunter()
const {
250 return Stack.back().first.back().PossiblyLoopCounter;
253 void pushFunction() {
255 assert(!isa<CapturingScopeInfo>(CurFnScope));
256 CurrentNonCapturingFunctionScope = CurFnScope;
260 if (!Stack.empty() && Stack.back().second == OldFSI) {
261 assert(Stack.back().first.empty());
264 CurrentNonCapturingFunctionScope =
nullptr;
266 if (!isa<CapturingScopeInfo>(FSI)) {
267 CurrentNonCapturingFunctionScope = FSI;
276 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
279 if (I != Criticals.end())
281 return std::make_pair(
nullptr, llvm::APSInt());
294 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
299 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
302 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
315 const Expr *ReductionRef);
321 Expr *&TaskgroupDescriptor)
const;
326 const Expr *&ReductionRef,
327 Expr *&TaskgroupDescriptor)
const;
329 Expr *getTaskgroupReductionRef()
const {
330 assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
331 "taskgroup reference expression requested for non taskgroup " 333 return Stack.back().first.back().TaskgroupReductionRef;
337 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
338 return Stack.back().first[
Level].TaskgroupReductionRef &&
339 cast<DeclRefExpr>(Stack.back().first[
Level].TaskgroupReductionRef)
345 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
347 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
354 bool FromParent)
const;
362 bool FromParent)
const;
368 unsigned Level,
bool NotLastprivate =
false)
const;
372 bool hasExplicitDirective(
374 unsigned Level)
const;
378 const llvm::function_ref<
bool(
381 bool FromParent)
const;
385 return isStackEmpty() ?
OMPD_unknown : Stack.back().first.back().Directive;
389 assert(!isStackEmpty() &&
"No directive at specified level.");
390 return Stack.back().first[
Level].Directive;
394 if (isStackEmpty() || Stack.back().first.size() == 1)
396 return std::next(Stack.back().first.rbegin())->
Directive;
401 RequiresDecls.push_back(RD);
407 bool IsDuplicate =
false;
410 for (
const OMPClause *CPrev : D->clauselists()) {
411 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
412 SemaRef.
Diag(CNew->getBeginLoc(),
413 diag::err_omp_requires_clause_redeclaration)
415 SemaRef.
Diag(CPrev->getBeginLoc(),
416 diag::note_omp_requires_previous_clause)
428 assert(!isStackEmpty());
429 Stack.back().first.back().DefaultAttr = DSA_none;
430 Stack.back().first.back().DefaultAttrLoc = Loc;
434 assert(!isStackEmpty());
435 Stack.back().first.back().DefaultAttr = DSA_shared;
436 Stack.back().first.back().DefaultAttrLoc = Loc;
440 assert(!isStackEmpty());
441 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
442 Stack.back().first.back().DefaultMapAttrLoc = Loc;
446 return isStackEmpty() ? DSA_unspecified
447 : Stack.back().first.back().DefaultAttr;
451 : Stack.back().first.back().DefaultAttrLoc;
454 return isStackEmpty() ? DMA_unspecified
455 : Stack.back().first.back().DefaultMapAttr;
458 return Stack.back().first[
Level].DefaultMapAttr;
462 : Stack.back().first.back().DefaultMapAttrLoc;
466 bool isThreadPrivate(
VarDecl *D) {
467 const DSAVarData DVar = getTopDSA(D,
false);
472 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
474 assert(!isStackEmpty());
476 Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
478 Stack.back().first.back().OrderedRegion.reset();
482 bool isOrderedRegion()
const {
485 return Stack.back().first.rbegin()->OrderedRegion.hasValue();
488 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
489 if (isStackEmpty() ||
490 !Stack.back().first.rbegin()->OrderedRegion.hasValue())
491 return std::make_pair(
nullptr,
nullptr);
492 return Stack.back().first.rbegin()->OrderedRegion.getValue();
496 bool isParentOrderedRegion()
const {
497 if (isStackEmpty() || Stack.back().first.size() == 1)
499 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
502 std::pair<const Expr *, OMPOrderedClause *>
503 getParentOrderedRegionParam()
const {
504 if (isStackEmpty() || Stack.back().first.size() == 1 ||
505 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
506 return std::make_pair(
nullptr,
nullptr);
507 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
510 void setNowaitRegion(
bool IsNowait =
true) {
511 assert(!isStackEmpty());
512 Stack.back().first.back().NowaitRegion = IsNowait;
516 bool isParentNowaitRegion()
const {
517 if (isStackEmpty() || Stack.back().first.size() == 1)
519 return std::next(Stack.back().first.rbegin())->NowaitRegion;
522 void setParentCancelRegion(
bool Cancel =
true) {
523 if (!isStackEmpty() && Stack.back().first.size() > 1) {
524 auto &StackElemRef = *std::next(Stack.back().first.rbegin());
525 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
529 bool isCancelRegion()
const {
530 return isStackEmpty() ?
false : Stack.back().first.back().CancelRegion;
534 void setAssociatedLoops(
unsigned Val) {
535 assert(!isStackEmpty());
536 Stack.back().first.back().AssociatedLoops = Val;
539 unsigned getAssociatedLoops()
const {
540 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
546 if (!isStackEmpty() && Stack.back().first.size() > 1) {
547 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
552 bool hasInnerTeamsRegion()
const {
553 return getInnerTeamsRegionLoc().
isValid();
558 : Stack.back().first.back().InnerTeamsRegionLoc;
561 Scope *getCurScope()
const {
562 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
566 : Stack.back().first.back().ConstructLoc;
571 bool checkMappableExprComponentListsForDecl(
572 const ValueDecl *VD,
bool CurrentRegionOnly,
573 const llvm::function_ref<
579 auto SI = Stack.back().first.rbegin();
580 auto SE = Stack.back().first.rend();
585 if (CurrentRegionOnly)
590 for (; SI != SE; ++SI) {
591 auto MI = SI->MappedExprComponents.find(VD);
592 if (MI != SI->MappedExprComponents.end())
594 MI->second.Components)
595 if (Check(L, MI->second.Kind))
603 bool checkMappableExprComponentListsForDeclAtLevel(
605 const llvm::function_ref<
612 auto StartI = Stack.back().first.begin();
613 auto EndI = Stack.back().first.end();
616 std::advance(StartI, Level);
618 auto MI = StartI->MappedExprComponents.find(VD);
619 if (MI != StartI->MappedExprComponents.end())
621 MI->second.Components)
622 if (Check(L, MI->second.Kind))
629 void addMappableExpressionComponents(
633 assert(!isStackEmpty() &&
634 "Not expecting to retrieve components from a empty stack!");
635 MappedExprComponentTy &MEC =
636 Stack.back().first.back().MappedExprComponents[VD];
638 MEC.Components.resize(MEC.Components.size() + 1);
639 MEC.Components.back().append(Components.begin(), Components.end());
640 MEC.Kind = WhereFoundClauseKind;
643 unsigned getNestingLevel()
const {
644 assert(!isStackEmpty());
645 return Stack.back().first.size() - 1;
648 const OperatorOffsetTy &OpsOffs) {
649 assert(!isStackEmpty() && Stack.back().first.size() > 1);
650 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
652 StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
654 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
655 getDoacrossDependClauses()
const {
656 assert(!isStackEmpty());
657 const SharingMapTy &StackElem = Stack.back().first.back();
659 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
660 return llvm::make_range(Ref.begin(), Ref.end());
662 return llvm::make_range(StackElem.DoacrossDepends.end(),
663 StackElem.DoacrossDepends.end());
667 void addMappedClassesQualTypes(
QualType QT) {
668 SharingMapTy &StackElem = Stack.back().first.back();
669 StackElem.MappedClassesQualTypes.insert(QT);
673 bool isClassPreviouslyMapped(
QualType QT)
const {
674 const SharingMapTy &StackElem = Stack.back().first.back();
675 return StackElem.MappedClassesQualTypes.count(QT) != 0;
691 if (
const auto *FE = dyn_cast<FullExpr>(E))
692 E = FE->getSubExpr();
694 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
695 E = MTE->GetTemporaryExpr();
697 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
698 E = Binder->getSubExpr();
700 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
701 E = ICE->getSubExprAsWritten();
710 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
711 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
712 D = ME->getMemberDecl();
713 const auto *VD = dyn_cast<
VarDecl>(D);
720 FD = FD->getCanonicalDecl();
731 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
734 auto *VD = dyn_cast<
VarDecl>(D);
737 if (isStackEmpty() || Iter == Stack.back().first.rend()) {
743 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
744 DVar.CKind = OMPC_shared;
750 if (VD && VD->hasGlobalStorage())
751 DVar.CKind = OMPC_shared;
755 DVar.CKind = OMPC_shared;
764 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
765 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
766 DVar.CKind = OMPC_private;
770 DVar.DKind = Iter->Directive;
773 if (Iter->SharingMap.count(D)) {
774 const DSAInfo &Data = Iter->SharingMap.lookup(D);
775 DVar.RefExpr = Data.RefExpr.getPointer();
776 DVar.PrivateCopy = Data.PrivateCopy;
777 DVar.CKind = Data.Attributes;
778 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
786 switch (Iter->DefaultAttr) {
788 DVar.CKind = OMPC_shared;
789 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
793 case DSA_unspecified:
798 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
801 DVar.CKind = OMPC_shared;
812 iterator I = Iter, E = Stack.back().first.rend();
820 DVarTemp = getDSA(I, D);
821 if (DVarTemp.CKind != OMPC_shared) {
822 DVar.RefExpr =
nullptr;
823 DVar.CKind = OMPC_firstprivate;
826 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
828 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
837 return getDSA(++Iter, D);
842 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
844 SharingMapTy &StackElem = Stack.back().first.back();
845 auto It = StackElem.AlignedMap.find(D);
846 if (It == StackElem.AlignedMap.end()) {
847 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
848 StackElem.AlignedMap[D] = NewDE;
851 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
856 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
858 SharingMapTy &StackElem = Stack.back().first.back();
859 StackElem.LCVMap.try_emplace(
860 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
863 const DSAStackTy::LCDeclInfo
864 DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
865 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
867 const SharingMapTy &StackElem = Stack.back().first.back();
868 auto It = StackElem.LCVMap.find(D);
869 if (It != StackElem.LCVMap.end())
874 const DSAStackTy::LCDeclInfo
875 DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
876 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
877 "Data-sharing attributes stack is empty");
879 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
880 auto It = StackElem.LCVMap.find(D);
881 if (It != StackElem.LCVMap.end())
886 const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
887 assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
888 "Data-sharing attributes stack is empty");
889 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
890 if (StackElem.LCVMap.size() < I)
892 for (
const auto &Pair : StackElem.LCVMap)
893 if (Pair.second.first == I)
902 DSAInfo &Data = Threadprivates[D];
904 Data.RefExpr.setPointer(E);
905 Data.PrivateCopy =
nullptr;
907 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
908 DSAInfo &Data = Stack.back().first.back().SharingMap[D];
909 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
910 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
911 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
912 (isLoopControlVariable(D).first && A == OMPC_private));
913 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
914 Data.RefExpr.setInt(
true);
917 const bool IsLastprivate =
918 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
920 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
921 Data.PrivateCopy = PrivateCopy;
924 Stack.back().first.back().SharingMap[PrivateCopy->
getDecl()];
926 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
927 Data.PrivateCopy =
nullptr;
934 StringRef Name,
const AttrVec *Attrs =
nullptr,
949 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
956 bool RefersToCapture =
false) {
967 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
969 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
970 "Additional reduction info may be specified only for reduction items.");
971 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
972 assert(ReductionData.ReductionRange.isInvalid() &&
973 Stack.back().first.back().Directive == OMPD_taskgroup &&
974 "Additional reduction info may be specified only once for reduction " 976 ReductionData.set(BOK, SR);
977 Expr *&TaskgroupReductionRef =
978 Stack.back().first.back().TaskgroupReductionRef;
979 if (!TaskgroupReductionRef) {
981 SemaRef.Context.VoidPtrTy,
".task_red.");
982 TaskgroupReductionRef =
988 const Expr *ReductionRef) {
990 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
992 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
993 "Additional reduction info may be specified only for reduction items.");
994 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
995 assert(ReductionData.ReductionRange.isInvalid() &&
996 Stack.back().first.back().Directive == OMPD_taskgroup &&
997 "Additional reduction info may be specified only once for reduction " 999 ReductionData.set(ReductionRef, SR);
1000 Expr *&TaskgroupReductionRef =
1001 Stack.back().first.back().TaskgroupReductionRef;
1002 if (!TaskgroupReductionRef) {
1004 SemaRef.Context.VoidPtrTy,
".task_red.");
1005 TaskgroupReductionRef =
1010 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1012 Expr *&TaskgroupDescriptor)
const {
1014 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1015 if (Stack.back().first.empty())
1016 return DSAVarData();
1017 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1018 E = Stack.back().first.rend();
1019 I != E; std::advance(I, 1)) {
1020 const DSAInfo &Data = I->SharingMap.lookup(D);
1021 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1023 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1024 if (!ReductionData.ReductionOp ||
1025 ReductionData.ReductionOp.is<
const Expr *>())
1026 return DSAVarData();
1027 SR = ReductionData.ReductionRange;
1028 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1029 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1030 "expression for the descriptor is not " 1032 TaskgroupDescriptor = I->TaskgroupReductionRef;
1033 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1034 Data.PrivateCopy, I->DefaultAttrLoc);
1036 return DSAVarData();
1039 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1041 Expr *&TaskgroupDescriptor)
const {
1043 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1044 if (Stack.back().first.empty())
1045 return DSAVarData();
1046 for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1047 E = Stack.back().first.rend();
1048 I != E; std::advance(I, 1)) {
1049 const DSAInfo &Data = I->SharingMap.lookup(D);
1050 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1052 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1053 if (!ReductionData.ReductionOp ||
1054 !ReductionData.ReductionOp.is<
const Expr *>())
1055 return DSAVarData();
1056 SR = ReductionData.ReductionRange;
1057 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1058 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1059 "expression for the descriptor is not " 1061 TaskgroupDescriptor = I->TaskgroupReductionRef;
1062 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1063 Data.PrivateCopy, I->DefaultAttrLoc);
1065 return DSAVarData();
1068 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, iterator Iter)
const {
1070 if (!isStackEmpty()) {
1071 iterator I = Iter, E = Stack.back().first.rend();
1072 Scope *TopScope =
nullptr;
1073 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
1078 TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
1079 Scope *CurScope = getCurScope();
1080 while (CurScope != TopScope && !CurScope->
isDeclScope(D))
1082 return CurScope != TopScope;
1088 bool AcceptIfMutable =
true,
1089 bool *IsClassType =
nullptr) {
1097 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1099 RD = CTD->getTemplatedDecl();
1102 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1109 bool AcceptIfMutable =
true,
1110 bool ListItemNotVar =
false) {
1114 unsigned Diag = ListItemNotVar
1115 ? diag::err_omp_const_list_item
1116 : IsClassType ? diag::err_omp_const_not_mutable_variable
1117 : diag::err_omp_const_variable;
1119 if (!ListItemNotVar && D) {
1124 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1132 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1137 auto *VD = dyn_cast<
VarDecl>(D);
1138 auto TI = Threadprivates.find(D);
1139 if (TI != Threadprivates.end()) {
1140 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1144 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1147 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1156 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1157 SemaRef.getLangOpts().OpenMPUseTLS &&
1158 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1160 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1167 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1168 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1169 !isLoopControlVariable(D).first) {
1170 iterator IterTarget =
1171 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1172 [](
const SharingMapTy &Data) {
1175 if (IterTarget != Stack.back().first.rend()) {
1176 iterator ParentIterTarget = std::next(IterTarget, 1);
1177 for (iterator Iter = Stack.back().first.rbegin();
1178 Iter != ParentIterTarget; std::advance(Iter, 1)) {
1179 if (isOpenMPLocal(VD, Iter)) {
1187 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1188 auto DSAIter = IterTarget->SharingMap.find(D);
1189 if (DSAIter != IterTarget->SharingMap.end() &&
1191 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1195 iterator
End = Stack.back().first.rend();
1196 if (!SemaRef.isOpenMPCapturedByRef(
1200 IterTarget->ConstructLoc);
1220 if (VD && VD->isStaticDataMember()) {
1221 DSAVarData DVarTemp = hasDSA(D,
isOpenMPPrivate, MatchesAlways, FromParent);
1222 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1225 DVar.CKind = OMPC_shared;
1231 if (SemaRef.LangOpts.OpenMP <= 31) {
1239 DSAVarData DVarTemp = hasInnermostDSA(
1242 return C == OMPC_firstprivate || C == OMPC_shared;
1244 MatchesAlways, FromParent);
1245 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1248 DVar.CKind = OMPC_shared;
1255 iterator I = Stack.back().first.rbegin();
1256 iterator EndI = Stack.back().first.rend();
1257 if (FromParent && I != EndI)
1259 auto It = I->SharingMap.find(D);
1260 if (It != I->SharingMap.end()) {
1261 const DSAInfo &Data = It->getSecond();
1262 DVar.RefExpr = Data.RefExpr.getPointer();
1263 DVar.PrivateCopy = Data.PrivateCopy;
1264 DVar.CKind = Data.Attributes;
1265 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1266 DVar.DKind = I->Directive;
1272 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1273 bool FromParent)
const {
1274 if (isStackEmpty()) {
1276 return getDSA(I, D);
1279 iterator StartI = Stack.back().first.rbegin();
1280 iterator EndI = Stack.back().first.rend();
1281 if (FromParent && StartI != EndI)
1282 std::advance(StartI, 1);
1283 return getDSA(StartI, D);
1286 const DSAStackTy::DSAVarData
1290 bool FromParent)
const {
1294 iterator I = Stack.back().first.rbegin();
1295 iterator EndI = Stack.back().first.rend();
1296 if (FromParent && I != EndI)
1298 for (; I != EndI; std::advance(I, 1)) {
1299 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
1302 DSAVarData DVar = getDSA(NewI, D);
1303 if (I == NewI && CPred(DVar.CKind))
1309 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1312 bool FromParent)
const {
1316 iterator StartI = Stack.back().first.rbegin();
1317 iterator EndI = Stack.back().first.rend();
1318 if (FromParent && StartI != EndI)
1319 std::advance(StartI, 1);
1320 if (StartI == EndI || !DPred(StartI->Directive))
1322 iterator NewI = StartI;
1323 DSAVarData DVar = getDSA(NewI, D);
1324 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1327 bool DSAStackTy::hasExplicitDSA(
1329 unsigned Level,
bool NotLastprivate)
const {
1333 auto StartI = Stack.back().first.begin();
1334 auto EndI = Stack.back().first.end();
1337 std::advance(StartI, Level);
1338 auto I = StartI->SharingMap.find(D);
1339 if ((I != StartI->SharingMap.end()) &&
1340 I->getSecond().RefExpr.getPointer() &&
1341 CPred(I->getSecond().Attributes) &&
1342 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1345 auto LI = StartI->LCVMap.find(D);
1346 if (LI != StartI->LCVMap.end())
1347 return CPred(OMPC_private);
1351 bool DSAStackTy::hasExplicitDirective(
1353 unsigned Level)
const {
1356 auto StartI = Stack.back().first.begin();
1357 auto EndI = Stack.back().first.end();
1360 std::advance(StartI, Level);
1361 return DPred(StartI->Directive);
1364 bool DSAStackTy::hasDirective(
1368 bool FromParent)
const {
1372 auto StartI = std::next(Stack.back().first.rbegin());
1373 auto EndI = Stack.back().first.rend();
1374 if (FromParent && StartI != EndI)
1375 StartI = std::next(StartI);
1376 for (
auto I = StartI, EE = EndI; I != EE; ++I) {
1377 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1383 void Sema::InitDataSharingAttributesStack() {
1384 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1387 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1389 void Sema::pushOpenMPFunctionRegion() {
1398 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1401 bool IsByRef =
true;
1462 if (Ty->isReferenceType())
1468 bool IsVariableUsedInMapClause =
false;
1469 bool IsVariableAssociatedWithSection =
false;
1471 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1473 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1480 if (WhereFoundClauseKind != OMPC_map)
1483 auto EI = MapExprComponents.rbegin();
1484 auto EE = MapExprComponents.rend();
1486 assert(EI != EE &&
"Invalid map expression!");
1488 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1489 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1495 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1496 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1497 isa<MemberExpr>(EI->getAssociatedExpression())) {
1498 IsVariableAssociatedWithSection =
true;
1507 if (IsVariableUsedInMapClause) {
1510 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1515 (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1516 !Ty->isAnyPointerType()) ||
1517 !Ty->isScalarType() ||
1518 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1524 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1526 ((
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1527 !Ty->isAnyPointerType()) ||
1534 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
1535 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1552 unsigned Sema::getOpenMPNestingLevel()
const {
1553 assert(getLangOpts().OpenMP);
1554 return DSAStack->getNestingLevel();
1559 !
DSAStack->isClauseParsingMode()) ||
1563 return isOpenMPTargetExecutionDirective(K);
1569 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1575 auto *VD = dyn_cast<
VarDecl>(D);
1576 if (VD && !VD->hasLocalStorage()) {
1577 if (isInOpenMPDeclareTargetContext() &&
1578 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1581 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1582 checkDeclIsAllowedInOpenMPTarget(
nullptr, VD);
1584 }
else if (isInOpenMPTargetExecutionDirective()) {
1588 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1595 if (VD && !
DSAStack->isClauseParsingMode()) {
1596 if (
const auto *RD = VD->getType()
1598 .getNonReferenceType()
1599 ->getAsCXXRecordDecl()) {
1600 bool SavedForceCaptureByReferenceInTargetExecutable =
1601 DSAStack->isForceCaptureByReferenceInTargetExecutable();
1602 DSAStack->setForceCaptureByReferenceInTargetExecutable(
true);
1603 if (RD->isLambda()) {
1604 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
1606 RD->getCaptureFields(Captures, ThisCapture);
1609 VarDecl *VD = LC.getCapturedVar();
1613 DSAStackTy::DSAVarData DVarPrivate =
1616 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
1618 !
DSAStack->checkMappableExprComponentListsForDecl(
1621 MappableExprComponentListRef,
1623 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar());
1624 }
else if (LC.getCaptureKind() ==
LCK_This) {
1625 QualType ThisTy = getCurrentThisType();
1628 CheckCXXThisCapture(LC.getLocation());
1632 DSAStack->setForceCaptureByReferenceInTargetExecutable(
1633 SavedForceCaptureByReferenceInTargetExecutable);
1638 (!
DSAStack->isClauseParsingMode() ||
1640 auto &&Info =
DSAStack->isLoopControlVariable(D);
1642 (VD && VD->hasLocalStorage() &&
1643 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
1644 (VD &&
DSAStack->isForceVarCapturing()))
1645 return VD ? VD : Info.second;
1646 DSAStackTy::DSAVarData DVarPrivate =
1649 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1654 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1659 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
1660 unsigned Level)
const {
1663 FunctionScopesIndex -= Regions.size();
1667 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
1673 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1675 if (
DSAStack->getAssociatedLoops() > 0 &&
1677 DSAStack->resetPossibleLoopCounter(D);
1682 DSAStack->isLoopControlVariable(D).first) &&
1690 (
DSAStack->isClauseParsingMode() &&
1691 DSAStack->getClauseParsingMode() == OMPC_private) ||
1697 DSAStack->isTaskgroupReductionRef(D, Level));
1702 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1705 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
1706 const unsigned NewLevel = I - 1;
1709 if (isOpenMPPrivate(K)) {
1717 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1728 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1729 DefaultMapAttributes::DMA_tofrom_scalar)
1730 OMPC = OMPC_firstprivate;
1735 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1739 unsigned Level)
const {
1740 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1743 const auto *VD = dyn_cast<
VarDecl>(D);
1749 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1754 DSAStack->push(DKind, DirName, CurScope, Loc);
1755 PushExpressionEvaluationContext(
1756 ExpressionEvaluationContext::PotentiallyEvaluated);
1773 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1775 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
1777 for (
Expr *DE : Clause->varlists()) {
1778 if (DE->isValueDependent() || DE->isTypeDependent()) {
1779 PrivateCopies.push_back(
nullptr);
1782 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1783 auto *VD = cast<VarDecl>(DRE->getDecl());
1785 const DSAStackTy::DSAVarData DVar =
1787 if (DVar.CKind == OMPC_lastprivate) {
1794 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
1795 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr, DRE);
1796 ActOnUninitializedDecl(VDPrivate);
1800 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
1804 PrivateCopies.push_back(
nullptr);
1808 if (PrivateCopies.size() == Clause->varlist_size())
1809 Clause->setPrivateCopies(PrivateCopies);
1815 DiscardCleanupsInEvaluationContext();
1816 PopExpressionEvaluationContext();
1820 Expr *NumIterations,
Sema &SemaRef,
1821 Scope *S, DSAStackTy *Stack);
1830 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1831 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1833 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1834 return VD->hasGlobalStorage() &&
1847 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
1848 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1850 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1864 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
1872 Id, LookupOrdinaryName, CurScope,
nullptr,
1873 llvm::make_unique<VarDeclFilterCCC>(*
this), CTK_ErrorRecovery)) {
1874 diagnoseTypo(Corrected,
1875 PDiag(Lookup.
empty()
1876 ? diag::err_undeclared_var_use_suggest
1877 : diag::err_omp_expected_var_arg_suggest)
1879 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1882 : diag::err_omp_expected_var_arg)
1896 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1901 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1912 !getCurLexicalContext()->isTranslationUnit()) {
1918 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1933 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1942 (!getCurLexicalContext()->isFileContext() ||
1943 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
1949 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1957 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1963 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1988 CurContext->addDecl(D);
1995 class LocalVarRefChecker final
2001 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2002 if (VD->hasLocalStorage()) {
2004 diag::err_omp_local_var_in_threadprivate_init)
2006 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2007 << VD << VD->getSourceRange();
2013 bool VisitStmt(
const Stmt *S) {
2015 if (Child && Visit(Child))
2020 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
2027 for (
Expr *RefExpr : VarList) {
2028 auto *DE = cast<DeclRefExpr>(RefExpr);
2029 auto *VD = cast<VarDecl>(DE->getDecl());
2033 VD->setReferenced();
2034 VD->markUsed(Context);
2045 if (RequireCompleteType(ILoc, VD->getType(),
2046 diag::err_omp_threadprivate_incomplete_type)) {
2052 if (VD->getType()->isReferenceType()) {
2053 Diag(ILoc, diag::err_omp_ref_type_arg)
2057 Diag(VD->getLocation(),
2058 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2066 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2067 getLangOpts().OpenMPUseTLS &&
2068 getASTContext().getTargetInfo().isTLSSupported())) ||
2069 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2070 !VD->isLocalVarDecl())) {
2071 Diag(ILoc, diag::err_omp_var_thread_local)
2075 Diag(VD->getLocation(),
2076 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2083 if (
const Expr *Init = VD->getAnyInitializer()) {
2084 LocalVarRefChecker Checker(*
this);
2085 if (Checker.Visit(Init))
2089 Vars.push_back(RefExpr);
2091 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2094 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2097 if (!Vars.empty()) {
2109 if (!CurContext->isFileContext()) {
2110 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
2112 D = CheckOMPRequiresDecl(Loc, ClauseList);
2114 CurContext->addDecl(D);
2123 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
2131 const DSAStackTy::DSAVarData &DVar,
2132 bool IsLoopIterVar =
false) {
2134 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2139 PDSA_StaticMemberShared,
2140 PDSA_StaticLocalVarShared,
2141 PDSA_LoopIterVarPrivate,
2142 PDSA_LoopIterVarLinear,
2143 PDSA_LoopIterVarLastprivate,
2144 PDSA_ConstVarShared,
2145 PDSA_GlobalVarShared,
2146 PDSA_TaskVarFirstprivate,
2147 PDSA_LocalVarPrivate,
2149 } Reason = PDSA_Implicit;
2150 bool ReportHint =
false;
2152 auto *VD = dyn_cast<
VarDecl>(D);
2153 if (IsLoopIterVar) {
2154 if (DVar.CKind == OMPC_private)
2155 Reason = PDSA_LoopIterVarPrivate;
2156 else if (DVar.CKind == OMPC_lastprivate)
2157 Reason = PDSA_LoopIterVarLastprivate;
2159 Reason = PDSA_LoopIterVarLinear;
2161 DVar.CKind == OMPC_firstprivate) {
2162 Reason = PDSA_TaskVarFirstprivate;
2163 ReportLoc = DVar.ImplicitDSALoc;
2164 }
else if (VD && VD->isStaticLocal())
2165 Reason = PDSA_StaticLocalVarShared;
2166 else if (VD && VD->isStaticDataMember())
2167 Reason = PDSA_StaticMemberShared;
2168 else if (VD && VD->isFileVarDecl())
2169 Reason = PDSA_GlobalVarShared;
2171 Reason = PDSA_ConstVarShared;
2172 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2174 Reason = PDSA_LocalVarPrivate;
2176 if (Reason != PDSA_Implicit) {
2177 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2178 << Reason << ReportHint
2180 }
else if (DVar.ImplicitDSALoc.isValid()) {
2181 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2187 class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
2190 bool ErrorFound =
false;
2195 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2203 if (!Cap.capturesVariable())
2205 VarDecl *VD = Cap.getCapturedVar();
2209 Stack->checkMappableExprComponentListsForDecl(
2216 Cap.getLocation(),
true);
2226 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2227 VD = VD->getCanonicalDecl();
2232 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
2234 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2239 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2241 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2250 if (DVar.CKind ==
OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2251 isImplicitOrExplicitTaskingRegion(DKind) &&
2252 VarsWithInheritedDSA.count(VD) == 0) {
2253 VarsWithInheritedDSA[VD] = E;
2258 !Stack->isLoopControlVariable(VD).first) {
2259 if (!Stack->checkMappableExprComponentListsForDecl(
2266 return StackComponents.size() == 1 ||
2268 std::next(StackComponents.rbegin()),
2269 StackComponents.rend(),
2270 [](const OMPClauseMappableExprCommon::
2271 MappableComponent &MC) {
2272 return MC.getAssociatedDeclaration() ==
2274 (isa<OMPArraySectionExpr>(
2275 MC.getAssociatedExpression()) ||
2276 isa<ArraySubscriptExpr>(
2277 MC.getAssociatedExpression()));
2280 bool IsFirstprivate =
false;
2282 if (
const auto *RD =
2283 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2284 IsFirstprivate = RD->isLambda();
2287 (VD->getType().getNonReferenceType()->isScalarType() &&
2288 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2290 ImplicitFirstprivate.emplace_back(E);
2292 ImplicitMap.emplace_back(E);
2301 DVar = Stack->hasInnermostDSA(
2310 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2316 DVar = Stack->getImplicitDSA(VD,
false);
2318 !Stack->isLoopControlVariable(VD).first)
2319 ImplicitFirstprivate.push_back(E);
2331 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
2334 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2338 !Stack->isLoopControlVariable(FD).first &&
2339 !Stack->checkMappableExprComponentListsForDecl(
2344 return isa<CXXThisExpr>(
2346 StackComponents.back().getAssociatedExpression())
2353 if (FD->isBitField())
2358 if (Stack->isClassPreviouslyMapped(TE->getType()))
2361 ImplicitMap.emplace_back(E);
2370 DVar = Stack->hasInnermostDSA(
2379 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2385 DVar = Stack->getImplicitDSA(FD,
false);
2387 !Stack->isLoopControlVariable(FD).first) {
2393 ImplicitFirstprivate.push_back(E);
2402 const auto *VD = cast<ValueDecl>(
2403 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2404 if (!Stack->checkMappableExprComponentListsForDecl(
2410 auto CCI = CurComponents.rbegin();
2411 auto CCE = CurComponents.rend();
2412 for (const auto &SC : llvm::reverse(StackComponents)) {
2414 if (CCI->getAssociatedExpression()->getStmtClass() !=
2415 SC.getAssociatedExpression()->getStmtClass())
2416 if (!(isa<OMPArraySectionExpr>(
2417 SC.getAssociatedExpression()) &&
2418 isa<ArraySubscriptExpr>(
2419 CCI->getAssociatedExpression())))
2422 const Decl *CCD = CCI->getAssociatedDeclaration();
2423 const Decl *SCD = SC.getAssociatedDeclaration();
2424 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2425 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2428 std::advance(CCI, 1);
2446 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
2448 for (
Stmt *CC :
C->children()) {
2455 VisitSubCaptures(S);
2457 void VisitStmt(
Stmt *S) {
2467 bool isErrorFound()
const {
return ErrorFound; }
2469 return ImplicitFirstprivate;
2473 return VarsWithInheritedDSA;
2477 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
2484 case OMPD_parallel_for:
2485 case OMPD_parallel_for_simd:
2486 case OMPD_parallel_sections:
2488 case OMPD_teams_distribute:
2489 case OMPD_teams_distribute_simd: {
2494 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2495 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2496 std::make_pair(StringRef(),
QualType())
2502 case OMPD_target_teams:
2503 case OMPD_target_parallel:
2504 case OMPD_target_parallel_for:
2505 case OMPD_target_parallel_for_simd:
2506 case OMPD_target_teams_distribute:
2507 case OMPD_target_teams_distribute_simd: {
2517 std::make_pair(
".global_tid.", KmpInt32Ty),
2518 std::make_pair(
".part_id.", KmpInt32PtrTy),
2519 std::make_pair(
".privates.", VoidPtrTy),
2524 std::make_pair(StringRef(),
QualType())
2530 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2531 AlwaysInlineAttr::CreateImplicit(
2532 Context, AlwaysInlineAttr::Keyword_forceinline));
2534 std::make_pair(StringRef(),
QualType())
2540 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2541 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2542 std::make_pair(StringRef(),
QualType())
2547 ParamsTeamsOrParallel);
2551 case OMPD_target_simd: {
2561 std::make_pair(
".global_tid.", KmpInt32Ty),
2562 std::make_pair(
".part_id.", KmpInt32PtrTy),
2563 std::make_pair(
".privates.", VoidPtrTy),
2568 std::make_pair(StringRef(),
QualType())
2574 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2575 AlwaysInlineAttr::CreateImplicit(
2576 Context, AlwaysInlineAttr::Keyword_forceinline));
2578 std::make_pair(StringRef(),
QualType()));
2589 case OMPD_taskgroup:
2590 case OMPD_distribute:
2591 case OMPD_distribute_simd:
2594 case OMPD_target_data: {
2596 std::make_pair(StringRef(),
QualType())
2612 std::make_pair(
".global_tid.", KmpInt32Ty),
2613 std::make_pair(
".part_id.", KmpInt32PtrTy),
2614 std::make_pair(
".privates.", VoidPtrTy),
2619 std::make_pair(StringRef(),
QualType())
2625 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2626 AlwaysInlineAttr::CreateImplicit(
2627 Context, AlwaysInlineAttr::Keyword_forceinline));
2631 case OMPD_taskloop_simd: {
2649 std::make_pair(
".global_tid.", KmpInt32Ty),
2650 std::make_pair(
".part_id.", KmpInt32PtrTy),
2651 std::make_pair(
".privates.", VoidPtrTy),
2656 std::make_pair(
".lb.", KmpUInt64Ty),
2657 std::make_pair(
".ub.", KmpUInt64Ty),
2658 std::make_pair(
".st.", KmpInt64Ty),
2659 std::make_pair(
".liter.", KmpInt32Ty),
2660 std::make_pair(
".reductions.", VoidPtrTy),
2661 std::make_pair(StringRef(),
QualType())
2667 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2668 AlwaysInlineAttr::CreateImplicit(
2669 Context, AlwaysInlineAttr::Keyword_forceinline));
2672 case OMPD_distribute_parallel_for_simd:
2673 case OMPD_distribute_parallel_for: {
2678 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2679 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2682 std::make_pair(StringRef(),
QualType())
2688 case OMPD_target_teams_distribute_parallel_for:
2689 case OMPD_target_teams_distribute_parallel_for_simd: {
2700 std::make_pair(
".global_tid.", KmpInt32Ty),
2701 std::make_pair(
".part_id.", KmpInt32PtrTy),
2702 std::make_pair(
".privates.", VoidPtrTy),
2707 std::make_pair(StringRef(),
QualType())
2713 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2714 AlwaysInlineAttr::CreateImplicit(
2715 Context, AlwaysInlineAttr::Keyword_forceinline));
2717 std::make_pair(StringRef(),
QualType())
2724 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2725 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2726 std::make_pair(StringRef(),
QualType())
2733 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2734 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2737 std::make_pair(StringRef(),
QualType())
2746 case OMPD_teams_distribute_parallel_for:
2747 case OMPD_teams_distribute_parallel_for_simd: {
2753 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2754 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2755 std::make_pair(StringRef(),
QualType())
2762 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2763 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2766 std::make_pair(StringRef(),
QualType())
2774 case OMPD_target_update:
2775 case OMPD_target_enter_data:
2776 case OMPD_target_exit_data: {
2786 std::make_pair(
".global_tid.", KmpInt32Ty),
2787 std::make_pair(
".part_id.", KmpInt32PtrTy),
2788 std::make_pair(
".privates.", VoidPtrTy),
2793 std::make_pair(StringRef(),
QualType())
2799 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2800 AlwaysInlineAttr::CreateImplicit(
2801 Context, AlwaysInlineAttr::Keyword_forceinline));
2804 case OMPD_threadprivate:
2805 case OMPD_taskyield:
2808 case OMPD_cancellation_point:
2811 case OMPD_declare_reduction:
2812 case OMPD_declare_simd:
2813 case OMPD_declare_target:
2814 case OMPD_end_declare_target:
2816 llvm_unreachable(
"OpenMP Directive is not allowed");
2818 llvm_unreachable(
"Unknown OpenMP directive");
2825 return CaptureRegions.size();
2829 Expr *CaptureExpr,
bool WithInit,
2830 bool AsExpression) {
2831 assert(CaptureExpr);
2851 CED->
addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2861 CD = cast<OMPCapturedExprDecl>(VD);
2883 if (!Res.isUsable())
2898 class CaptureRegionUnwinderRAII {
2905 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
2907 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2908 ~CaptureRegionUnwinderRAII() {
2911 while (--ThisCaptureLevel >= 0)
2920 bool ErrorFound =
false;
2921 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2922 *
this, ErrorFound,
DSAStack->getCurrentDirective());
2940 auto *IRC = cast<OMPInReductionClause>(Clause);
2941 for (
Expr *E : IRC->taskgroup_descriptors())
2943 MarkDeclarationsReferencedInExpr(E);
2947 (getLangOpts().OpenMPUseTLS &&
2948 getASTContext().getTargetInfo().isTLSSupported() &&
2953 if (
auto *E = cast_or_null<Expr>(VarRef)) {
2954 MarkDeclarationsReferencedInExpr(E);
2957 DSAStack->setForceVarCapturing(
false);
2958 }
else if (CaptureRegions.size() > 1 ||
2963 if (
Expr *E =
C->getPostUpdateExpr())
2964 MarkDeclarationsReferencedInExpr(E);
2968 SC = cast<OMPScheduleClause>(Clause);
2970 OC = cast<OMPOrderedClause>(Clause);
2972 LCs.push_back(cast<OMPLinearClause>(Clause));
2980 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2985 diag::err_omp_schedule_nonmonotonic_ordered)
2986 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2989 if (!LCs.empty() && OC && OC->getNumForLoops()) {
2991 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
2992 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2998 OC->getNumForLoops()) {
2999 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3019 if (CaptureRegion == ThisCaptureRegion ||
3021 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
3022 for (
Decl *D : DS->decls())
3023 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
3028 SR = ActOnCapturedRegionEnd(SR.
get());
3037 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3040 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3041 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3044 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3054 if (Stack->getCurScope()) {
3057 bool NestingProhibited =
false;
3058 bool CloseNesting =
true;
3059 bool OrphanSeen =
false;
3062 ShouldBeInParallelRegion,
3063 ShouldBeInOrderedRegion,
3064 ShouldBeInTargetRegion,
3065 ShouldBeInTeamsRegion
3066 } Recommend = NoRecommend;
3076 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
3077 ? diag::err_omp_prohibited_region_simd
3078 : diag::warn_omp_nesting_simd);
3079 return CurrentRegion != OMPD_simd;
3081 if (ParentRegion == OMPD_atomic) {
3084 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3087 if (CurrentRegion == OMPD_section) {
3092 if (ParentRegion != OMPD_sections &&
3093 ParentRegion != OMPD_parallel_sections) {
3094 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3106 CurrentRegion != OMPD_cancellation_point &&
3107 CurrentRegion != OMPD_cancel)
3109 if (CurrentRegion == OMPD_cancellation_point ||
3110 CurrentRegion == OMPD_cancel) {
3123 !((CancelRegion == OMPD_parallel &&
3124 (ParentRegion == OMPD_parallel ||
3125 ParentRegion == OMPD_target_parallel)) ||
3126 (CancelRegion == OMPD_for &&
3127 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3128 ParentRegion == OMPD_target_parallel_for ||
3129 ParentRegion == OMPD_distribute_parallel_for ||
3130 ParentRegion == OMPD_teams_distribute_parallel_for ||
3131 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3132 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3133 (CancelRegion == OMPD_sections &&
3134 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3135 ParentRegion == OMPD_parallel_sections)));
3137 }
else if (CurrentRegion == OMPD_master) {
3143 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
3149 bool DeadLock = Stack->hasDirective(
3153 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
3154 PreviousCriticalLoc = Loc;
3161 SemaRef.
Diag(StartLoc,
3162 diag::err_omp_prohibited_region_critical_same_name)
3164 if (PreviousCriticalLoc.
isValid())
3165 SemaRef.
Diag(PreviousCriticalLoc,
3166 diag::note_omp_previous_critical_region);
3169 }
else if (CurrentRegion == OMPD_barrier) {
3175 ParentRegion == OMPD_master ||
3176 ParentRegion == OMPD_critical ||
3177 ParentRegion == OMPD_ordered;
3186 ParentRegion == OMPD_master ||
3187 ParentRegion == OMPD_critical ||
3188 ParentRegion == OMPD_ordered;
3189 Recommend = ShouldBeInParallelRegion;
3190 }
else if (CurrentRegion == OMPD_ordered) {
3199 NestingProhibited = ParentRegion == OMPD_critical ||
3202 Stack->isParentOrderedRegion());
3203 Recommend = ShouldBeInOrderedRegion;
3208 NestingProhibited = ParentRegion != OMPD_target;
3210 Recommend = ShouldBeInTargetRegion;
3212 if (!NestingProhibited &&
3215 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3222 Recommend = ShouldBeInParallelRegion;
3224 if (!NestingProhibited &&
3230 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3231 Recommend = ShouldBeInTeamsRegion;
3233 if (!NestingProhibited &&
3240 NestingProhibited = Stack->hasDirective(
3244 OffendingRegion = K;
3250 CloseNesting =
false;
3252 if (NestingProhibited) {
3254 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3257 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
3270 bool ErrorFound =
false;
3271 unsigned NamedModifiersNumber = 0;
3276 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
3280 if (FoundNameModifiers[CurNM]) {
3281 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
3286 NameModifierLoc.push_back(IC->getNameModifierLoc());
3287 ++NamedModifiersNumber;
3289 FoundNameModifiers[CurNM] = IC;
3296 bool MatchFound =
false;
3297 for (
auto NM : AllowedNameModifiers) {
3304 S.
Diag(IC->getNameModifierLoc(),
3305 diag::err_omp_wrong_if_directive_name_modifier)
3313 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
3314 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3316 diag::err_omp_no_more_if_clause);
3319 std::string Sep(
", ");
3320 unsigned AllowedCnt = 0;
3321 unsigned TotalAllowedNum =
3322 AllowedNameModifiers.size() - NamedModifiersNumber;
3323 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
3326 if (!FoundNameModifiers[NM]) {
3330 if (AllowedCnt + 2 == TotalAllowedNum)
3332 else if (AllowedCnt + 1 != TotalAllowedNum)
3338 diag::err_omp_unnamed_if_clause)
3339 << (TotalAllowedNum > 1) << Values;
3342 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
3362 bool ErrorFound =
false;
3363 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3364 if (AStmt && !CurContext->isDependentContext()) {
3365 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
3368 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
3369 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3371 while (--ThisCaptureLevel >= 0)
3372 S = cast<CapturedStmt>(S)->getCapturedStmt();
3373 DSAChecker.Visit(S);
3374 if (DSAChecker.isErrorFound())
3377 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3380 DSAChecker.getImplicitFirstprivate().begin(),
3381 DSAChecker.getImplicitFirstprivate().end());
3383 DSAChecker.getImplicitMap().end());
3386 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
3387 for (
Expr *E : IRC->taskgroup_descriptors())
3389 ImplicitFirstprivates.emplace_back(E);
3392 if (!ImplicitFirstprivates.empty()) {
3393 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3396 ClausesWithImplicit.push_back(Implicit);
3397 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3398 ImplicitFirstprivates.size();
3403 if (!ImplicitMaps.empty()) {
3404 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
3409 ClausesWithImplicit.emplace_back(Implicit);
3411 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3421 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3423 AllowedNameModifiers.push_back(OMPD_parallel);
3426 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3427 VarsWithInheritedDSA);
3430 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3431 VarsWithInheritedDSA);
3434 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3435 EndLoc, VarsWithInheritedDSA);
3438 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3442 assert(ClausesWithImplicit.empty() &&
3443 "No clauses are allowed for 'omp section' directive");
3444 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3447 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3451 assert(ClausesWithImplicit.empty() &&
3452 "No clauses are allowed for 'omp master' directive");
3453 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3456 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3459 case OMPD_parallel_for:
3460 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3461 EndLoc, VarsWithInheritedDSA);
3462 AllowedNameModifiers.push_back(OMPD_parallel);
3464 case OMPD_parallel_for_simd:
3465 Res = ActOnOpenMPParallelForSimdDirective(
3466 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3467 AllowedNameModifiers.push_back(OMPD_parallel);
3469 case OMPD_parallel_sections:
3470 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3472 AllowedNameModifiers.push_back(OMPD_parallel);
3476 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3477 AllowedNameModifiers.push_back(OMPD_task);
3479 case OMPD_taskyield:
3480 assert(ClausesWithImplicit.empty() &&
3481 "No clauses are allowed for 'omp taskyield' directive");
3482 assert(AStmt ==
nullptr &&
3483 "No associated statement allowed for 'omp taskyield' directive");
3484 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3487 assert(ClausesWithImplicit.empty() &&
3488 "No clauses are allowed for 'omp barrier' directive");
3489 assert(AStmt ==
nullptr &&
3490 "No associated statement allowed for 'omp barrier' directive");
3491 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3494 assert(ClausesWithImplicit.empty() &&
3495 "No clauses are allowed for 'omp taskwait' directive");
3496 assert(AStmt ==
nullptr &&
3497 "No associated statement allowed for 'omp taskwait' directive");
3498 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3500 case OMPD_taskgroup:
3501 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3505 assert(AStmt ==
nullptr &&
3506 "No associated statement allowed for 'omp flush' directive");
3507 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3510 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3514 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3519 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3522 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3524 AllowedNameModifiers.push_back(OMPD_target);
3526 case OMPD_target_parallel:
3527 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3529 AllowedNameModifiers.push_back(OMPD_target);
3530 AllowedNameModifiers.push_back(OMPD_parallel);
3532 case OMPD_target_parallel_for:
3533 Res = ActOnOpenMPTargetParallelForDirective(
3534 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3535 AllowedNameModifiers.push_back(OMPD_target);
3536 AllowedNameModifiers.push_back(OMPD_parallel);
3538 case OMPD_cancellation_point:
3539 assert(ClausesWithImplicit.empty() &&
3540 "No clauses are allowed for 'omp cancellation point' directive");
3541 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp " 3542 "cancellation point' directive");
3543 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3546 assert(AStmt ==
nullptr &&
3547 "No associated statement allowed for 'omp cancel' directive");
3548 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3550 AllowedNameModifiers.push_back(OMPD_cancel);
3552 case OMPD_target_data:
3553 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3555 AllowedNameModifiers.push_back(OMPD_target_data);
3557 case OMPD_target_enter_data:
3558 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3560 AllowedNameModifiers.push_back(OMPD_target_enter_data);
3562 case OMPD_target_exit_data:
3563 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3565 AllowedNameModifiers.push_back(OMPD_target_exit_data);
3568 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3569 EndLoc, VarsWithInheritedDSA);
3570 AllowedNameModifiers.push_back(OMPD_taskloop);
3572 case OMPD_taskloop_simd:
3573 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3574 EndLoc, VarsWithInheritedDSA);
3575 AllowedNameModifiers.push_back(OMPD_taskloop);
3577 case OMPD_distribute:
3578 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3579 EndLoc, VarsWithInheritedDSA);
3581 case OMPD_target_update:
3582 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3584 AllowedNameModifiers.push_back(OMPD_target_update);
3586 case OMPD_distribute_parallel_for:
3587 Res = ActOnOpenMPDistributeParallelForDirective(
3588 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3589 AllowedNameModifiers.push_back(OMPD_parallel);
3591 case OMPD_distribute_parallel_for_simd:
3592 Res = ActOnOpenMPDistributeParallelForSimdDirective(
3593 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3594 AllowedNameModifiers.push_back(OMPD_parallel);
3596 case OMPD_distribute_simd:
3597 Res = ActOnOpenMPDistributeSimdDirective(
3598 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3600 case OMPD_target_parallel_for_simd:
3601 Res = ActOnOpenMPTargetParallelForSimdDirective(
3602 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3603 AllowedNameModifiers.push_back(OMPD_target);
3604 AllowedNameModifiers.push_back(OMPD_parallel);
3606 case OMPD_target_simd:
3607 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3608 EndLoc, VarsWithInheritedDSA);
3609 AllowedNameModifiers.push_back(OMPD_target);
3611 case OMPD_teams_distribute:
3612 Res = ActOnOpenMPTeamsDistributeDirective(
3613 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3615 case OMPD_teams_distribute_simd:
3616 Res = ActOnOpenMPTeamsDistributeSimdDirective(
3617 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3619 case OMPD_teams_distribute_parallel_for_simd:
3620 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3621 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3622 AllowedNameModifiers.push_back(OMPD_parallel);
3624 case OMPD_teams_distribute_parallel_for:
3625 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3626 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3627 AllowedNameModifiers.push_back(OMPD_parallel);
3629 case OMPD_target_teams:
3630 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3632 AllowedNameModifiers.push_back(OMPD_target);
3634 case OMPD_target_teams_distribute:
3635 Res = ActOnOpenMPTargetTeamsDistributeDirective(
3636 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3637 AllowedNameModifiers.push_back(OMPD_target);
3639 case OMPD_target_teams_distribute_parallel_for:
3640 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3641 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3642 AllowedNameModifiers.push_back(OMPD_target);
3643 AllowedNameModifiers.push_back(OMPD_parallel);
3645 case OMPD_target_teams_distribute_parallel_for_simd:
3646 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3647 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3648 AllowedNameModifiers.push_back(OMPD_target);
3649 AllowedNameModifiers.push_back(OMPD_parallel);
3651 case OMPD_target_teams_distribute_simd:
3652 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3653 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3654 AllowedNameModifiers.push_back(OMPD_target);
3656 case OMPD_declare_target:
3657 case OMPD_end_declare_target:
3658 case OMPD_threadprivate:
3659 case OMPD_declare_reduction:
3660 case OMPD_declare_simd:
3662 llvm_unreachable(
"OpenMP Directive is not allowed");
3664 llvm_unreachable(
"Unknown OpenMP directive");
3667 for (
const auto &
P : VarsWithInheritedDSA) {
3668 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3669 <<
P.first <<
P.second->getSourceRange();
3671 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3673 if (!AllowedNameModifiers.empty())
3674 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
3687 assert(Aligneds.size() == Alignments.size());
3688 assert(Linears.size() == LinModifiers.size());
3689 assert(Linears.size() == Steps.size());
3690 if (!DG || DG.
get().isNull())
3693 if (!DG.
get().isSingleDecl()) {
3694 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
3697 Decl *ADecl = DG.
get().getSingleDecl();
3698 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3699 ADecl = FTD->getTemplatedDecl();
3712 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3719 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3720 const Expr *UniformedLinearThis =
nullptr;
3721 for (
const Expr *E : Uniforms) {
3723 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3724 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3725 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3726 FD->getParamDecl(PVD->getFunctionScopeIndex())
3728 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3731 if (isa<CXXThisExpr>(E)) {
3732 UniformedLinearThis = E;
3736 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3746 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3747 const Expr *AlignedThis =
nullptr;
3748 for (
const Expr *E : Aligneds) {
3750 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3751 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3753 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3754 FD->getParamDecl(PVD->getFunctionScopeIndex())
3758 if (AlignedArgs.count(CanonPVD) > 0) {
3761 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3762 diag::note_omp_explicit_dsa)
3766 AlignedArgs[CanonPVD] = E;
3768 .getNonReferenceType()
3769 .getUnqualifiedType()
3770 .getCanonicalType();
3773 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3775 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3780 if (isa<CXXThisExpr>(E)) {
3791 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3798 for (
Expr *E : Alignments) {
3801 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3802 NewAligns.push_back(Align.
get());
3813 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3814 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
3815 auto MI = LinModifiers.begin();
3816 for (
const Expr *E : Linears) {
3820 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
3821 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3823 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3824 FD->getParamDecl(PVD->getFunctionScopeIndex())
3828 if (LinearArgs.count(CanonPVD) > 0) {
3832 Diag(LinearArgs[CanonPVD]->getExprLoc(),
3833 diag::note_omp_explicit_dsa)
3838 if (UniformedArgs.count(CanonPVD) > 0) {
3842 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3843 diag::note_omp_explicit_dsa)
3847 LinearArgs[CanonPVD] = E;
3852 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
3853 PVD->getOriginalType());
3857 if (isa<CXXThisExpr>(E)) {
3858 if (UniformedLinearThis) {
3863 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
3868 UniformedLinearThis = E;
3872 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
3877 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3880 Expr *NewStep =
nullptr;
3882 for (
Expr *E : Steps) {
3884 if (Step == E || !E) {
3885 NewSteps.push_back(E ? NewStep :
nullptr);
3889 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3890 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3892 if (UniformedArgs.count(CanonPVD) == 0) {
3899 NewSteps.push_back(Step);
3910 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(),
Step)
3913 NewStep = VerifyIntegerConstantExpression(NewStep).get();
3915 NewSteps.push_back(NewStep);
3917 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3918 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
3919 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
3920 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
3921 const_cast<Expr **
>(Linears.data()), Linears.size(),
3922 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
3923 NewSteps.data(), NewSteps.size(), SR);
3925 return ConvertDeclToDeclGroup(ADecl);
3935 auto *CS = cast<CapturedStmt>(AStmt);
3943 setFunctionHasBranchProtectedScope();
3953 class OpenMPIterationSpaceChecker {
3969 Expr *LCRef =
nullptr;
3984 bool TestIsStrictOp =
false;
3986 bool SubtractStep =
false;
3990 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3993 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
3996 bool checkAndSetCond(
Expr *S);
3999 bool checkAndSetInc(
Expr *S);
4001 ValueDecl *getLoopDecl()
const {
return LCDecl; }
4003 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
4005 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
4007 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
4009 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
4011 bool shouldSubtractStep()
const {
return SubtractStep; }
4013 Expr *buildNumIterations(
4014 Scope *S,
const bool LimitedType,
4015 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
4019 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
4022 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4023 DSAStackTy &DSA)
const;
4026 Expr *buildPrivateCounterVar()
const;
4030 Expr *buildCounterStep()
const;
4034 buildOrderedLoopData(
Scope *S,
Expr *Counter,
4035 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4039 bool dependent()
const;
4044 bool checkAndSetIncRHS(
Expr *RHS);
4054 bool OpenMPIterationSpaceChecker::dependent()
const {
4056 assert(!LB && !UB && !
Step);
4059 return LCDecl->getType()->isDependentType() ||
4060 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4061 (
Step &&
Step->isValueDependent());
4064 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
4068 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
4069 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4070 if (!NewLCDecl || !NewLB)
4073 LCRef = NewLCRefExpr;
4074 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4076 if ((Ctor->isCopyOrMoveConstructor() ||
4077 Ctor->isConvertingConstructor(
false)) &&
4078 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
4088 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
4089 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4094 TestIsLessOp = LessOp;
4095 TestIsStrictOp = StrictOp;
4096 ConditionSrcRange = SR;
4103 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
4113 NewStep = Val.
get();
4130 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4132 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4133 bool IsConstZero = IsConstant && !Result.getBoolValue();
4136 if (!TestIsLessOp.hasValue())
4137 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
4138 if (UB && (IsConstZero ||
4139 (TestIsLessOp.getValue() ?
4140 (IsConstNeg || (IsUnsigned && Subtract)) :
4141 (IsConstPos || (IsUnsigned && !Subtract))))) {
4143 diag::err_omp_loop_incr_not_compatible)
4144 << LCDecl << TestIsLessOp.getValue() << NewStep->
getSourceRange();
4145 SemaRef.
Diag(ConditionLoc,
4146 diag::note_omp_loop_cond_requres_compatible_incr)
4147 << TestIsLessOp.getValue() << ConditionSrcRange;
4150 if (TestIsLessOp.getValue() == Subtract) {
4154 Subtract = !Subtract;
4159 SubtractStep = Subtract;
4163 bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
4174 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4178 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4179 if (!ExprTemp->cleanupsHaveSideEffects())
4180 S = ExprTemp->getSubExpr();
4183 if (
Expr *E = dyn_cast<Expr>(S))
4185 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
4186 if (BO->getOpcode() == BO_Assign) {
4188 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4189 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4191 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4192 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4194 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
4195 if (ME->isArrow() &&
4196 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4197 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4200 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
4201 if (DS->isSingleDecl()) {
4202 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4203 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4207 diag::ext_omp_loop_not_canonical_init)
4209 return setLCDeclAndLB(
4212 Var->getType().getNonReferenceType(),
4218 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4219 if (CE->getOperator() == OO_Equal) {
4220 Expr *LHS = CE->getArg(0);
4221 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4222 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4224 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4225 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4227 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
4228 if (ME->isArrow() &&
4229 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4230 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4250 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4252 if ((Ctor->isCopyOrMoveConstructor() ||
4253 Ctor->isConvertingConstructor(
false)) &&
4254 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
4256 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4257 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4260 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
4261 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4266 bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
4274 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4279 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
4280 if (BO->isRelationalOp()) {
4281 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4282 return setUB(BO->getRHS(),
4283 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4284 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4285 BO->getSourceRange(), BO->getOperatorLoc());
4286 if (getInitLCDecl(BO->getRHS()) == LCDecl)
4287 return setUB(BO->getLHS(),
4288 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4289 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4290 BO->getSourceRange(), BO->getOperatorLoc());
4291 }
else if (BO->getOpcode() == BO_NE)
4292 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
4293 BO->getRHS() : BO->getLHS(),
4296 BO->getSourceRange(), BO->getOperatorLoc());
4297 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4298 if (CE->getNumArgs() == 2) {
4299 auto Op = CE->getOperator();
4302 case OO_GreaterEqual:
4305 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4306 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4307 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4308 CE->getOperatorLoc());
4309 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4310 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4311 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4312 CE->getOperatorLoc());
4314 case OO_ExclaimEqual:
4315 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
4316 CE->getArg(1) : CE->getArg(0),
4319 CE->getSourceRange(),
4320 CE->getOperatorLoc());
4329 SemaRef.
Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4334 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
4341 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4342 if (BO->isAdditiveOp()) {
4343 bool IsAdd = BO->getOpcode() == BO_Add;
4344 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4345 return setStep(BO->getRHS(), !IsAdd);
4346 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4347 return setStep(BO->getLHS(),
false);
4349 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4350 bool IsAdd = CE->getOperator() == OO_Plus;
4351 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4352 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4353 return setStep(CE->getArg(1), !IsAdd);
4354 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4355 return setStep(CE->getArg(0),
false);
4360 SemaRef.
Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4365 bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
4380 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4383 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4384 if (!ExprTemp->cleanupsHaveSideEffects())
4385 S = ExprTemp->getSubExpr();
4389 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
4390 if (UO->isIncrementDecrementOp() &&
4391 getInitLCDecl(UO->getSubExpr()) == LCDecl)
4393 .ActOnIntegerConstant(UO->getBeginLoc(),
4394 (UO->isDecrementOp() ? -1 : 1))
4397 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
4398 switch (BO->getOpcode()) {
4401 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4402 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4405 if (getInitLCDecl(BO->getLHS()) == LCDecl)
4406 return checkAndSetIncRHS(BO->getRHS());
4411 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4412 switch (CE->getOperator()) {
4415 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4417 .ActOnIntegerConstant(
4419 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4425 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4426 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4429 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4430 return checkAndSetIncRHS(CE->getArg(1));
4444 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
4445 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4452 auto I = Captures.find(Capture);
4453 if (I != Captures.end())
4457 Captures[Capture] = Ref;
4462 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4463 Scope *S,
const bool LimitedType,
4464 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
4466 QualType VarType = LCDecl->getType().getNonReferenceType();
4470 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
4471 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
4472 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4473 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4474 if (!Upper || !Lower)
4477 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4494 S, DefaultLoc, BO_Sub, Diff.
get(),
4503 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.
get());
4513 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
4536 unsigned NewSize = (C.
getTypeSize(Type) > 32) ? 64 : 32;
4539 assert(NewSize == 64 &&
"incorrect loop var size");
4540 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4541 << InitSrcRange << ConditionSrcRange;
4558 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4560 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
4565 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4566 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4572 TestIsLessOp.getValue() ?
4573 (TestIsStrictOp ? BO_LT : BO_LE) :
4574 (TestIsStrictOp ? BO_GT : BO_GE),
4575 NewLB.
get(), NewUB.
get());
4585 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
4589 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4590 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4591 DSAStackTy &DSA)
const {
4592 auto *VD = dyn_cast<
VarDecl>(LCDecl);
4596 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4597 const DSAStackTy::DSAVarData Data =
4598 DSA.getTopDSA(LCDecl,
false);
4602 Captures.insert(std::make_pair(LCRef, Ref));
4609 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
4610 if (LCDecl && !LCDecl->isInvalidDecl()) {
4611 QualType Type = LCDecl->getType().getNonReferenceType();
4613 SemaRef, DefaultLoc, Type, LCDecl->getName(),
4614 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr,
4615 isa<VarDecl>(LCDecl)
4629 Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
4631 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4633 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
4639 assert((OOK == OO_Plus || OOK == OO_Minus) &&
4640 "Expected only + or - operations for depend clauses.");
4647 QualType VarType = LCDecl->getType().getNonReferenceType();
4652 TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4654 TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4655 if (!Upper || !Lower)
4658 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4681 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
4689 struct LoopIterationSpace final {
4691 Expr *PreCond =
nullptr;
4694 Expr *NumIterations =
nullptr;
4696 Expr *CounterVar =
nullptr;
4698 Expr *PrivateCounterVar =
nullptr;
4700 Expr *CounterInit =
nullptr;
4703 Expr *CounterStep =
nullptr;
4705 bool Subtract =
false;
4717 assert(getLangOpts().OpenMP &&
"OpenMP is not active.");
4718 assert(Init &&
"Expected loop in canonical form.");
4719 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
4720 if (AssociatedLoops > 0 &&
4723 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
4724 if (!ISC.checkAndSetInit(Init,
false)) {
4726 auto *VD = dyn_cast<
VarDecl>(D);
4728 if (
VarDecl *Private = isOpenMPCapturedDecl(D)) {
4733 VD = cast<VarDecl>(Ref->
getDecl());
4736 DSAStack->addLoopControlVariable(D, VD);
4739 DSAStack->resetPossibleLoopCounter();
4740 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
4741 MarkDeclarationsReferencedInExpr(
4743 Var->getType().getNonLValueExprType(Context),
4748 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4756 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
4757 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
4758 Expr *OrderedLoopCountExpr,
4760 LoopIterationSpace &ResultIterSpace,
4761 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4764 auto *For = dyn_cast_or_null<ForStmt>(S);
4767 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
4769 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4770 if (TotalNestedLoopCount > 1) {
4771 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4772 SemaRef.
Diag(DSA.getConstructLoc(),
4773 diag::note_omp_collapse_ordered_expr)
4776 else if (CollapseLoopCountExpr)
4778 diag::note_omp_collapse_ordered_expr)
4782 diag::note_omp_collapse_ordered_expr)
4787 assert(For->getBody());
4789 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4792 Stmt *Init = For->getInit();
4793 if (ISC.checkAndSetInit(Init))
4796 bool HasErrors =
false;
4799 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
4800 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4807 QualType VarType = LCDecl->getType().getNonReferenceType();
4811 SemaRef.
Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
4825 VarsWithImplicitDSA.erase(LCDecl);
4835 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl,
false);
4840 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4843 DVar.CKind != PredeterminedCKind) ||
4847 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4848 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
4849 SemaRef.
Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
4852 if (DVar.RefExpr ==
nullptr)
4853 DVar.CKind = PredeterminedCKind;
4856 }
else if (LoopDeclRefExpr !=
nullptr) {
4865 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4871 HasErrors |= ISC.checkAndSetCond(For->getCond());
4874 HasErrors |= ISC.checkAndSetInc(For->getInc());
4881 ResultIterSpace.PreCond =
4882 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4883 ResultIterSpace.NumIterations = ISC.buildNumIterations(
4888 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4889 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4890 ResultIterSpace.CounterInit = ISC.buildCounterInit();
4891 ResultIterSpace.CounterStep = ISC.buildCounterStep();
4892 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4893 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4894 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4895 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4897 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
4898 ResultIterSpace.NumIterations ==
nullptr ||
4899 ResultIterSpace.CounterVar ==
nullptr ||
4900 ResultIterSpace.PrivateCounterVar ==
nullptr ||
4901 ResultIterSpace.CounterInit ==
nullptr ||
4902 ResultIterSpace.CounterStep ==
nullptr);
4903 if (!HasErrors && DSA.isOrderedRegion()) {
4904 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4905 if (CurrentNestedLoopCount <
4906 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4907 DSA.getOrderedRegionParam().second->setLoopNumIterations(
4908 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4909 DSA.getOrderedRegionParam().second->setLoopCounter(
4910 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4913 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
4914 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4918 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4919 Pair.second.size() <= CurrentNestedLoopCount) {
4921 Pair.first->setLoopData(CurrentNestedLoopCount,
nullptr);
4925 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4926 CntValue = ISC.buildOrderedLoopData(
4927 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4928 Pair.first->getDependencyLoc());
4930 CntValue = ISC.buildOrderedLoopData(
4931 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4932 Pair.first->getDependencyLoc(),
4933 Pair.second[CurrentNestedLoopCount].first,
4934 Pair.second[CurrentNestedLoopCount].second);
4935 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4946 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4948 ExprResult NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
4952 VarRef.
get()->getType())) {
4969 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
4978 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
4990 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
4997 if (VarRef.
get()->getType()->isOverloadableType() ||
4998 NewStart.
get()->getType()->isOverloadableType() ||
4999 Update.
get()->getType()->isOverloadableType()) {
5006 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
5007 VarRef.
get(), SavedUpdate.
get());
5018 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
5019 NewStart.
get(), SavedUpdate.
get());
5024 VarRef.
get()->getType())) {
5031 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
5044 if (HasBits >= Bits)
5059 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5066 if (!PreInits.empty()) {
5077 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5078 if (!Captures.empty()) {
5080 for (
const auto &Pair : Captures)
5081 PreInits.push_back(Pair.second->getDecl());
5089 Expr *PostUpdate =
nullptr;
5090 if (!PostUpdates.empty()) {
5091 for (
Expr *E : PostUpdates) {
5097 PostUpdate = PostUpdate
5112 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
5116 unsigned NestedLoopCount = 1;
5117 if (CollapseLoopCountExpr) {
5121 NestedLoopCount = Result.
Val.
getInt().getLimitedValue();
5123 unsigned OrderedLoopCount = 1;
5124 if (OrderedLoopCountExpr) {
5129 if (Result.getLimitedValue() < NestedLoopCount) {
5131 diag::err_omp_wrong_ordered_loop_count)
5134 diag::note_collapse_loop_count)
5137 OrderedLoopCount = Result.getLimitedValue();
5142 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
5144 IterSpaces.resize(
std::max(OrderedLoopCount, NestedLoopCount));
5146 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5148 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5149 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5150 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5160 for (
unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
5162 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5163 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5164 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5167 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
5169 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
5170 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
5171 Captures[DRE] = DRE;
5182 Built.
clear( NestedLoopCount);
5185 return NestedLoopCount;
5218 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
5219 Expr *N0 = IterSpaces[0].NumIterations;
5223 .PerformImplicitConversion(
5237 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
5238 return NestedLoopCount;
5243 Scope *CurScope = DSA.getCurScope();
5244 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5245 if (PreCond.isUsable()) {
5247 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
5248 PreCond.get(), IterSpaces[Cnt].PreCond);
5250 Expr *N = IterSpaces[Cnt].NumIterations;
5255 CurScope, Loc, BO_Mul, LastIteration32.
get(),
5261 if (LastIteration64.isUsable())
5263 CurScope, Loc, BO_Mul, LastIteration64.get(),
5273 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
5276 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5279 LastIteration32.
get()->getType()->hasSignedIntegerRepresentation(),
5280 LastIteration64.get(), SemaRef))))
5281 LastIteration = LastIteration32;
5299 CurScope, LastIteration.
get()->getExprLoc(), BO_Sub,
5300 LastIteration.
get(),
5310 LastIteration.
get()->isIntegerConstantExpr(Result, SemaRef.
Context);
5314 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
5315 LastIteration = SaveRef;
5319 CurScope, SaveRef.
get()->getExprLoc(), BO_Add, SaveRef.
get(),
5328 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5355 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
5364 UB.
get(), LastIteration.
get());
5366 LastIteration.
get()->getExprLoc(), InitLoc, IsUBGreater.
get(),
5367 LastIteration.
get(), UB.
get());
5368 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
5393 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
5396 LastIteration.
get(), CombUB.
get());
5397 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
5402 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5406 "Unexpected number of parameters in loop combined directive");
5433 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5444 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5455 ? SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get())
5456 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5457 NumIterations.
get());
5462 CurScope, CondLoc, BO_LT, IV.get(), NumIterations.
get());
5468 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.
get());
5473 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5477 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
5486 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5517 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
5529 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
5543 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
5545 DistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get());
5546 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
5549 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
5550 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5551 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5555 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5563 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
5564 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
5572 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.
get());
5576 bool HasErrors =
false;
5577 Built.
Counters.resize(NestedLoopCount);
5578 Built.
Inits.resize(NestedLoopCount);
5579 Built.
Updates.resize(NestedLoopCount);
5580 Built.
Finals.resize(NestedLoopCount);
5598 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5599 LoopIterationSpace &IS = IterSpaces[Cnt];
5606 for (
unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5607 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
5608 IterSpaces[K].NumIterations);
5613 if (Cnt + 1 < NestedLoopCount)
5614 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div,
5627 if (Cnt + 1 < NestedLoopCount)
5628 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul,
5632 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub,
5636 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5638 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5641 IS.CounterInit, Captures);
5642 if (!Init.isUsable()) {
5647 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5648 IS.CounterStep, IS.Subtract, &Captures);
5656 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5657 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5668 Built.
Counters[Cnt] = IS.CounterVar;
5670 Built.
Inits[Cnt] = Init.get();
5687 Built.
PreCond = PreCond.get();
5692 Built.
LB = LB.
get();
5693 Built.
UB = UB.
get();
5694 Built.
IL = IL.
get();
5695 Built.
ST = ST.
get();
5697 Built.
NLB = NextLB.
get();
5698 Built.
NUB = NextUB.
get();
5713 return NestedLoopCount;
5717 auto CollapseClauses =
5718 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5719 if (CollapseClauses.begin() != CollapseClauses.end())
5720 return (*CollapseClauses.begin())->getNumForLoops();
5725 auto OrderedClauses =
5726 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5727 if (OrderedClauses.begin() != OrderedClauses.end())
5728 return (*OrderedClauses.begin())->getNumForLoops();
5737 for (
const OMPClause *Clause : Clauses) {
5739 Safelen = cast<OMPSafelenClause>(Clause);
5741 Simdlen = cast<OMPSimdlenClause>(Clause);
5742 if (Safelen && Simdlen)
5746 if (Simdlen && Safelen) {
5760 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
5761 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
5766 if (SimdlenRes > SafelenRes) {
5768 diag::err_omp_wrong_simdlen_safelen_values)
5783 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5789 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5790 if (NestedLoopCount == 0)
5793 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5794 "omp simd loop exprs were not built");
5796 if (!CurContext->isDependentContext()) {
5799 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5810 setFunctionHasBranchProtectedScope();
5822 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5828 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5829 if (NestedLoopCount == 0)
5832 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5833 "omp for loop exprs were not built");
5835 if (!CurContext->isDependentContext()) {
5838 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5846 setFunctionHasBranchProtectedScope();
5848 Clauses, AStmt, B,
DSAStack->isCancelRegion());
5857 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5861 unsigned NestedLoopCount =
5864 VarsWithImplicitDSA, B);
5865 if (NestedLoopCount == 0)
5868 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5869 "omp for simd loop exprs were not built");
5871 if (!CurContext->isDependentContext()) {
5874 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5885 setFunctionHasBranchProtectedScope();
5897 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5898 auto BaseStmt = AStmt;
5899 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5901 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5902 auto S =
C->children();
5903 if (S.begin() == S.end())
5907 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5908 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5910 Diag(SectionStmt->getBeginLoc(),
5911 diag::err_omp_sections_substmt_not_section);
5914 cast<OMPSectionDirective>(SectionStmt)
5915 ->setHasCancel(
DSAStack->isCancelRegion());
5922 setFunctionHasBranchProtectedScope();
5934 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5936 setFunctionHasBranchProtectedScope();
5950 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5952 setFunctionHasBranchProtectedScope();
5958 for (
const OMPClause *Clause : Clauses) {
5962 Copyprivate = Clause;
5963 if (Copyprivate && Nowait) {
5965 diag::err_omp_single_copyprivate_with_nowait);
5980 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5982 setFunctionHasBranchProtectedScope();
5993 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5995 bool ErrorFound =
false;
5998 bool DependentHint =
false;
6000 if (
C->getClauseKind() == OMPC_hint) {
6002 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
6005 Expr *E = cast<OMPHintClause>(
C)->getHint();
6008 DependentHint =
true;
6011 HintLoc =
C->getBeginLoc();
6017 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
6018 if (Pair.first && DirName.
getName() && !DependentHint) {
6019 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6020 Diag(StartLoc, diag::err_omp_critical_with_hint);
6022 Diag(HintLoc, diag::note_omp_critical_hint_here)
6023 << 0 << Hint.toString(10,
false);
6025 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6026 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
6027 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
6029 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
6032 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6037 setFunctionHasBranchProtectedScope();
6041 if (!Pair.first && DirName.
getName() && !DependentHint)
6042 DSAStack->addCriticalWithHint(Dir, Hint);
6052 auto *CS = cast<CapturedStmt>(AStmt);
6063 unsigned NestedLoopCount =
6066 VarsWithImplicitDSA, B);
6067 if (NestedLoopCount == 0)
6070 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6071 "omp parallel for loop exprs were not built");
6073 if (!CurContext->isDependentContext()) {
6076 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6084 setFunctionHasBranchProtectedScope();
6086 NestedLoopCount, Clauses, AStmt, B,
6096 auto *CS = cast<CapturedStmt>(AStmt);
6107 unsigned NestedLoopCount =
6110 VarsWithImplicitDSA, B);
6111 if (NestedLoopCount == 0)
6114 if (!CurContext->isDependentContext()) {
6117 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6128 setFunctionHasBranchProtectedScope();
6130 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6140 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6141 auto BaseStmt = AStmt;
6142 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6144 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6145 auto S =
C->children();
6146 if (S.begin() == S.end())
6150 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6151 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6153 Diag(SectionStmt->getBeginLoc(),
6154 diag::err_omp_parallel_sections_substmt_not_section);
6157 cast<OMPSectionDirective>(SectionStmt)
6158 ->setHasCancel(
DSAStack->isCancelRegion());
6162 diag::err_omp_parallel_sections_not_compound_stmt);
6166 setFunctionHasBranchProtectedScope();
6169 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
6178 auto *CS = cast<CapturedStmt>(AStmt);
6186 setFunctionHasBranchProtectedScope();
6214 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6216 setFunctionHasBranchProtectedScope();
6220 DSAStack->getTaskgroupReductionRef());
6226 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
6235 const OMPClause *DependSourceClause =
nullptr;
6236 const OMPClause *DependSinkClause =
nullptr;
6237 bool ErrorFound =
false;
6241 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
6243 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6244 if (DependSourceClause) {
6245 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
6250 DependSourceClause =
C;
6252 if (DependSinkClause) {
6253 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6257 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6258 if (DependSourceClause) {
6259 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6263 DependSinkClause =
C;
6265 }
else if (
C->getClauseKind() == OMPC_threads) {
6266 TC = cast<OMPThreadsClause>(
C);
6267 }
else if (
C->getClauseKind() == OMPC_simd) {
6268 SC = cast<OMPSIMDClause>(
C);
6271 if (!ErrorFound && !SC &&
6276 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6278 }
else if (DependFound && (TC || SC)) {
6279 Diag(DependFound->
getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6282 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
6284 diag::err_omp_ordered_directive_without_param);
6286 }
else if (TC || Clauses.empty()) {
6287 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
6289 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6291 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6295 if ((!AStmt && !DependFound) || ErrorFound)
6299 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6301 setFunctionHasBranchProtectedScope();
6310 class OpenMPAtomicUpdateChecker {
6312 enum ExprAnalysisErrorCode {
6316 NotABinaryOrUnaryExpression,
6318 NotAnUnaryIncDecExpression,
6324 NotABinaryExpression,
6330 NotAnUpdateExpression,
6348 bool IsXLHSInRHSPart;
6353 bool IsPostfixUpdate;
6356 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
6357 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
6358 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
6366 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
6368 Expr *getX()
const {
return X; }
6370 Expr *getExpr()
const {
return E; }
6374 Expr *getUpdateExpr()
const {
return UpdateExpr; }
6377 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
6381 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
6384 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
6385 unsigned NoteId = 0);
6389 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6391 ExprAnalysisErrorCode ErrorFound = NoError;
6397 if (AtomicBinOp->
getOpcode() == BO_Assign) {
6399 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6401 if (AtomicInnerBinOp->isMultiplicativeOp() ||
6402 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6403 AtomicInnerBinOp->isBitwiseOp()) {
6404 Op = AtomicInnerBinOp->getOpcode();
6405 OpLoc = AtomicInnerBinOp->getOperatorLoc();
6406 Expr *LHS = AtomicInnerBinOp->getLHS();
6407 Expr *RHS = AtomicInnerBinOp->getRHS();
6408 llvm::FoldingSetNodeID XId, LHSId, RHSId;
6417 IsXLHSInRHSPart =
true;
6418 }
else if (XId == RHSId) {
6420 IsXLHSInRHSPart =
false;
6422 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6423 ErrorRange = AtomicInnerBinOp->getSourceRange();
6424 NoteLoc =
X->getExprLoc();
6425 NoteRange =
X->getSourceRange();
6426 ErrorFound = NotAnUpdateExpression;
6429 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6430 ErrorRange = AtomicInnerBinOp->getSourceRange();
6431 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6433 ErrorFound = NotABinaryOperator;
6438 ErrorFound = NotABinaryExpression;
6445 ErrorFound = NotAnAssignmentOp;
6447 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6448 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6449 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6453 E =
X = UpdateExpr =
nullptr;
6454 return ErrorFound != NoError;
6457 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
6459 ExprAnalysisErrorCode ErrorFound = NoError;
6470 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
6471 AtomicBody = AtomicBody->IgnoreParenImpCasts();
6472 if (AtomicBody->getType()->isScalarType() ||
6473 AtomicBody->isInstantiationDependent()) {
6474 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6475 AtomicBody->IgnoreParenImpCasts())) {
6478 AtomicCompAssignOp->getOpcode());
6479 OpLoc = AtomicCompAssignOp->getOperatorLoc();
6480 E = AtomicCompAssignOp->getRHS();
6481 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6482 IsXLHSInRHSPart =
true;
6483 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6484 AtomicBody->IgnoreParenImpCasts())) {
6486 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6488 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6489 AtomicBody->IgnoreParenImpCasts())) {
6491 if (AtomicUnaryOp->isIncrementDecrementOp()) {
6492 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6493 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6494 OpLoc = AtomicUnaryOp->getOperatorLoc();
6495 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6497 IsXLHSInRHSPart =
true;
6499 ErrorFound = NotAnUnaryIncDecExpression;
6500 ErrorLoc = AtomicUnaryOp->getExprLoc();
6501 ErrorRange = AtomicUnaryOp->getSourceRange();
6502 NoteLoc = AtomicUnaryOp->getOperatorLoc();
6505 }
else if (!AtomicBody->isInstantiationDependent()) {
6506 ErrorFound = NotABinaryOrUnaryExpression;
6507 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6508 NoteRange = ErrorRange = AtomicBody->getSourceRange();
6511 ErrorFound = NotAScalarType;
6512 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6513 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6516 ErrorFound = NotAnExpression;
6518 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6520 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6521 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6522 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6526 E =
X = UpdateExpr =
nullptr;
6527 if (ErrorFound == NoError && E &&
X) {
6537 IsXLHSInRHSPart ? OVEExpr : OVEX);
6544 UpdateExpr = Update.
get();
6546 return ErrorFound != NoError;
6556 auto *CS = cast<CapturedStmt>(AStmt);
6565 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
6566 C->getClauseKind() == OMPC_update ||
6567 C->getClauseKind() == OMPC_capture) {
6569 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6571 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6574 AtomicKind =
C->getClauseKind();
6575 AtomicKindLoc =
C->getBeginLoc();
6581 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6582 Body = EWC->getSubExpr();
6588 bool IsXLHSInRHSPart =
false;
6589 bool IsPostfixUpdate =
false;
6612 if (AtomicKind == OMPC_read) {
6619 } ErrorFound = NoError;
6624 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6625 const auto *AtomicBinOp =
6627 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6634 ErrorFound = NotAnLValue;
6642 const Expr *NotScalarExpr =
6646 ErrorFound = NotAScalarType;
6652 }
else if (!AtomicBody->isInstantiationDependent()) {
6653 ErrorFound = NotAnAssignmentOp;
6654 ErrorLoc = AtomicBody->getExprLoc();
6655 ErrorRange = AtomicBody->getSourceRange();
6657 : AtomicBody->getExprLoc();
6659 : AtomicBody->getSourceRange();
6662 ErrorFound = NotAnExpression;
6664 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6666 if (ErrorFound != NoError) {
6667 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6669 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6673 if (CurContext->isDependentContext())
6675 }
else if (AtomicKind == OMPC_write) {
6682 } ErrorFound = NoError;
6687 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6688 const auto *AtomicBinOp =
6690 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6691 X = AtomicBinOp->
getLHS();
6692 E = AtomicBinOp->
getRHS();
6696 ErrorFound = NotAnLValue;
6704 const Expr *NotScalarExpr =
6708 ErrorFound = NotAScalarType;
6714 }
else if (!AtomicBody->isInstantiationDependent()) {
6715 ErrorFound = NotAnAssignmentOp;
6716 ErrorLoc = AtomicBody->getExprLoc();
6717 ErrorRange = AtomicBody->getSourceRange();
6719 : AtomicBody->getExprLoc();
6721 : AtomicBody->getSourceRange();
6724 ErrorFound = NotAnExpression;
6726 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6728 if (ErrorFound != NoError) {
6729 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6731 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6735 if (CurContext->isDependentContext())
6737 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
6746 OpenMPAtomicUpdateChecker Checker(*
this);
6747 if (Checker.checkStatement(
6748 Body, (AtomicKind == OMPC_update)
6749 ? diag::err_omp_atomic_update_not_expression_statement
6750 : diag::err_omp_atomic_not_expression_statement,
6751 diag::note_omp_atomic_update))
6753 if (!CurContext->isDependentContext()) {
6754 E = Checker.getExpr();
6756 UE = Checker.getUpdateExpr();
6757 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6759 }
else if (AtomicKind == OMPC_capture) {
6762 NotACompoundStatement,
6763 NotTwoSubstatements,
6764 NotASpecificExpression,
6766 } ErrorFound = NoError;
6769 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6778 const auto *AtomicBinOp =
6780 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6781 V = AtomicBinOp->
getLHS();
6783 OpenMPAtomicUpdateChecker Checker(*
this);
6784 if (Checker.checkStatement(
6785 Body, diag::err_omp_atomic_capture_not_expression_statement,
6786 diag::note_omp_atomic_update))
6788 E = Checker.getExpr();
6790 UE = Checker.getUpdateExpr();
6791 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6792 IsPostfixUpdate = Checker.isPostfixUpdate();
6793 }
else if (!AtomicBody->isInstantiationDependent()) {
6794 ErrorLoc = AtomicBody->getExprLoc();
6795 ErrorRange = AtomicBody->getSourceRange();
6797 : AtomicBody->getExprLoc();
6799 : AtomicBody->getSourceRange();
6800 ErrorFound = NotAnAssignmentOp;
6802 if (ErrorFound != NoError) {
6803 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6805 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6808 if (CurContext->isDependentContext())
6809 UE = V = E = X =
nullptr;
6827 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
6829 if (CS->size() == 2) {
6831 Stmt *Second = CS->body_back();
6832 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
6833 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6834 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6835 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6837 OpenMPAtomicUpdateChecker Checker(*
this);
6838 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6840 if (IsUpdateExprFound) {
6842 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6844 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6854 llvm::FoldingSetNodeID XId, PossibleXId;
6855 Checker.getX()->Profile(XId, Context,
true);
6856 PossibleX->
Profile(PossibleXId, Context,
true);
6857 IsUpdateExprFound = XId == PossibleXId;
6858 if (IsUpdateExprFound) {
6861 E = Checker.getExpr();
6862 UE = Checker.getUpdateExpr();
6863 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6864 IsPostfixUpdate =
true;
6867 if (!IsUpdateExprFound) {
6868 IsUpdateExprFound = !Checker.checkStatement(First);
6870 if (IsUpdateExprFound) {
6872 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6874 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6884 llvm::FoldingSetNodeID XId, PossibleXId;
6885 Checker.getX()->Profile(XId, Context,
true);
6886 PossibleX->
Profile(PossibleXId, Context,
true);
6887 IsUpdateExprFound = XId == PossibleXId;
6888 if (IsUpdateExprFound) {
6891 E = Checker.getExpr();
6892 UE = Checker.getUpdateExpr();
6893 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6894 IsPostfixUpdate =
false;
6898 if (!IsUpdateExprFound) {
6900 auto *FirstExpr = dyn_cast<
Expr>(
First);
6901 auto *SecondExpr = dyn_cast<
Expr>(Second);
6902 if (!FirstExpr || !SecondExpr ||
6903 !(FirstExpr->isInstantiationDependent() ||
6904 SecondExpr->isInstantiationDependent())) {
6906 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6907 ErrorFound = NotAnAssignmentOp;
6908 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6910 NoteRange = ErrorRange = FirstBinOp
6911 ? FirstBinOp->getSourceRange()
6915 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6916 ErrorFound = NotAnAssignmentOp;
6917 NoteLoc = ErrorLoc = SecondBinOp
6918 ? SecondBinOp->getOperatorLoc()
6920 NoteRange = ErrorRange =
6921 SecondBinOp ? SecondBinOp->getSourceRange()
6924 Expr *PossibleXRHSInFirst =
6926 Expr *PossibleXLHSInSecond =
6928 llvm::FoldingSetNodeID X1Id, X2Id;
6929 PossibleXRHSInFirst->
Profile(X1Id, Context,
6931 PossibleXLHSInSecond->
Profile(X2Id, Context,
6933 IsUpdateExprFound = X1Id == X2Id;
6934 if (IsUpdateExprFound) {
6935 V = FirstBinOp->getLHS();
6936 X = SecondBinOp->getLHS();
6937 E = SecondBinOp->getRHS();
6939 IsXLHSInRHSPart =
false;
6940 IsPostfixUpdate =
true;
6942 ErrorFound = NotASpecificExpression;
6943 ErrorLoc = FirstBinOp->getExprLoc();
6944 ErrorRange = FirstBinOp->getSourceRange();
6945 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6946 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6954 NoteRange = ErrorRange =
6956 ErrorFound = NotTwoSubstatements;
6960 NoteRange = ErrorRange =
6962 ErrorFound = NotACompoundStatement;
6964 if (ErrorFound != NoError) {
6965 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6967 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6970 if (CurContext->isDependentContext())
6971 UE = V = E = X =
nullptr;
6975 setFunctionHasBranchProtectedScope();
6978 X, V, E, UE, IsXLHSInRHSPart,
6989 auto *CS = cast<CapturedStmt>(AStmt);
6996 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6997 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7011 if (
DSAStack->hasInnerTeamsRegion()) {
7013 bool OMPTeamsFound =
true;
7014 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
7015 auto I = CS->body_begin();
7016 while (I != CS->body_end()) {
7019 OMPTeamsFound =
false;
7024 assert(I != CS->body_end() &&
"Not found statement");
7030 if (!OMPTeamsFound) {
7031 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7033 diag::note_omp_nested_teams_construct_here);
7035 << isa<OMPExecutableDirective>(S);
7040 setFunctionHasBranchProtectedScope();
7052 auto *CS = cast<CapturedStmt>(AStmt);
7059 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7060 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7070 setFunctionHasBranchProtectedScope();
7082 auto *CS = cast<CapturedStmt>(AStmt);
7089 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7090 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7103 unsigned NestedLoopCount =
7106 VarsWithImplicitDSA, B);
7107 if (NestedLoopCount == 0)
7110 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7111 "omp target parallel for loop exprs were not built");
7113 if (!CurContext->isDependentContext()) {
7116 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7124 setFunctionHasBranchProtectedScope();
7126 NestedLoopCount, Clauses, AStmt,
7133 return llvm::any_of(
7137 template <
typename... Params>
7139 const Params... ClauseTypes) {
7150 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7154 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7155 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7156 <<
"'map' or 'use_device_ptr'" 7161 setFunctionHasBranchProtectedScope();
7174 auto *CS = cast<CapturedStmt>(AStmt);
7181 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7182 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7195 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7211 auto *CS = cast<CapturedStmt>(AStmt);
7218 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7219 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7232 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7248 auto *CS = cast<CapturedStmt>(AStmt);
7255 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7256 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7266 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
7267 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7280 auto *CS = cast<CapturedStmt>(AStmt);
7288 setFunctionHasBranchProtectedScope();
7290 DSAStack->setParentTeamsRegionLoc(StartLoc);
7299 if (
DSAStack->isParentNowaitRegion()) {
7300 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7303 if (
DSAStack->isParentOrderedRegion()) {
7304 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7315 if (
DSAStack->isParentNowaitRegion()) {
7316 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7319 if (
DSAStack->isParentOrderedRegion()) {
7320 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7323 DSAStack->setParentCancelRegion(
true);
7331 bool ErrorFound =
false;
7333 if (
C->getClauseKind() == OMPC_grainsize ||
7334 C->getClauseKind() == OMPC_num_tasks) {
7338 S.
Diag(
C->getBeginLoc(),
7339 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7343 diag::note_omp_previous_grainsize_num_tasks)
7354 const OMPClause *ReductionClause =
nullptr;
7355 const OMPClause *NogroupClause =
nullptr;
7357 if (
C->getClauseKind() == OMPC_reduction) {
7358 ReductionClause =
C;
7363 if (
C->getClauseKind() == OMPC_nogroup) {
7365 if (ReductionClause)
7370 if (ReductionClause && NogroupClause) {
7371 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7385 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7389 unsigned NestedLoopCount =
7392 VarsWithImplicitDSA, B);
7393 if (NestedLoopCount == 0)
7396 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7397 "omp for loop exprs were not built");
7410 setFunctionHasBranchProtectedScope();
7412 NestedLoopCount, Clauses, AStmt, B);
7421 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7425 unsigned NestedLoopCount =
7428 VarsWithImplicitDSA, B);
7429 if (NestedLoopCount == 0)
7432 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7433 "omp for loop exprs were not built");
7435 if (!CurContext->isDependentContext()) {
7438 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7459 setFunctionHasBranchProtectedScope();
7461 NestedLoopCount, Clauses, AStmt, B);
7470 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7474 unsigned NestedLoopCount =
7477 *
this, *
DSAStack, VarsWithImplicitDSA, B);
7478 if (NestedLoopCount == 0)
7481 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7482 "omp for loop exprs were not built");
7484 setFunctionHasBranchProtectedScope();
7486 NestedLoopCount, Clauses, AStmt, B);
7495 auto *CS = cast<CapturedStmt>(AStmt);
7502 for (
int ThisCaptureLevel =
7503 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7504 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7520 VarsWithImplicitDSA, B);
7521 if (NestedLoopCount == 0)
7524 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7525 "omp for loop exprs were not built");
7527 setFunctionHasBranchProtectedScope();
7529 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7539 auto *CS = cast<CapturedStmt>(AStmt);
7546 for (
int ThisCaptureLevel =
7547 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7548 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7564 VarsWithImplicitDSA, B);
7565 if (NestedLoopCount == 0)
7568 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7569 "omp for loop exprs were not built");
7571 if (!CurContext->isDependentContext()) {
7574 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7585 setFunctionHasBranchProtectedScope();
7587 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7596 auto *CS = cast<CapturedStmt>(AStmt);
7603 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7604 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7617 unsigned NestedLoopCount =
7619 nullptr , CS, *
this,
7620 *
DSAStack, VarsWithImplicitDSA, B);
7621 if (NestedLoopCount == 0)
7624 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7625 "omp for loop exprs were not built");
7627 if (!CurContext->isDependentContext()) {
7630 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7641 setFunctionHasBranchProtectedScope();
7643 NestedLoopCount, Clauses, AStmt, B);
7652 auto *CS = cast<CapturedStmt>(AStmt);
7659 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7660 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7676 VarsWithImplicitDSA, B);
7677 if (NestedLoopCount == 0)
7680 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7681 "omp target parallel for simd loop exprs were not built");
7683 if (!CurContext->isDependentContext()) {
7686 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7696 setFunctionHasBranchProtectedScope();
7698 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7707 auto *CS = cast<CapturedStmt>(AStmt);
7714 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7715 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7728 unsigned NestedLoopCount =
7731 VarsWithImplicitDSA, B);
7732 if (NestedLoopCount == 0)
7735 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7736 "omp target simd loop exprs were not built");
7738 if (!CurContext->isDependentContext()) {
7741 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7752 setFunctionHasBranchProtectedScope();
7754 NestedLoopCount, Clauses, AStmt, B);
7763 auto *CS = cast<CapturedStmt>(AStmt);
7770 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7771 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7784 unsigned NestedLoopCount =
7786 nullptr , CS, *
this,
7787 *
DSAStack, VarsWithImplicitDSA, B);
7788 if (NestedLoopCount == 0)
7791 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7792 "omp teams distribute loop exprs were not built");
7794 setFunctionHasBranchProtectedScope();
7796 DSAStack->setParentTeamsRegionLoc(StartLoc);
7799 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7808 auto *CS = cast<CapturedStmt>(AStmt);
7815 for (
int ThisCaptureLevel =
7816 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7817 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7834 VarsWithImplicitDSA, B);
7836 if (NestedLoopCount == 0)
7839 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7840 "omp teams distribute simd loop exprs were not built");
7842 if (!CurContext->isDependentContext()) {
7845 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7856 setFunctionHasBranchProtectedScope();
7858 DSAStack->setParentTeamsRegionLoc(StartLoc);
7861 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7870 auto *CS = cast<CapturedStmt>(AStmt);
7878 for (
int ThisCaptureLevel =
7879 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7880 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7896 VarsWithImplicitDSA, B);
7898 if (NestedLoopCount == 0)
7901 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7902 "omp for loop exprs were not built");
7904 if (!CurContext->isDependentContext()) {
7907 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7918 setFunctionHasBranchProtectedScope();
7920 DSAStack->setParentTeamsRegionLoc(StartLoc);
7923 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7932 auto *CS = cast<CapturedStmt>(AStmt);
7940 for (
int ThisCaptureLevel =
7941 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7942 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7958 VarsWithImplicitDSA, B);
7960 if (NestedLoopCount == 0)
7963 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7964 "omp for loop exprs were not built");
7966 setFunctionHasBranchProtectedScope();
7968 DSAStack->setParentTeamsRegionLoc(StartLoc);
7971 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7982 auto *CS = cast<CapturedStmt>(AStmt);
7990 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7991 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8000 setFunctionHasBranchProtectedScope();
8012 auto *CS = cast<CapturedStmt>(AStmt);
8019 for (
int ThisCaptureLevel =
8020 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8021 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8037 VarsWithImplicitDSA, B);
8038 if (NestedLoopCount == 0)
8041 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8042 "omp target teams distribute loop exprs were not built");
8044 setFunctionHasBranchProtectedScope();
8046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8055 auto *CS = cast<CapturedStmt>(AStmt);
8062 for (
int ThisCaptureLevel =
8063 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8064 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8080 VarsWithImplicitDSA, B);
8081 if (NestedLoopCount == 0)
8084 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8085 "omp target teams distribute parallel for loop exprs were not built");
8087 if (!CurContext->isDependentContext()) {
8090 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8098 setFunctionHasBranchProtectedScope();
8100 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8110 auto *CS = cast<CapturedStmt>(AStmt);
8117 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(
8118 OMPD_target_teams_distribute_parallel_for_simd);
8119 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8132 unsigned NestedLoopCount =
8135 nullptr , CS, *
this,
8136 *
DSAStack, VarsWithImplicitDSA, B);
8137 if (NestedLoopCount == 0)
8140 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8141 "omp target teams distribute parallel for simd loop exprs were not " 8144 if (!CurContext->isDependentContext()) {
8147 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8158 setFunctionHasBranchProtectedScope();
8160 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8169 auto *CS = cast<CapturedStmt>(AStmt);
8176 for (
int ThisCaptureLevel =
8177 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8178 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8194 VarsWithImplicitDSA, B);
8195 if (NestedLoopCount == 0)
8198 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8199 "omp target teams distribute simd loop exprs were not built");
8201 if (!CurContext->isDependentContext()) {
8204 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8215 setFunctionHasBranchProtectedScope();
8217 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8227 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
8229 case OMPC_num_threads:
8230 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
8233 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
8236 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
8239 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
8242 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
8245 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
8247 case OMPC_num_teams:
8248 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
8250 case OMPC_thread_limit:
8251 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
8254 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
8256 case OMPC_grainsize:
8257 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
8259 case OMPC_num_tasks:
8260 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
8263 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
8267 case OMPC_proc_bind:
8270 case OMPC_firstprivate:
8271 case OMPC_lastprivate:
8273 case OMPC_reduction:
8274 case OMPC_task_reduction:
8275 case OMPC_in_reduction:
8279 case OMPC_copyprivate:
8282 case OMPC_mergeable:
8295 case OMPC_dist_schedule:
8296 case OMPC_defaultmap:
8301 case OMPC_use_device_ptr:
8302 case OMPC_is_device_ptr:
8303 case OMPC_unified_address:
8304 case OMPC_unified_shared_memory:
8305 case OMPC_reverse_offload:
8306 case OMPC_dynamic_allocators:
8307 case OMPC_atomic_default_mem_order:
8308 llvm_unreachable(
"Clause is not allowed.");
8325 case OMPD_target_parallel:
8326 case OMPD_target_parallel_for:
8327 case OMPD_target_parallel_for_simd:
8330 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
8331 CaptureRegion = OMPD_target;
8333 case OMPD_target_teams_distribute_parallel_for:
8334 case OMPD_target_teams_distribute_parallel_for_simd:
8337 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
8338 CaptureRegion = OMPD_teams;
8340 case OMPD_teams_distribute_parallel_for:
8341 case OMPD_teams_distribute_parallel_for_simd:
8342 CaptureRegion = OMPD_teams;
8344 case OMPD_target_update:
8345 case OMPD_target_enter_data:
8346 case OMPD_target_exit_data:
8347 CaptureRegion = OMPD_task;
8351 case OMPD_parallel_sections:
8352 case OMPD_parallel_for:
8353 case OMPD_parallel_for_simd:
8355 case OMPD_target_simd:
8356 case OMPD_target_teams:
8357 case OMPD_target_teams_distribute:
8358 case OMPD_target_teams_distribute_simd:
8359 case OMPD_distribute_parallel_for:
8360 case OMPD_distribute_parallel_for_simd:
8363 case OMPD_taskloop_simd:
8364 case OMPD_target_data:
8367 case OMPD_threadprivate:
8368 case OMPD_taskyield:
8371 case OMPD_cancellation_point:
8373 case OMPD_declare_reduction:
8374 case OMPD_declare_simd:
8375 case OMPD_declare_target:
8376 case OMPD_end_declare_target:
8386 case OMPD_taskgroup:
8387 case OMPD_distribute:
8390 case OMPD_distribute_simd:
8391 case OMPD_teams_distribute:
8392 case OMPD_teams_distribute_simd:
8394 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
8396 llvm_unreachable(
"Unknown OpenMP directive");
8399 case OMPC_num_threads:
8401 case OMPD_target_parallel:
8402 case OMPD_target_parallel_for:
8403 case OMPD_target_parallel_for_simd:
8404 CaptureRegion = OMPD_target;
8406 case OMPD_teams_distribute_parallel_for:
8407 case OMPD_teams_distribute_parallel_for_simd:
8408 case OMPD_target_teams_distribute_parallel_for:
8409 case OMPD_target_teams_distribute_parallel_for_simd:
8410 CaptureRegion = OMPD_teams;
8413 case OMPD_parallel_sections:
8414 case OMPD_parallel_for:
8415 case OMPD_parallel_for_simd:
8416 case OMPD_distribute_parallel_for:
8417 case OMPD_distribute_parallel_for_simd:
8420 case OMPD_target_data:
8421 case OMPD_target_enter_data:
8422 case OMPD_target_exit_data:
8423 case OMPD_target_update:
8425 case OMPD_target_simd:
8426 case OMPD_target_teams:
8427 case OMPD_target_teams_distribute:
8428 case OMPD_target_teams_distribute_simd:
8432 case OMPD_taskloop_simd:
8433 case OMPD_threadprivate:
8434 case OMPD_taskyield:
8437 case OMPD_cancellation_point:
8439 case OMPD_declare_reduction:
8440 case OMPD_declare_simd:
8441 case OMPD_declare_target:
8442 case OMPD_end_declare_target:
8452 case OMPD_taskgroup:
8453 case OMPD_distribute:
8456 case OMPD_distribute_simd:
8457 case OMPD_teams_distribute:
8458 case OMPD_teams_distribute_simd:
8460 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
8462 llvm_unreachable(
"Unknown OpenMP directive");
8465 case OMPC_num_teams:
8467 case OMPD_target_teams:
8468 case OMPD_target_teams_distribute:
8469 case OMPD_target_teams_distribute_simd:
8470 case OMPD_target_teams_distribute_parallel_for:
8471 case OMPD_target_teams_distribute_parallel_for_simd:
8472 CaptureRegion = OMPD_target;
8474 case OMPD_teams_distribute_parallel_for:
8475 case OMPD_teams_distribute_parallel_for_simd:
8477 case OMPD_teams_distribute:
8478 case OMPD_teams_distribute_simd:
8481 case OMPD_distribute_parallel_for:
8482 case OMPD_distribute_parallel_for_simd:
8485 case OMPD_taskloop_simd:
8486 case OMPD_target_data:
8487 case OMPD_target_enter_data:
8488 case OMPD_target_exit_data:
8489 case OMPD_target_update:
8492 case OMPD_parallel_sections:
8493 case OMPD_parallel_for:
8494 case OMPD_parallel_for_simd:
8496 case OMPD_target_simd:
8497 case OMPD_target_parallel:
8498 case OMPD_target_parallel_for:
8499 case OMPD_target_parallel_for_simd:
8500 case OMPD_threadprivate:
8501 case OMPD_taskyield:
8504 case OMPD_cancellation_point:
8506 case OMPD_declare_reduction:
8507 case OMPD_declare_simd:
8508 case OMPD_declare_target:
8509 case OMPD_end_declare_target:
8518 case OMPD_taskgroup:
8519 case OMPD_distribute:
8522 case OMPD_distribute_simd:
8524 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8526 llvm_unreachable(
"Unknown OpenMP directive");
8529 case OMPC_thread_limit:
8531 case OMPD_target_teams:
8532 case OMPD_target_teams_distribute:
8533 case OMPD_target_teams_distribute_simd:
8534 case OMPD_target_teams_distribute_parallel_for:
8535 case OMPD_target_teams_distribute_parallel_for_simd:
8536 CaptureRegion = OMPD_target;
8538 case OMPD_teams_distribute_parallel_for:
8539 case OMPD_teams_distribute_parallel_for_simd:
8541 case OMPD_teams_distribute:
8542 case OMPD_teams_distribute_simd:
8545 case OMPD_distribute_parallel_for:
8546 case OMPD_distribute_parallel_for_simd:
8549 case OMPD_taskloop_simd:
8550 case OMPD_target_data:
8551 case OMPD_target_enter_data:
8552 case OMPD_target_exit_data:
8553 case OMPD_target_update:
8556 case OMPD_parallel_sections:
8557 case OMPD_parallel_for:
8558 case OMPD_parallel_for_simd:
8560 case OMPD_target_simd:
8561 case OMPD_target_parallel:
8562 case OMPD_target_parallel_for:
8563 case OMPD_target_parallel_for_simd:
8564 case OMPD_threadprivate:
8565 case OMPD_taskyield:
8568 case OMPD_cancellation_point:
8570 case OMPD_declare_reduction:
8571 case OMPD_declare_simd:
8572 case OMPD_declare_target:
8573 case OMPD_end_declare_target:
8582 case OMPD_taskgroup:
8583 case OMPD_distribute:
8586 case OMPD_distribute_simd:
8588 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
8590 llvm_unreachable(
"Unknown OpenMP directive");
8595 case OMPD_parallel_for:
8596 case OMPD_parallel_for_simd:
8597 case OMPD_distribute_parallel_for:
8598 case OMPD_distribute_parallel_for_simd:
8599 case OMPD_teams_distribute_parallel_for:
8600 case OMPD_teams_distribute_parallel_for_simd:
8601 case OMPD_target_parallel_for:
8602 case OMPD_target_parallel_for_simd:
8603 case OMPD_target_teams_distribute_parallel_for:
8604 case OMPD_target_teams_distribute_parallel_for_simd:
8605 CaptureRegion = OMPD_parallel;
8613 case OMPD_taskloop_simd:
8614 case OMPD_target_data:
8615 case OMPD_target_enter_data:
8616 case OMPD_target_exit_data:
8617 case OMPD_target_update:
8619 case OMPD_teams_distribute:
8620 case OMPD_teams_distribute_simd:
8621 case OMPD_target_teams_distribute:
8622 case OMPD_target_teams_distribute_simd:
8624 case OMPD_target_simd:
8625 case OMPD_target_parallel:
8628 case OMPD_parallel_sections:
8629 case OMPD_threadprivate:
8630 case OMPD_taskyield:
8633 case OMPD_cancellation_point:
8635 case OMPD_declare_reduction:
8636 case OMPD_declare_simd:
8637 case OMPD_declare_target:
8638 case OMPD_end_declare_target:
8645 case OMPD_taskgroup:
8646 case OMPD_distribute:
8649 case OMPD_distribute_simd:
8650 case OMPD_target_teams:
8652 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8654 llvm_unreachable(
"Unknown OpenMP directive");
8657 case OMPC_dist_schedule:
8659 case OMPD_teams_distribute_parallel_for:
8660 case OMPD_teams_distribute_parallel_for_simd:
8661 case OMPD_teams_distribute:
8662 case OMPD_teams_distribute_simd:
8663 case OMPD_target_teams_distribute_parallel_for:
8664 case OMPD_target_teams_distribute_parallel_for_simd:
8665 case OMPD_target_teams_distribute:
8666 case OMPD_target_teams_distribute_simd:
8667 CaptureRegion = OMPD_teams;
8669 case OMPD_distribute_parallel_for:
8670 case OMPD_distribute_parallel_for_simd:
8671 case OMPD_distribute:
8672 case OMPD_distribute_simd:
8675 case OMPD_parallel_for:
8676 case OMPD_parallel_for_simd:
8677 case OMPD_target_parallel_for_simd:
8678 case OMPD_target_parallel_for:
8681 case OMPD_taskloop_simd:
8682 case OMPD_target_data:
8683 case OMPD_target_enter_data:
8684 case OMPD_target_exit_data:
8685 case OMPD_target_update:
8688 case OMPD_target_simd:
8689 case OMPD_target_parallel:
8692 case OMPD_parallel_sections:
8693 case OMPD_threadprivate:
8694 case OMPD_taskyield:
8697 case OMPD_cancellation_point:
8699 case OMPD_declare_reduction:
8700 case OMPD_declare_simd:
8701 case OMPD_declare_target:
8702 case OMPD_end_declare_target:
8711 case OMPD_taskgroup:
8714 case OMPD_target_teams:
8716 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8718 llvm_unreachable(
"Unknown OpenMP directive");
8723 case OMPD_target_update:
8724 case OMPD_target_enter_data:
8725 case OMPD_target_exit_data:
8727 case OMPD_target_simd:
8728 case OMPD_target_teams:
8729 case OMPD_target_parallel:
8730 case OMPD_target_teams_distribute:
8731 case OMPD_target_teams_distribute_simd:
8732 case OMPD_target_parallel_for:
8733 case OMPD_target_parallel_for_simd:
8734 case OMPD_target_teams_distribute_parallel_for:
8735 case OMPD_target_teams_distribute_parallel_for_simd:
8736 CaptureRegion = OMPD_task;
8738 case OMPD_target_data:
8741 case OMPD_teams_distribute_parallel_for:
8742 case OMPD_teams_distribute_parallel_for_simd:
8744 case OMPD_teams_distribute:
8745 case OMPD_teams_distribute_simd:
8746 case OMPD_distribute_parallel_for:
8747 case OMPD_distribute_parallel_for_simd:
8750 case OMPD_taskloop_simd:
8753 case OMPD_parallel_sections:
8754 case OMPD_parallel_for:
8755 case OMPD_parallel_for_simd:
8756 case OMPD_threadprivate:
8757 case OMPD_taskyield:
8760 case OMPD_cancellation_point:
8762 case OMPD_declare_reduction:
8763 case OMPD_declare_simd:
8764 case OMPD_declare_target:
8765 case OMPD_end_declare_target:
8774 case OMPD_taskgroup:
8775 case OMPD_distribute:
8778 case OMPD_distribute_simd:
8780 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8782 llvm_unreachable(
"Unknown OpenMP directive");
8785 case OMPC_firstprivate:
8786 case OMPC_lastprivate:
8787 case OMPC_reduction:
8788 case OMPC_task_reduction:
8789 case OMPC_in_reduction:
8792 case OMPC_proc_bind:
8801 case OMPC_copyprivate:
8805 case OMPC_mergeable:
8818 case OMPC_grainsize:
8820 case OMPC_num_tasks:
8822 case OMPC_defaultmap:
8827 case OMPC_use_device_ptr:
8828 case OMPC_is_device_ptr:
8829 case OMPC_unified_address:
8830 case OMPC_unified_shared_memory:
8831 case OMPC_reverse_offload:
8832 case OMPC_dynamic_allocators:
8833 case OMPC_atomic_default_mem_order:
8834 llvm_unreachable(
"Unexpected OpenMP clause.");
8836 return CaptureRegion;
8845 Expr *ValExpr = Condition;
8846 Stmt *HelperValStmt =
nullptr;
8851 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8855 ValExpr = Val.
get();
8860 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8861 ValExpr = MakeFullExpr(ValExpr).get();
8862 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8863 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8868 return new (Context)
8869 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8870 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8877 Expr *ValExpr = Condition;
8881 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8885 ValExpr = MakeFullExpr(Val.
get()).
get();
8888 return new (Context)
OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8897 IntConvertDiagnoser()
8901 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
8905 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
8910 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8919 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8928 llvm_unreachable(
"conversion functions are permitted");
8931 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8936 bool StrictlyPositive) {
8945 ValExpr = Value.
get();
8949 Result.isSigned() &&
8950 !((!StrictlyPositive && Result.isNonNegative()) ||
8951 (StrictlyPositive && Result.isStrictlyPositive()))) {
8952 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
8965 Expr *ValExpr = NumThreads;
8966 Stmt *HelperValStmt =
nullptr;
8977 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8978 ValExpr = MakeFullExpr(ValExpr).get();
8979 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8980 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8985 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8990 bool StrictlyPositive) {
8997 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
9000 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
9001 (!StrictlyPositive && !Result.isNonNegative())) {
9002 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
9007 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9012 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
9013 DSAStack->setAssociatedLoops(Result.getExtValue());
9014 else if (CKind == OMPC_ordered)
9015 DSAStack->setAssociatedLoops(Result.getExtValue());
9025 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9028 return new (Context)
9038 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9041 return new (Context)
9055 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9058 return new (Context)
9065 Expr *NumForLoops) {
9071 if (NumForLoops && LParenLoc.
isValid()) {
9073 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9076 NumForLoops = NumForLoopsResult.
get();
9078 NumForLoops =
nullptr;
9081 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
9082 StartLoc, LParenLoc, EndLoc);
9083 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
9094 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9095 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9097 case OMPC_proc_bind:
9098 Res = ActOnOpenMPProcBindClause(
9099 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
9102 case OMPC_atomic_default_mem_order:
9103 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9104 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9105 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9109 case OMPC_num_threads:
9115 case OMPC_firstprivate:
9116 case OMPC_lastprivate:
9118 case OMPC_reduction:
9119 case OMPC_task_reduction:
9120 case OMPC_in_reduction:
9124 case OMPC_copyprivate:
9128 case OMPC_mergeable:
9141 case OMPC_num_teams:
9142 case OMPC_thread_limit:
9144 case OMPC_grainsize:
9146 case OMPC_num_tasks:
9148 case OMPC_dist_schedule:
9149 case OMPC_defaultmap:
9154 case OMPC_use_device_ptr:
9155 case OMPC_is_device_ptr:
9156 case OMPC_unified_address:
9157 case OMPC_unified_shared_memory:
9158 case OMPC_reverse_offload:
9159 case OMPC_dynamic_allocators:
9160 llvm_unreachable(
"Clause is not allowed.");
9169 llvm::raw_svector_ostream Out(Buffer);
9170 unsigned Bound = Last >= 2 ? Last - 2 : 0;
9171 unsigned Skipped = Exclude.size();
9172 auto S = Exclude.begin(), E = Exclude.end();
9173 for (
unsigned I = First; I <
Last; ++I) {
9174 if (std::find(S, E, I) != E) {
9179 if (I == Bound - Skipped)
9181 else if (I != Bound + 1 - Skipped)
9194 "OMPC_DEFAULT_unknown not greater than 0");
9195 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9202 case OMPC_DEFAULT_none:
9203 DSAStack->setDefaultDSANone(KindKwLoc);
9205 case OMPC_DEFAULT_shared:
9206 DSAStack->setDefaultDSAShared(KindKwLoc);
9209 llvm_unreachable(
"Clause kind is not allowed.");
9212 return new (Context)
9222 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9228 return new (Context)
9236 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9238 OMPC_atomic_default_mem_order, 0,
9255 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
9256 assert(Argument.size() == NumberOfElements &&
9257 ArgumentLoc.size() == NumberOfElements);
9258 Res = ActOnOpenMPScheduleClause(
9259 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9260 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9261 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9262 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9263 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9266 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9267 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9268 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9271 case OMPC_dist_schedule:
9272 Res = ActOnOpenMPDistScheduleClause(
9273 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9274 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9276 case OMPC_defaultmap:
9278 Res = ActOnOpenMPDefaultmapClause(
9279 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
9280 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9281 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9285 case OMPC_num_threads:
9290 case OMPC_proc_bind:
9292 case OMPC_firstprivate:
9293 case OMPC_lastprivate:
9295 case OMPC_reduction:
9296 case OMPC_task_reduction:
9297 case OMPC_in_reduction:
9301 case OMPC_copyprivate:
9305 case OMPC_mergeable:
9318 case OMPC_num_teams:
9319 case OMPC_thread_limit:
9321 case OMPC_grainsize:
9323 case OMPC_num_tasks:
9329 case OMPC_use_device_ptr:
9330 case OMPC_is_device_ptr:
9331 case OMPC_unified_address:
9332 case OMPC_unified_shared_memory:
9333 case OMPC_reverse_offload:
9334 case OMPC_dynamic_allocators:
9335 case OMPC_atomic_default_mem_order:
9336 llvm_unreachable(
"Clause is not allowed.");
9347 Excluded.push_back(M2);
9348 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9349 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9350 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9351 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9352 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9375 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9376 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9377 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9378 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9379 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9395 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9402 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9403 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9404 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9405 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9406 diag::err_omp_schedule_nonmonotonic_static);
9409 Expr *ValExpr = ChunkSize;
9410 Stmt *HelperValStmt =
nullptr;
9417 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9421 ValExpr = Val.
get();
9428 if (Result.isSigned() && !Result.isStrictlyPositive()) {
9429 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9434 DSAStack->getCurrentDirective(), OMPC_schedule) !=
9436 !CurContext->isDependentContext()) {
9437 ValExpr = MakeFullExpr(ValExpr).get();
9438 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9439 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
9445 return new (Context)
9447 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9456 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9459 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9462 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9464 case OMPC_mergeable:
9465 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9468 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9471 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9474 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9477 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9480 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9483 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9486 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9489 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9491 case OMPC_unified_address:
9492 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
9494 case OMPC_unified_shared_memory:
9495 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9497 case OMPC_reverse_offload:
9498 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
9500 case OMPC_dynamic_allocators:
9501 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
9505 case OMPC_num_threads:
9511 case OMPC_firstprivate:
9512 case OMPC_lastprivate:
9514 case OMPC_reduction:
9515 case OMPC_task_reduction:
9516 case OMPC_in_reduction:
9520 case OMPC_copyprivate:
9522 case OMPC_proc_bind:
9528 case OMPC_num_teams:
9529 case OMPC_thread_limit:
9531 case OMPC_grainsize:
9532 case OMPC_num_tasks:
9534 case OMPC_dist_schedule:
9535 case OMPC_defaultmap:
9540 case OMPC_use_device_ptr:
9541 case OMPC_is_device_ptr:
9542 case OMPC_atomic_default_mem_order:
9543 llvm_unreachable(
"Clause is not allowed.");
9637 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9639 case OMPC_firstprivate:
9640 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9642 case OMPC_lastprivate:
9643 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9646 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9648 case OMPC_reduction:
9649 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9650 EndLoc, ReductionIdScopeSpec, ReductionId);
9652 case OMPC_task_reduction:
9653 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9654 EndLoc, ReductionIdScopeSpec,
9657 case OMPC_in_reduction:
9659 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9660 EndLoc, ReductionIdScopeSpec, ReductionId);
9663 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9664 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9667 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9671 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9673 case OMPC_copyprivate:
9674 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9677 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9680 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9681 StartLoc, LParenLoc, EndLoc);
9684 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
9685 IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
9686 VarList, StartLoc, LParenLoc, EndLoc);
9689 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9692 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9694 case OMPC_use_device_ptr:
9695 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9697 case OMPC_is_device_ptr:
9698 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9702 case OMPC_num_threads:
9707 case OMPC_proc_bind:
9712 case OMPC_mergeable:
9722 case OMPC_num_teams:
9723 case OMPC_thread_limit:
9725 case OMPC_grainsize:
9727 case OMPC_num_tasks:
9729 case OMPC_dist_schedule:
9730 case OMPC_defaultmap:
9733 case OMPC_unified_address:
9734 case OMPC_unified_shared_memory:
9735 case OMPC_reverse_offload:
9736 case OMPC_dynamic_allocators:
9737 case OMPC_atomic_default_mem_order:
9738 llvm_unreachable(
"Clause is not allowed.");
9749 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
9750 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
9755 Res = DefaultLvalueConversion(Res.
get());
9762 static std::pair<ValueDecl *, bool>
9764 SourceRange &ERange,
bool AllowArraySection =
false) {
9767 return std::make_pair(
nullptr,
true);
9779 } IsArrayExpr = NoArrayExpr;
9780 if (AllowArraySection) {
9781 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9782 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
9783 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9786 IsArrayExpr = ArraySubscript;
9787 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9788 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
9789 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9791 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9794 IsArrayExpr = OMPArraySection;
9800 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9801 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9802 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9804 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9805 !isa<FieldDecl>(ME->getMemberDecl()))) {
9806 if (IsArrayExpr != NoArrayExpr) {
9807 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9812 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9813 : diag::err_omp_expected_var_name_member_expr)
9816 return std::make_pair(
nullptr,
false);
9818 return std::make_pair(
9828 for (
Expr *RefExpr : VarList) {
9829 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
9832 Expr *SimpleRefExpr = RefExpr;
9836 Vars.push_back(RefExpr);
9837 PrivateCopies.push_back(
nullptr);
9844 auto *VD = dyn_cast<
VarDecl>(D);
9849 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9871 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9872 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
9883 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9890 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9900 if (
DSAStack->checkMappableExprComponentListsForDecl(
9904 ConflictKind = WhereFoundClauseKind;
9907 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9929 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
9930 ActOnUninitializedDecl(VDPrivate);
9937 if (!VD && !CurContext->isDependentContext())
9939 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9940 Vars.push_back((VD || CurContext->isDependentContext())
9941 ? RefExpr->IgnoreParens()
9943 PrivateCopies.push_back(VDPrivateRefExpr);
9954 class DiagsUninitializedSeveretyRAII {
9958 bool IsIgnored =
false;
9963 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9965 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
9969 ~DiagsUninitializedSeveretyRAII() {
9984 bool IsImplicitClause =
9988 for (
Expr *RefExpr : VarList) {
9989 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
9992 Expr *SimpleRefExpr = RefExpr;
9996 Vars.push_back(RefExpr);
9997 PrivateCopies.push_back(
nullptr);
9998 Inits.push_back(
nullptr);
10004 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
10006 auto *VD = dyn_cast<
VarDecl>(D);
10011 if (RequireCompleteType(ELoc, Type,
10012 diag::err_omp_firstprivate_incomplete_type))
10023 DSAStackTy::DSAVarData TopDVar;
10024 if (!IsImplicitClause) {
10025 DSAStackTy::DSAVarData DVar =
10029 bool IsConstant = ElemType.
isConstant(Context);
10037 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10039 DVar.CKind != OMPC_lastprivate) &&
10041 Diag(ELoc, diag::err_omp_wrong_dsa)
10059 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10060 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
10061 Diag(ELoc, diag::err_omp_wrong_dsa)
10087 DVar =
DSAStack->getImplicitDSA(D,
true);
10088 if (DVar.CKind != OMPC_shared &&
10092 Diag(ELoc, diag::err_omp_required_access)
10119 if (DVar.CKind == OMPC_reduction &&
10123 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10135 if (
DSAStack->checkMappableExprComponentListsForDecl(
10140 ConflictKind = WhereFoundClauseKind;
10143 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10156 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10163 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10172 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
10178 Expr *VDInitRefExpr =
nullptr;
10185 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10188 ".firstprivate.temp");
10203 ".firstprivate.temp");
10205 RefExpr->getExprLoc());
10206 AddInitializerToDecl(VDPrivate,
10207 DefaultLvalueConversion(VDInitRefExpr).
get(),
10211 if (IsImplicitClause) {
10212 Diag(RefExpr->getExprLoc(),
10213 diag::note_omp_task_predetermined_firstprivate_here);
10217 CurContext->addDecl(VDPrivate);
10220 RefExpr->getExprLoc());
10222 if (!VD && !CurContext->isDependentContext()) {
10223 if (TopDVar.CKind == OMPC_lastprivate) {
10224 Ref = TopDVar.PrivateCopy;
10227 if (!isOpenMPCapturedDecl(D))
10228 ExprCaptures.push_back(Ref->getDecl());
10231 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10232 Vars.push_back((VD || CurContext->isDependentContext())
10233 ? RefExpr->IgnoreParens()
10235 PrivateCopies.push_back(VDPrivateRefExpr);
10236 Inits.push_back(VDInitRefExpr);
10243 Vars, PrivateCopies, Inits,
10257 for (
Expr *RefExpr : VarList) {
10258 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
10261 Expr *SimpleRefExpr = RefExpr;
10265 Vars.push_back(RefExpr);
10266 SrcExprs.push_back(
nullptr);
10267 DstExprs.push_back(
nullptr);
10268 AssignmentOps.push_back(
nullptr);
10275 auto *VD = dyn_cast<
VarDecl>(D);
10280 if (RequireCompleteType(ELoc, Type,
10281 diag::err_omp_lastprivate_incomplete_type))
10305 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10306 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10308 DVar.CKind != OMPC_firstprivate) &&
10309 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
10310 Diag(ELoc, diag::err_omp_wrong_dsa)
10323 DSAStackTy::DSAVarData TopDVar = DVar;
10327 DVar =
DSAStack->getImplicitDSA(D,
true);
10328 if (DVar.CKind != OMPC_shared) {
10329 Diag(ELoc, diag::err_omp_required_access)
10357 ExprResult AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
10358 PseudoDstExpr, PseudoSrcExpr);
10362 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
10367 if (!VD && !CurContext->isDependentContext()) {
10368 if (TopDVar.CKind == OMPC_firstprivate) {
10369 Ref = TopDVar.PrivateCopy;
10372 if (!isOpenMPCapturedDecl(D))
10373 ExprCaptures.push_back(Ref->
getDecl());
10375 if (TopDVar.CKind == OMPC_firstprivate ||
10376 (!isOpenMPCapturedDecl(D) &&
10378 ExprResult RefRes = DefaultLvalueConversion(Ref);
10382 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10386 ExprPostUpdates.push_back(
10387 IgnoredValueConversions(PostUpdateRes.
get()).
get());
10390 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10391 Vars.push_back((VD || CurContext->isDependentContext())
10392 ? RefExpr->IgnoreParens()
10394 SrcExprs.push_back(PseudoSrcExpr);
10395 DstExprs.push_back(PseudoDstExpr);
10396 AssignmentOps.push_back(AssignmentOp.
get());
10403 Vars, SrcExprs, DstExprs, AssignmentOps,
10413 for (
Expr *RefExpr : VarList) {
10414 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
10417 Expr *SimpleRefExpr = RefExpr;
10421 Vars.push_back(RefExpr);
10427 auto *VD = dyn_cast<
VarDecl>(D);
10435 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10436 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
10445 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10447 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10448 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10449 ? RefExpr->IgnoreParens()
10460 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
10465 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
10466 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
10467 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10471 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10478 bool VisitStmt(
Stmt *S) {
10480 if (Child && Visit(Child))
10485 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10492 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
10499 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
10504 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
10505 return CapturedExpr;
10507 return BaseTransform::TransformMemberExpr(E);
10509 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
10513 template <
typename T,
typename U>
10515 const llvm::function_ref<T(
ValueDecl *)> Gen) {
10516 for (U &Set : Lookups) {
10517 for (
auto *D : Set) {
10518 if (T Res = Gen(cast<ValueDecl>(D)))
10528 for (
auto RD : D->
redecls()) {
10533 auto ND = cast<NamedDecl>(RD);
10551 AssociatedClasses);
10564 for (
auto *NS : AssociatedNamespaces) {
10577 for (
auto *D : R) {
10578 auto *Underlying = D;
10579 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
10580 Underlying = USD->getTargetDecl();
10582 if (!isa<OMPDeclareReductionDecl>(Underlying))
10589 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
10590 Underlying = USD->getTargetDecl();
10592 Lookups.emplace_back();
10593 Lookups.back().addDecl(Underlying);
10616 Lookups.emplace_back();
10617 Lookups.back().append(Lookup.
begin(), Lookup.
end());
10620 }
else if (
auto *ULE =
10621 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10623 Decl *PrevD =
nullptr;
10627 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
10628 Lookups.back().addDecl(DRD);
10635 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) {
10645 ResSet.
append(Set.begin(), Set.end());
10647 ResSet.
addDecl(Set[Set.size() - 1]);
10652 true,
true, ResSet.
begin(), ResSet.
end());
10668 Lookup.suppressDiagnostics();
10672 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
10673 TyRec->getDecl()->getDefinition()) {
10676 if (Lookup.empty()) {
10677 Lookups.emplace_back();
10678 Lookups.back().append(Lookup.begin(), Lookup.end());
10684 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10692 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10702 if (SemaRef.
IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10704 VD->getType().getUnqualifiedType()))) {
10714 if (ReductionIdScopeSpec.
isSet()) {
10715 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10723 struct ReductionData {
10741 ReductionData() =
delete;
10743 ReductionData(
unsigned Size) {
10744 Vars.reserve(Size);
10745 Privates.reserve(Size);
10746 LHSs.reserve(Size);
10747 RHSs.reserve(Size);
10748 ReductionOps.reserve(Size);
10749 TaskgroupDescriptors.reserve(Size);
10750 ExprCaptures.reserve(Size);
10751 ExprPostUpdates.reserve(Size);
10755 void push(
Expr *Item,
Expr *ReductionOp) {
10756 Vars.emplace_back(Item);
10757 Privates.emplace_back(
nullptr);
10758 LHSs.emplace_back(
nullptr);
10759 RHSs.emplace_back(
nullptr);
10760 ReductionOps.emplace_back(ReductionOp);
10761 TaskgroupDescriptors.emplace_back(
nullptr);
10765 Expr *TaskgroupDescriptor) {
10766 Vars.emplace_back(Item);
10767 Privates.emplace_back(Private);
10768 LHSs.emplace_back(LHS);
10769 RHSs.emplace_back(RHS);
10770 ReductionOps.emplace_back(ReductionOp);
10771 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10780 if (Length ==
nullptr) {
10787 SingleElement =
true;
10788 ArraySizes.push_back(llvm::APSInt::get(1));
10794 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
10795 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10796 ArraySizes.push_back(ConstantLengthValue);
10804 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10805 Length = TempOASE->getLength();
10806 if (Length ==
nullptr) {
10813 ArraySizes.push_back(llvm::APSInt::get(1));
10819 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
10820 if (ConstantLengthValue.getSExtValue() != 1)
10823 ArraySizes.push_back(ConstantLengthValue);
10829 if (!SingleElement) {
10830 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10832 ArraySizes.push_back(llvm::APSInt::get(1));
10886 case OO_Array_Delete:
10895 case OO_GreaterEqual:
10897 case OO_MinusEqual:
10899 case OO_SlashEqual:
10900 case OO_PercentEqual:
10901 case OO_CaretEqual:
10905 case OO_GreaterGreater:
10906 case OO_LessLessEqual:
10907 case OO_GreaterGreaterEqual:
10908 case OO_EqualEqual:
10909 case OO_ExclaimEqual:
10912 case OO_MinusMinus:
10918 case OO_Conditional:
10921 llvm_unreachable(
"Unexpected reduction identifier");
10924 if (II->isStr(
"max"))
10926 else if (II->isStr(
"min"))
10932 if (ReductionIdScopeSpec.
isValid())
10938 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10939 bool FirstIter =
true;
10940 for (
Expr *RefExpr : VarList) {
10941 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
10949 if (!FirstIter && IR != ER)
10954 Expr *SimpleRefExpr = RefExpr;
10963 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10964 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10965 Expr *ReductionOp =
nullptr;
10967 (DeclareReductionRef.
isUnset() ||
10968 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
10969 ReductionOp = DeclareReductionRef.
get();
10971 RD.push(RefExpr, ReductionOp);
10977 Expr *TaskgroupDescriptor =
nullptr;
10982 Type = ASE->getType().getNonReferenceType();
10987 Type = ATy->getElementType();
10994 auto *VD = dyn_cast<
VarDecl>(D);
11000 diag::err_omp_reduction_incomplete_type))
11006 false, ASE || OASE))
11013 if (!ASE && !OASE) {
11016 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
11017 DSARefChecker Check(Stack);
11018 if (Check.Visit(VDDef->
getInit())) {
11019 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11038 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
11039 if (DVar.CKind == OMPC_reduction) {
11040 S.
Diag(ELoc, diag::err_omp_once_referenced)
11043 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11047 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
11061 DVar = Stack->getImplicitDSA(D,
true);
11062 if (DVar.CKind != OMPC_shared) {
11063 S.
Diag(ELoc, diag::err_omp_required_access)
11076 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11077 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11081 (DeclareReductionRef.
isUnset() ||
11082 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
11083 RD.push(RefExpr, DeclareReductionRef.
get());
11086 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
11088 S.
Diag(ReductionId.getBeginLoc(),
11089 diag::err_omp_unknown_reduction_identifier)
11090 << Type << ReductionIdRange;
11102 if (DeclareReductionRef.
isUnset()) {
11103 if ((BOK == BO_GT || BOK == BO_LT) &&
11104 !(Type->isScalarType() ||
11105 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11106 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11108 if (!ASE && !OASE) {
11109 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11112 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11117 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11118 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
11119 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11121 if (!ASE && !OASE) {
11122 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11125 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11132 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11141 bool ConstantLengthOASE =
false;
11143 bool SingleElement;
11146 Context, OASE, SingleElement, ArraySizes);
11149 if (ConstantLengthOASE && !SingleElement) {
11150 for (llvm::APSInt &Size : ArraySizes)
11156 if ((OASE && !ConstantLengthOASE) ||
11161 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11162 S.
Diag(ELoc, diag::note_vla_unsupported);
11174 }
else if (!ASE && !OASE &&
11182 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11184 Expr *Init =
nullptr;
11187 if (DeclareReductionRef.
isUsable()) {
11189 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11190 if (DRD->getInitializer()) {
11192 RHSVD->setInit(DRDRef);
11202 if (Type->isScalarType() || Type->isAnyComplexType())
11207 if (Type->isScalarType() || Type->isAnyComplexType()) {
11216 Type = ComplexTy->getElementType();
11217 if (Type->isRealFloatingType()) {
11218 llvm::APFloat InitValue =
11219 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
11223 }
else if (Type->isScalarType()) {
11226 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11243 if (Type->isIntegerType() || Type->isPointerType()) {
11248 llvm::APInt InitValue =
11249 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11250 : llvm::APInt::getMinValue(Size)
11251 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11252 : llvm::APInt::getMaxValue(Size);
11254 if (Type->isPointerType()) {
11260 Init = CastExpr.
get();
11262 }
else if (Type->isRealFloatingType()) {
11263 llvm::APFloat InitValue = llvm::APFloat::getLargest(
11294 llvm_unreachable(
"Unexpected reduction operation");
11297 if (Init && DeclareReductionRef.
isUnset())
11301 if (RHSVD->isInvalidDecl())
11303 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
11304 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11305 << Type << ReductionIdRange;
11306 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11309 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11315 PrivateVD->
setInit(RHSVD->getInit());
11319 if (DeclareReductionRef.
isUsable()) {
11320 QualType RedTy = DeclareReductionRef.
get()->getType();
11324 if (!BasePath.empty()) {
11328 CK_UncheckedDerivedToBase, LHS.
get(),
11329 &BasePath, LHS.
get()->getValueKind());
11331 CK_UncheckedDerivedToBase, RHS.get(),
11332 &BasePath, RHS.get()->getValueKind());
11335 QualType Params[] = {PtrRedTy, PtrRedTy};
11345 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11347 if (BOK != BO_LT && BOK != BO_GT) {
11349 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11350 BO_Assign, LHSDRE, ReductionOp.
get());
11352 auto *ConditionalOp =
new (Context)
11356 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11357 BO_Assign, LHSDRE, ConditionalOp);
11374 if (ClauseKind == OMPC_in_reduction) {
11377 const Expr *ParentReductionOp;
11378 Expr *ParentBOKTD, *ParentReductionOpTD;
11379 DSAStackTy::DSAVarData ParentBOKDSA =
11380 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11382 DSAStackTy::DSAVarData ParentReductionOpDSA =
11383 Stack->getTopMostTaskgroupReductionData(
11384 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11385 bool IsParentBOK = ParentBOKDSA.DKind !=
OMPD_unknown;
11386 bool IsParentReductionOp = ParentReductionOpDSA.DKind !=
OMPD_unknown;
11387 if (!IsParentBOK && !IsParentReductionOp) {
11388 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11391 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
11392 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
11393 IsParentReductionOp) {
11394 bool EmitError =
true;
11395 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
11396 llvm::FoldingSetNodeID RedId, ParentRedId;
11397 ParentReductionOp->
Profile(ParentRedId, Context,
true);
11398 DeclareReductionRef.
get()->Profile(RedId, Context,
11400 EmitError = RedId != ParentRedId;
11403 S.
Diag(ReductionId.getBeginLoc(),
11404 diag::err_omp_reduction_identifier_mismatch)
11405 << ReductionIdRange << RefExpr->getSourceRange();
11407 diag::note_omp_previous_reduction_identifier)
11409 << (IsParentBOK ? ParentBOKDSA.RefExpr
11410 : ParentReductionOpDSA.RefExpr)
11411 ->getSourceRange();
11415 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11416 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
11423 TransformExprToCaptures RebuildToCapture(S, D);
11425 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
11426 Ref = RebuildToCapture.getCapturedExpr();
11428 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
11431 RD.ExprCaptures.emplace_back(Ref->
getDecl());
11437 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11442 Stack->getCurrentDirective() == OMPD_taskgroup) {
11443 S.
Diag(RefExpr->getExprLoc(),
11444 diag::err_omp_reduction_non_addressable_expression)
11445 << RefExpr->getSourceRange();
11448 RD.ExprPostUpdates.emplace_back(
11455 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11456 if (CurrDir == OMPD_taskgroup) {
11457 if (DeclareReductionRef.
isUsable())
11458 Stack->addTaskgroupReductionData(D, ReductionIdRange,
11459 DeclareReductionRef.
get());
11461 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11463 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
11464 TaskgroupDescriptor);
11466 return RD.Vars.empty();
11474 ReductionData RD(VarList.size());
11476 StartLoc, LParenLoc, ColonLoc, EndLoc,
11477 ReductionIdScopeSpec, ReductionId,
11478 UnresolvedReductions, RD))
11482 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11484 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11494 ReductionData RD(VarList.size());
11496 StartLoc, LParenLoc, ColonLoc, EndLoc,
11497 ReductionIdScopeSpec, ReductionId,
11498 UnresolvedReductions, RD))
11502 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11504 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11514 ReductionData RD(VarList.size());
11516 StartLoc, LParenLoc, ColonLoc, EndLoc,
11517 ReductionIdScopeSpec, ReductionId,
11518 UnresolvedReductions, RD))
11522 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11524 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
11531 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
11533 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
11542 const auto *VD = dyn_cast_or_null<VarDecl>(D);
11544 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
11546 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
11548 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
11564 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11565 !Ty->isPointerType())) {
11566 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11572 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11589 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11590 LinKind = OMPC_LINEAR_val;
11591 for (
Expr *RefExpr : VarList) {
11592 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11595 Expr *SimpleRefExpr = RefExpr;
11599 Vars.push_back(RefExpr);
11600 Privates.push_back(
nullptr);
11601 Inits.push_back(
nullptr);
11608 auto *VD = dyn_cast<
VarDecl>(D);
11614 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
11615 if (DVar.RefExpr) {
11622 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11630 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11636 if (!VD && !CurContext->isDependentContext()) {
11638 if (!isOpenMPCapturedDecl(D)) {
11639 ExprCaptures.push_back(Ref->
getDecl());
11641 ExprResult RefRes = DefaultLvalueConversion(Ref);
11645 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
11646 SimpleRefExpr, RefRes.
get());
11649 ExprPostUpdates.push_back(
11650 IgnoredValueConversions(PostUpdateRes.
get()).
get());
11654 if (LinKind == OMPC_LINEAR_uval)
11655 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11657 InitExpr = VD ? SimpleRefExpr : Ref;
11658 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
11662 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11663 Vars.push_back((VD || CurContext->isDependentContext())
11664 ? RefExpr->IgnoreParens()
11666 Privates.push_back(PrivateRef);
11667 Inits.push_back(InitRef);
11674 Expr *CalcStepExpr =
nullptr;
11679 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11682 StepExpr = Val.
get();
11690 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11691 CalcStep = ActOnFinishFullExpr(CalcStep.get(),
false);
11697 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11698 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11699 << (Vars.size() > 1);
11700 if (!IsConstant && CalcStep.isUsable()) {
11703 CalcStepExpr = CalcStep.get();
11708 ColonLoc, EndLoc, Vars, Privates, Inits,
11709 StepExpr, CalcStepExpr,
11715 Expr *NumIterations,
Sema &SemaRef,
11716 Scope *S, DSAStackTy *Stack) {
11727 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
11728 bool HasErrors =
false;
11729 auto CurInit = Clause.inits().begin();
11730 auto CurPrivate = Clause.privates().begin();
11735 Expr *SimpleRefExpr = RefExpr;
11736 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
11738 if (Res.second || !D) {
11739 Updates.push_back(
nullptr);
11740 Finals.push_back(
nullptr);
11744 auto &&Info = Stack->isLoopControlVariable(D);
11751 diag::err_omp_linear_distribute_var_non_loop_iteration);
11752 Updates.push_back(
nullptr);
11753 Finals.push_back(
nullptr);
11757 Expr *InitExpr = *CurInit;
11760 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11762 if (LinKind == OMPC_LINEAR_uval)
11763 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11767 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11775 InitExpr, IV,
Step,
false);
11777 Update = *CurPrivate;
11786 InitExpr, NumIterations,
Step,
false);
11788 Final = *CurPrivate;
11792 if (!Update.isUsable() || !Final.isUsable()) {
11793 Updates.push_back(
nullptr);
11794 Finals.push_back(
nullptr);
11797 Updates.push_back(Update.get());
11798 Finals.push_back(Final.get());
11803 Clause.setUpdates(Updates);
11804 Clause.setFinals(Finals);
11812 for (
Expr *RefExpr : VarList) {
11813 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11816 Expr *SimpleRefExpr = RefExpr;
11820 Vars.push_back(RefExpr);
11827 auto *VD = dyn_cast<
VarDecl>(D);
11833 const Type *Ty = QType.getTypePtrOrNull();
11835 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11836 << QType << getLangOpts().CPlusPlus << ERange;
11841 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11848 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11849 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11850 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11856 if (!VD && isOpenMPCapturedDecl(D))
11858 Vars.push_back(DefaultFunctionArrayConversion(
11859 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11868 if (Alignment !=
nullptr) {
11870 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11873 Alignment = AlignResult.
get();
11879 EndLoc, Vars, Alignment);
11890 for (
Expr *RefExpr : VarList) {
11891 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
11892 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11894 Vars.push_back(RefExpr);
11895 SrcExprs.push_back(
nullptr);
11896 DstExprs.push_back(
nullptr);
11897 AssignmentOps.push_back(
nullptr);
11907 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11908 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11909 << 0 << RefExpr->getSourceRange();
11913 Decl *D = DE->getDecl();
11914 auto *VD = cast<VarDecl>(D);
11917 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11919 Vars.push_back(DE);
11920 SrcExprs.push_back(
nullptr);
11921 DstExprs.push_back(
nullptr);
11922 AssignmentOps.push_back(
nullptr);
11928 if (!
DSAStack->isThreadPrivate(VD)) {
11929 Diag(ELoc, diag::err_omp_required_access)
11942 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11946 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
11947 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11953 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11955 if (AssignmentOp.isInvalid())
11957 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11959 if (AssignmentOp.isInvalid())
11962 DSAStack->addDSA(VD, DE, OMPC_copyin);
11963 Vars.push_back(DE);
11964 SrcExprs.push_back(PseudoSrcExpr);
11965 DstExprs.push_back(PseudoDstExpr);
11966 AssignmentOps.push_back(AssignmentOp.get());
11973 SrcExprs, DstExprs, AssignmentOps);
11984 for (
Expr *RefExpr : VarList) {
11985 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11988 Expr *SimpleRefExpr = RefExpr;
11992 Vars.push_back(RefExpr);
11993 SrcExprs.push_back(
nullptr);
11994 DstExprs.push_back(
nullptr);
11995 AssignmentOps.push_back(
nullptr);
12002 auto *VD = dyn_cast<
VarDecl>(D);
12007 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
12008 DSAStackTy::DSAVarData DVar =
12010 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12012 Diag(ELoc, diag::err_omp_wrong_dsa)
12023 DVar =
DSAStack->getImplicitDSA(D,
false);
12024 if (DVar.CKind == OMPC_shared) {
12025 Diag(ELoc, diag::err_omp_required_access)
12027 <<
"threadprivate or private in the enclosing context";
12036 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12043 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12053 .getUnqualifiedType();
12055 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.src",
12059 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.dst",
12063 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12067 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
12073 assert(VD || isOpenMPCapturedDecl(D));
12075 VD ? RefExpr->IgnoreParens()
12077 SrcExprs.push_back(PseudoSrcExpr);
12078 DstExprs.push_back(PseudoDstExpr);
12079 AssignmentOps.push_back(AssignmentOp.
get());
12086 Vars, SrcExprs, DstExprs, AssignmentOps);
12093 if (VarList.empty())
12104 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
12105 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12106 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12110 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
12112 DepKind == OMPC_DEPEND_sink)) {
12113 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
12114 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12122 llvm::APSInt DepCounter(32);
12123 llvm::APSInt TotalDepCount(32);
12124 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12125 if (
const Expr *OrderedCountExpr =
12126 DSAStack->getParentOrderedRegionParam().first) {
12127 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12128 TotalDepCount.setIsUnsigned(
true);
12131 for (
Expr *RefExpr : VarList) {
12132 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
12133 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12135 Vars.push_back(RefExpr);
12141 if (DepKind == OMPC_DEPEND_sink) {
12142 if (
DSAStack->getParentOrderedRegionParam().first &&
12143 DepCounter >= TotalDepCount) {
12144 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12156 if (CurContext->isDependentContext()) {
12158 Vars.push_back(RefExpr);
12164 Expr *LHS = SimpleExpr;
12165 Expr *RHS =
nullptr;
12166 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12168 OOLoc = BO->getOperatorLoc();
12171 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12172 OOK = OCE->getOperator();
12173 OOLoc = OCE->getOperatorLoc();
12176 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12177 OOK = MCE->getMethodDecl()
12180 .getCXXOverloadedOperator();
12181 OOLoc = MCE->getCallee()->getExprLoc();
12190 Vars.push_back(RefExpr);
12196 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
12197 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12201 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12202 RHS, OMPC_depend,
false);
12206 if (!CurContext->isDependentContext() &&
12207 DSAStack->getParentOrderedRegionParam().first &&
12208 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
12210 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12212 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12215 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12218 OpsOffs.emplace_back(RHS, OOK);
12221 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12223 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12224 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12225 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12226 << RefExpr->getSourceRange();
12229 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12230 getDiagnostics().setSuppressAllDiagnostics(
true);
12232 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12233 getDiagnostics().setSuppressAllDiagnostics(Suppress);
12234 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12235 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12236 << RefExpr->getSourceRange();
12240 Vars.push_back(RefExpr->IgnoreParenImpCasts());
12243 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12244 TotalDepCount > VarList.size() &&
12245 DSAStack->getParentOrderedRegionParam().first &&
12246 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12247 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12248 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12250 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12255 DepKind, DepLoc, ColonLoc, Vars,
12256 TotalDepCount.getZExtValue());
12257 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12258 DSAStack->isParentOrderedRegion())
12259 DSAStack->addDoacrossDependClause(
C, OpsOffs);
12266 Expr *ValExpr = Device;
12267 Stmt *HelperValStmt =
nullptr;
12278 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12279 ValExpr = MakeFullExpr(ValExpr).get();
12280 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12281 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12285 return new (Context)
OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12286 StartLoc, LParenLoc, EndLoc);
12291 bool FullCheck =
true) {
12294 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
12299 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12314 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12315 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
12316 return ATy->getSize().getSExtValue() != 1;
12321 assert(OASE &&
"Expecting array section if not an array subscript.");
12322 const Expr *LowerBound = OASE->getLowerBound();
12323 const Expr *Length = OASE->getLength();
12332 llvm::APSInt ConstLowerBound = Result.
Val.
getInt();
12333 if (ConstLowerBound.getSExtValue())
12356 llvm::APSInt ConstLength = Result.
Val.
getInt();
12357 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12370 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12373 assert(OASE &&
"Expecting array section if not an array subscript.");
12374 const Expr *Length = OASE->getLength();
12380 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
12381 return ATy->getSize().getSExtValue() != 1;
12391 llvm::APSInt ConstLength = Result.
Val.
getInt();
12392 return ConstLength.getSExtValue() != 1;
12425 const Expr *RelevantExpr =
nullptr;
12444 bool AllowUnitySizeArraySection =
true;
12445 bool AllowWholeSizeArraySection =
true;
12447 while (!RelevantExpr) {
12450 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12451 if (!isa<VarDecl>(CurE->getDecl()))
12454 RelevantExpr = CurE;
12458 AllowUnitySizeArraySection =
false;
12459 AllowWholeSizeArraySection =
false;
12462 CurComponents.emplace_back(CurE, CurE->getDecl());
12463 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
12466 if (isa<CXXThisExpr>(BaseE))
12468 RelevantExpr = CurE;
12472 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12474 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12475 << CurE->getSourceRange();
12483 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12488 if (FD->isBitField()) {
12490 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12510 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
12511 << CurE->getSourceRange();
12524 AllowUnitySizeArraySection =
false;
12525 AllowWholeSizeArraySection =
false;
12528 CurComponents.emplace_back(CurE, FD);
12529 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
12534 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
12535 << 0 << CurE->getSourceRange();
12546 AllowWholeSizeArraySection =
false;
12548 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12550 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.
getASTContext())) {
12551 if (!Result.
Val.
getInt().isNullValue()) {
12552 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
12553 diag::err_omp_invalid_map_this_expr);
12554 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
12555 diag::note_omp_invalid_subscript_on_this_ptr_map);
12562 CurComponents.emplace_back(CurE,
nullptr);
12563 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
12564 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
12579 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
12580 << 0 << CurE->getSourceRange();
12589 if (AllowWholeSizeArraySection) {
12596 if (NotWhole || IsPointer)
12597 AllowWholeSizeArraySection =
false;
12598 }
else if (AllowUnitySizeArraySection && NotUnity) {
12602 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12603 << CurE->getSourceRange();
12607 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12610 if (CurE->getLength()->EvaluateAsInt(ResultR,
12612 if (!ResultR.
Val.
getInt().isOneValue()) {
12613 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
12614 diag::err_omp_invalid_map_this_expr);
12615 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
12616 diag::note_omp_invalid_length_on_this_ptr_mapping);
12619 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
12621 if (!ResultL.
Val.
getInt().isNullValue()) {
12622 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
12623 diag::err_omp_invalid_map_this_expr);
12624 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
12625 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
12632 CurComponents.emplace_back(CurE,
nullptr);
12637 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12644 return RelevantExpr;
12651 bool CurrentRegionOnly,
12662 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
12663 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12664 "Map clause expression with unexpected base!");
12667 bool IsEnclosedByDataEnvironmentExpr =
false;
12668 const Expr *EnclosingExpr =
nullptr;
12670 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12671 VD, CurrentRegionOnly,
12672 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12673 ERange, CKind, &EnclosingExpr,
12677 assert(!StackComponents.empty() &&
12678 "Map clause expression with no components!");
12679 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12680 "Map clause expression with unexpected base!");
12684 const Expr *RE = StackComponents.front().getAssociatedExpression();
12690 auto CI = CurComponents.rbegin();
12691 auto CE = CurComponents.rend();
12692 auto SI = StackComponents.rbegin();
12693 auto SE = StackComponents.rend();
12694 for (; CI != CE && SI != SE; ++CI, ++SI) {
12699 if (CurrentRegionOnly &&
12700 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12701 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12702 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12703 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12704 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
12705 diag::err_omp_multiple_array_items_in_map_clause)
12706 << CI->getAssociatedExpression()->getSourceRange();
12707 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
12708 diag::note_used_here)
12709 << SI->getAssociatedExpression()->getSourceRange();
12714 if (CI->getAssociatedExpression()->getStmtClass() !=
12715 SI->getAssociatedExpression()->getStmtClass())
12719 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12725 for (; SI != SE; ++SI) {
12727 if (
const auto *ASE =
12728 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12729 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12730 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12731 SI->getAssociatedExpression())) {
12738 SemaRef, SI->getAssociatedExpression(), Type))
12748 if (CI == CE && SI == SE) {
12749 if (CurrentRegionOnly) {
12750 if (CKind == OMPC_map) {
12751 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12753 assert(CKind == OMPC_to || CKind == OMPC_from);
12754 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12757 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12758 << RE->getSourceRange();
12763 IsEnclosedByDataEnvironmentExpr =
true;
12768 std::prev(CI)->getAssociatedDeclaration()->getType();
12770 std::prev(CI)->getAssociatedExpression()->getExprLoc();
12789 if (CI == CE || SI == SE) {
12792 diag::err_omp_pointer_mapped_along_with_derived_section)
12794 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12795 << RE->getSourceRange();
12798 if (CI->getAssociatedExpression()->getStmtClass() !=
12799 SI->getAssociatedExpression()->getStmtClass() ||
12800 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12801 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12802 assert(CI != CE && SI != SE);
12803 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12805 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12806 << RE->getSourceRange();
12816 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12817 if (CKind == OMPC_map) {
12818 if (CI != CE || SI != SE) {
12822 CI != CE ? CurComponents.begin() : StackComponents.begin();
12823 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
12825 while (It !=
End && !It->getAssociatedDeclaration())
12826 std::advance(It, 1);
12827 assert(It !=
End &&
12828 "Expected at least one component with the declaration.");
12829 if (It !=
Begin && It->getAssociatedDeclaration()
12831 .getCanonicalType()
12832 ->isAnyPointerType()) {
12833 IsEnclosedByDataEnvironmentExpr =
false;
12834 EnclosingExpr =
nullptr;
12838 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12840 assert(CKind == OMPC_to || CKind == OMPC_from);
12841 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12844 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12845 << RE->getSourceRange();
12851 if (!CurrentRegionOnly && SI != SE)
12852 EnclosingExpr = RE;
12856 IsEnclosedByDataEnvironmentExpr |=
12857 (!CurrentRegionOnly && CI != CE && SI == SE);
12862 if (CurrentRegionOnly)
12876 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12878 diag::err_omp_original_storage_is_shared_and_does_not_contain)
12891 struct MappableVarListInfo {
12904 VarComponents.reserve(VarList.size());
12905 VarBaseDeclarations.reserve(VarList.size());
12920 bool IsMapTypeImplicit =
false) {
12922 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12923 "Unexpected clause kind with mappable expressions!");
12931 for (
Expr *RE : MVLI.VarList) {
12932 assert(RE &&
"Null expr in omp to/from/map clause");
12942 MVLI.ProcessedVarList.push_back(RE);
12950 diag::err_omp_expected_named_var_member_or_array_expression)
12961 SemaRef, SimpleExpr, CurComponents, CKind,
false);
12965 assert(!CurComponents.empty() &&
12966 "Invalid mappable expression information.");
12968 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
12970 DSAS->addMappedClassesQualTypes(TE->getType());
12972 MVLI.ProcessedVarList.push_back(RE);
12973 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12974 MVLI.VarComponents.back().append(CurComponents.begin(),
12975 CurComponents.end());
12976 MVLI.VarBaseDeclarations.push_back(
nullptr);
12983 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12984 assert(CurDeclaration &&
"Null decl on map clause.");
12987 "Expecting components to have associated only canonical declarations.");
12989 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
12990 const auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
12992 assert((VD || FD) &&
"Only variables or fields are expected here!");
12999 if (VD && DSAS->isThreadPrivate(VD)) {
13000 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
13001 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
13016 true, CurComponents, CKind))
13018 if (CKind == OMPC_map &&
13020 false, CurComponents, CKind))
13027 auto I = llvm::find_if(
13032 assert(I != CurComponents.end() &&
"Null decl on map clause.");
13034 I->getAssociatedDeclaration()->getType().getNonReferenceType();
13044 if (CKind == OMPC_map) {
13050 if (DKind == OMPD_target_enter_data &&
13051 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13052 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13053 << (IsMapTypeImplicit ? 1 : 0)
13063 if (DKind == OMPD_target_exit_data &&
13064 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13065 MapType == OMPC_MAP_delete)) {
13066 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13067 << (IsMapTypeImplicit ? 1 : 0)
13077 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
13079 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13090 MVLI.ProcessedVarList.push_back(RE);
13094 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13100 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13101 MVLI.VarComponents.back().append(CurComponents.begin(),
13102 CurComponents.end());
13103 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 13115 MappableVarListInfo MVLI(VarList);
13117 MapType, IsMapTypeImplicit);
13124 unsigned Count = 0;
13125 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
13126 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13127 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13128 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13132 "Modifiers exceed the allowed number of map type modifiers");
13133 Modifiers[Count] = MapTypeModifiers[I];
13134 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13141 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13142 MVLI.VarComponents, Modifiers, ModifiersLoc,
13143 MapType, IsMapTypeImplicit, MapLoc);
13150 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
13151 if (ReductionType.isNull())
13158 if (ReductionType.hasQualifiers()) {
13159 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13163 if (ReductionType->isFunctionType()) {
13164 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13167 if (ReductionType->isReferenceType()) {
13168 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13171 if (ReductionType->isArrayType()) {
13172 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13175 return ReductionType;
13180 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
13183 Decls.reserve(ReductionTypes.size());
13186 forRedeclarationInCurContext());
13191 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13193 bool InCompoundScope =
true;
13194 if (S !=
nullptr) {
13200 LookupName(Lookup, S);
13201 FilterLookupForScope(Lookup, DC, S,
false,
13203 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13206 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.
next());
13207 if (InCompoundScope) {
13208 auto I = UsedAsPrevious.find(PrevDecl);
13209 if (I == UsedAsPrevious.end())
13210 UsedAsPrevious[PrevDecl] =
false;
13212 UsedAsPrevious[D] =
true;
13214 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13215 PrevDecl->getLocation();
13218 if (InCompoundScope) {
13219 for (
const auto &PrevData : UsedAsPrevious) {
13220 if (!PrevData.second) {
13221 PrevDRD = PrevData.first;
13226 }
else if (PrevDeclInScope !=
nullptr) {
13227 auto *PrevDRDInScope = PrevDRD =
13228 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13230 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13232 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13233 }
while (PrevDRDInScope !=
nullptr);
13235 for (
const auto &TyData : ReductionTypes) {
13236 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13237 bool Invalid =
false;
13238 if (I != PreviousRedeclTypes.end()) {
13239 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13241 Diag(I->second, diag::note_previous_definition);
13244 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13246 Name, TyData.first, PrevDRD);
13248 DRD->setAccess(AS);
13249 Decls.push_back(DRD);
13251 DRD->setInvalidDecl();
13256 return DeclGroupPtrTy::make(
13261 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13264 PushFunctionScope();
13265 setFunctionHasBranchProtectedScope();
13266 getCurFunction()->setHasOMPDeclareReductionCombiner();
13269 PushDeclContext(S, DRD);
13273 PushExpressionEvaluationContext(
13274 ExpressionEvaluationContext::PotentiallyEvaluated);
13276 QualType ReductionType = DRD->getType();
13293 if (S !=
nullptr) {
13294 PushOnScopeChains(OmpInParm, S);
13295 PushOnScopeChains(OmpOutParm, S);
13297 DRD->addDecl(OmpInParm);
13298 DRD->addDecl(OmpOutParm);
13304 DRD->setCombinerData(InE, OutE);
13308 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13309 DiscardCleanupsInEvaluationContext();
13310 PopExpressionEvaluationContext();
13313 PopFunctionScopeInfo();
13315 if (Combiner !=
nullptr)
13316 DRD->setCombiner(Combiner);
13318 DRD->setInvalidDecl();
13322 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13325 PushFunctionScope();
13326 setFunctionHasBranchProtectedScope();
13329 PushDeclContext(S, DRD);
13333 PushExpressionEvaluationContext(
13334 ExpressionEvaluationContext::PotentiallyEvaluated);
13336 QualType ReductionType = DRD->getType();
13353 if (S !=
nullptr) {
13354 PushOnScopeChains(OmpPrivParm, S);
13355 PushOnScopeChains(OmpOrigParm, S);
13357 DRD->addDecl(OmpPrivParm);
13358 DRD->addDecl(OmpOrigParm);
13364 DRD->setInitializerData(OrigE, PrivE);
13365 return OmpPrivParm;
13370 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13371 DiscardCleanupsInEvaluationContext();
13372 PopExpressionEvaluationContext();
13375 PopFunctionScopeInfo();
13377 if (Initializer !=
nullptr) {
13379 }
else if (OmpPrivParm->
hasInit()) {
13380 DRD->setInitializer(OmpPrivParm->
getInit(),
13385 DRD->setInvalidDecl();
13391 for (
Decl *D : DeclReductions.
get()) {
13394 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
13400 return DeclReductions;
13407 Expr *ValExpr = NumTeams;
13408 Stmt *HelperValStmt =
nullptr;
13419 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
13420 ValExpr = MakeFullExpr(ValExpr).get();
13421 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13422 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13427 StartLoc, LParenLoc, EndLoc);
13434 Expr *ValExpr = ThreadLimit;
13435 Stmt *HelperValStmt =
nullptr;
13446 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
13447 ValExpr = MakeFullExpr(ValExpr).get();
13448 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13449 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13454 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13461 Expr *ValExpr = Priority;
13476 Expr *ValExpr = Grainsize;
13492 Expr *ValExpr = NumTasks;
13510 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
13513 return new (Context)
13522 std::string Values;
13526 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13530 Expr *ValExpr = ChunkSize;
13531 Stmt *HelperValStmt =
nullptr;
13538 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13542 ValExpr = Val.
get();
13549 if (Result.isSigned() && !Result.isStrictlyPositive()) {
13550 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13555 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
13557 !CurContext->isDependentContext()) {
13558 ValExpr = MakeFullExpr(ValExpr).get();
13559 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13560 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13566 return new (Context)
13568 Kind, ValExpr, HelperValStmt);
13576 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
13580 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
13582 OMPC_DEFAULTMAP_MODIFIER_tofrom);
13586 OMPC_DEFAULTMAP_scalar);
13590 Diag(Loc, diag::err_omp_unexpected_clause_value)
13594 DSAStack->setDefaultDMAToFromScalar(StartLoc);
13596 return new (Context)
13601 DeclContext *CurLexicalContext = getCurLexicalContext();
13605 !isa<CXXRecordDecl>(CurLexicalContext) &&
13606 !isa<ClassTemplateDecl>(CurLexicalContext) &&
13607 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
13608 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
13609 Diag(Loc, diag::err_omp_region_not_file_context);
13612 ++DeclareTargetNestingLevel;
13617 assert(DeclareTargetNestingLevel > 0 &&
13618 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
13619 --DeclareTargetNestingLevel;
13625 OMPDeclareTargetDeclAttr::MapTypeTy MT,
13628 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
13636 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr,
13637 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
13638 CTK_ErrorRecovery)) {
13639 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
13641 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
13650 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
13651 isa<FunctionTemplateDecl>(ND)) {
13655 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
13656 cast<ValueDecl>(ND));
13658 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13661 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13662 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Id.
getLoc());
13663 }
else if (*Res != MT) {
13664 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
13674 if (!D || !isa<VarDecl>(D))
13676 auto *VD = cast<VarDecl>(D);
13677 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
13679 SemaRef.
Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
13680 SemaRef.
Diag(SL, diag::note_used_here) << SR;
13684 Sema &SemaRef, DSAStackTy *Stack,
13686 return VD->
hasAttr<OMPDeclareTargetDeclAttr>() ||
13697 if (
auto *VD = dyn_cast<VarDecl>(D)) {
13699 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
13700 !VD->isStaticDataMember())
13704 if (
DSAStack->isThreadPrivate(VD)) {
13705 Diag(SL, diag::err_omp_threadprivate_in_target);
13710 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13711 D = FTD->getTemplatedDecl();
13712 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
13714 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
13715 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
13716 assert(IdLoc.
isValid() &&
"Source location is expected");
13717 Diag(IdLoc, diag::err_omp_function_in_link_clause);
13718 Diag(FD->getLocation(), diag::note_defined_here) << FD;
13722 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
13728 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
13730 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13731 isa<FunctionTemplateDecl>(D)) {
13732 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13733 Context, OMPDeclareTargetDeclAttr::MT_To);
13736 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13750 MappableVarListInfo MVLI(VarList);
13752 if (MVLI.ProcessedVarList.empty())
13756 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13757 MVLI.VarComponents);
13764 MappableVarListInfo MVLI(VarList);
13766 if (MVLI.ProcessedVarList.empty())
13770 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13771 MVLI.VarComponents);
13778 MappableVarListInfo MVLI(VarList);
13782 for (
Expr *RefExpr : VarList) {
13783 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
13786 Expr *SimpleRefExpr = RefExpr;
13790 MVLI.ProcessedVarList.push_back(RefExpr);
13791 PrivateCopies.push_back(
nullptr);
13792 Inits.push_back(
nullptr);
13801 auto *VD = dyn_cast<
VarDecl>(D);
13805 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13806 << 0 << RefExpr->getSourceRange();
13814 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
13815 if (VDPrivate->isInvalidDecl())
13818 CurContext->addDecl(VDPrivate);
13820 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13824 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
13826 *
this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13827 AddInitializerToDecl(VDPrivate,
13828 DefaultLvalueConversion(VDInitRefExpr).
get(),
13836 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13837 PrivateCopies.push_back(VDPrivateRefExpr);
13838 Inits.push_back(VDInitRefExpr);
13843 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13847 MVLI.VarBaseDeclarations.push_back(D);
13848 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13849 MVLI.VarComponents.back().push_back(
13853 if (MVLI.ProcessedVarList.empty())
13857 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13858 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13865 MappableVarListInfo MVLI(VarList);
13866 for (
Expr *RefExpr : VarList) {
13867 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
13870 Expr *SimpleRefExpr = RefExpr;
13874 MVLI.ProcessedVarList.push_back(RefExpr);
13884 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13885 << 0 << RefExpr->getSourceRange();
13891 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
13893 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13901 const Expr *ConflictExpr;
13902 if (
DSAStack->checkMappableExprComponentListsForDecl(
13907 ConflictExpr = R.front().getAssociatedExpression();
13910 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13919 DSAStack->addMappableExpressionComponents(
13920 D, MC, OMPC_is_device_ptr);
13923 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13928 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13929 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13930 "Unexpected device pointer expression!");
13931 MVLI.VarBaseDeclarations.push_back(
13932 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
13933 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13934 MVLI.VarComponents.back().push_back(MC);
13937 if (MVLI.ProcessedVarList.empty())
13941 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13942 MVLI.VarBaseDeclarations, MVLI.VarComponents);
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
QualType withConst() const
Retrieves a version of this type with const applied.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
void setImplicit(bool I=true)
Represents a function declaration or definition.
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'task_reduction' clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
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)
SourceLocation getExprLoc() const
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.
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
bool EvaluateAsInt(EvalResult &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...
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Filter makeFilter()
Create a filter for this result set.
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc...
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
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, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
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.
static constexpr unsigned NumberOfModifiers
Number of allowed map-type-modifiers.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents 'if' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
This represents 'priority' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
const TargetInfo & getTargetInfo() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
void setInitStyle(InitializationStyle Style)
Describes the capture of a variable or of this, or of a C++1y init-capture.
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)
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Retains information about a function, method, or block that is currently being parsed.
void setNothrow(bool Nothrow=true)
This represents 'read' clause in the '#pragma omp atomic' directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
bool isEnumeralType() const
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
const T * getAs() const
Member-template getAs<specific type>'.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Extra information about a function prototype.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isInvalidDecl() const
void setBegin(SourceLocation b)
static const Expr * getExprAsWritten(const Expr *E)
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
bool hasDefinition() const
This represents 'reverse_offload' clause in the '#pragma omp requires' directive. ...
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
Struct that defines common infrastructure to handle mappable expressions used in OpenMP clauses...
This represents 'nogroup' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * LastIteration
Loop last iteration number.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void ActOnUninitializedDecl(Decl *dcl)
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
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)
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
One of these records is kept for each identifier that is lexed.
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D)
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
The results of name lookup within a DeclContext.
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.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Represents a member of a struct/union/class.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement...
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause *> Clauses)
End of OpenMP region.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
bool isReferenceType() const
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Defines some OpenMP-specific enums and functions.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
Expr * getSafelen() const
Return safe iteration space distance.
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl *> PreInits)
Build preinits statement for the given declarations.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp critical' directive.
void EndOpenMPClause()
End analysis of clauses.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
DeclClass * getAsSingle() const
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
bool isCompleteType(SourceLocation Loc, QualType T)
Represents the results of name lookup.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct...
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
APValue Val
Val - This is the value the expression can be folded to.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
ValueDecl * getAssociatedDeclaration() const
Concrete class used by the front-end to report problems and issues.
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
Look up the name of an OpenMP user-defined reduction operation.
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
This represents 'default' clause in the '#pragma omp ...' directive.
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Scope - A scope is a transient data structure that is used while parsing the program.
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses)
Creates directive with a list of Clauses.
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Represents a C++ nested-name-specifier or a global scope specifier.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
const LangOptions & getLangOpts() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
bool isScalarType() const
An ordinary object is located at an address in memory.
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
Represents the body of a CapturedStmt, and serves as its DeclContext.
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Expr * Cond
Loop condition.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
DiagnosticsEngine & getDiagnostics() const
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Expr * PreCond
Loop pre-condition.
OpenMP 4.0 [2.4, Array Sections].
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause *> Clauses)
ConditionalOperator - The ?: ternary operator.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Describes the capture of either a variable, or 'this', or variable-length array type.
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)
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * DistCond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct whe...
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.
This represents '#pragma omp requires...' directive.
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
Allows QualTypes to be sorted and hence used in maps and sets.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Allow any unmodeled side effect.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
const T * castAs() const
Member-template castAs<specific type>.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
OpenMPClauseKind
OpenMP clauses.
bool isFileContext() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
SourceLocation getBeginLoc() const
DeclContext * getDeclContext()
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
bool isAnyComplexType() const
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is used in 'private' clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
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.
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
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.
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
Expr * ParForInDistCond
'omp parallel for' loop condition used when composed with 'omp distribute' in the same construct and ...
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'in_reduction' clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
This represents 'collapse' clause in the '#pragma omp ...' directive.
Represents a C++ conversion function within a class.
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
The result type of a method or function.
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause *> ClauseList)
Called on well-formed '#pragma omp requires'.
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause *> Clauses)
Check restrictions on Requires directive.
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.
This represents 'unified_address' clause in the '#pragma omp requires' directive. ...
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
This captures a statement into a function.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
QualType getCanonicalType() const
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
ASTContext & getASTContext() const
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
SourceLocation getOperatorLoc() const
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
This represents '#pragma omp declare reduction ...' directive.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Pseudo declaration for capturing expressions.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
This is a basic class for representing single OpenMP executable directive.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents 'schedule' clause in the '#pragma omp ...' directive.
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr *> PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
IdentifierTable & getIdentifierTable()
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getColonLoc() const
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
This file defines OpenMP nodes for declarative directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
This is a basic class for representing single OpenMP clause.
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const
Return true if the provided declaration VD should be captured by reference.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
bool isAnyPointerType() const
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
A class for iterating through a result set and possibly filtering out results.
This declaration is only a declaration.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
DefaultMapAttributes
Attributes of the defaultmap clause.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
QualType withRestrict() const
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
This represents 'device' clause in the '#pragma omp ...' directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
EvalResult is a struct with detailed info about an evaluated expression.
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
const Scope * getParent() const
getParent - Return the scope that this is nested in.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
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.
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)
bool shouldDiagnoseTargetSupportFromOpenMP() const
Return true if (un)supported features for the current target should be diagnosed if OpenMP (offloadin...
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'use_device_ptr' clause.
This represents clause 'linear' in the '#pragma omp ...' directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is captured by 'target' directive.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
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.
SourceLocation getEndLoc() const
Returns the ending location of the clause.
Class that represents a component of a mappable expression.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
Not an overloaded operator.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. '#pragme omp end declare target'.
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.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S'...
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'is_device_ptr' clause.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Expr * Inc
Loop increment.
DeclContext * getCurLexicalContext() const
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'to' clause.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
ImplicitParamDecl * getParam(unsigned i) const
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build 'VarRef = Start.
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
void addDecl(Decl *D)
Add the declaration D into this context.
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause *> CL)
Create requires node.
Capturing the *this object by reference.
This represents 'write' clause in the '#pragma omp atomic' directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
const Type * getTypePtrOrNull() const
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
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)
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
void Deallocate(void *Ptr) const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
This represents 'nowait' clause in the '#pragma omp ...' directive.
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the '#pragma omp declare target'.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
sema::FunctionScopeInfo * getCurFunction() const
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Do not present this diagnostic, ignore it.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed '#pragma omp threadprivate'.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
__DEVICE__ int max(int __a, int __b)
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct...
Stmt * PreInits
Init statement for all captured expressions.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
bool isStaticDataMember() const
Determines whether this is a static data member.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
bool empty() const
Return true if no decls were found.
An l-value expression is a reference to an object with independent storage.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'from' clause.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
A trivial tuple used to represent a source range.
This represents a decl that may have a name.
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
static T filterLookupForUDR(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
bool isConstant(const ASTContext &Ctx) const
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
static OMPClauseWithPostUpdate * get(OMPClause *C)
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
Describes an entity that is being initialized.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of ':'.
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp threadprivate ...' directive.
VerifyDiagnosticConsumer::Directive Directive
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Represents the canonical version of C arrays with a specified constant size.
bool getSuppressAllDiagnostics() const
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
SourceLocation getLocation() const
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
Expr * getLength()
Get length of array section.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.