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(),
5401 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5405 "Unexpected number of parameters in loop combined directive");
5432 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5443 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5453 ? SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get())
5454 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5455 NumIterations.
get());
5460 CurScope, CondLoc, BO_LT, IV.get(), NumIterations.
get());
5466 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.
get());
5471 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5475 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
5484 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5513 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
5524 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
5537 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
5539 DistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.
get());
5540 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
5543 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
5544 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5545 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5548 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
5556 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
5557 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
5564 SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.
get());
5568 bool HasErrors =
false;
5569 Built.
Counters.resize(NestedLoopCount);
5570 Built.
Inits.resize(NestedLoopCount);
5571 Built.
Updates.resize(NestedLoopCount);
5572 Built.
Finals.resize(NestedLoopCount);
5590 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5591 LoopIterationSpace &IS = IterSpaces[Cnt];
5598 for (
unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5599 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
5600 IterSpaces[K].NumIterations);
5605 if (Cnt + 1 < NestedLoopCount)
5606 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div,
5619 if (Cnt + 1 < NestedLoopCount)
5620 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul,
5624 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub,
5628 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5630 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5633 IS.CounterInit, Captures);
5634 if (!Init.isUsable()) {
5639 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5640 IS.CounterStep, IS.Subtract, &Captures);
5648 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5649 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5660 Built.
Counters[Cnt] = IS.CounterVar;
5662 Built.
Inits[Cnt] = Init.get();
5677 Built.
PreCond = PreCond.get();
5682 Built.
LB = LB.
get();
5683 Built.
UB = UB.
get();
5684 Built.
IL = IL.
get();
5685 Built.
ST = ST.
get();
5687 Built.
NLB = NextLB.
get();
5688 Built.
NUB = NextUB.
get();
5703 return NestedLoopCount;
5707 auto CollapseClauses =
5708 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5709 if (CollapseClauses.begin() != CollapseClauses.end())
5710 return (*CollapseClauses.begin())->getNumForLoops();
5715 auto OrderedClauses =
5716 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5717 if (OrderedClauses.begin() != OrderedClauses.end())
5718 return (*OrderedClauses.begin())->getNumForLoops();
5727 for (
const OMPClause *Clause : Clauses) {
5729 Safelen = cast<OMPSafelenClause>(Clause);
5731 Simdlen = cast<OMPSimdlenClause>(Clause);
5732 if (Safelen && Simdlen)
5736 if (Simdlen && Safelen) {
5750 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
5751 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
5756 if (SimdlenRes > SafelenRes) {
5758 diag::err_omp_wrong_simdlen_safelen_values)
5773 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5779 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5780 if (NestedLoopCount == 0)
5783 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5784 "omp simd loop exprs were not built");
5786 if (!CurContext->isDependentContext()) {
5789 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5800 setFunctionHasBranchProtectedScope();
5812 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5818 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
5819 if (NestedLoopCount == 0)
5822 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5823 "omp for loop exprs were not built");
5825 if (!CurContext->isDependentContext()) {
5828 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5836 setFunctionHasBranchProtectedScope();
5838 Clauses, AStmt, B,
DSAStack->isCancelRegion());
5847 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5851 unsigned NestedLoopCount =
5854 VarsWithImplicitDSA, B);
5855 if (NestedLoopCount == 0)
5858 assert((CurContext->isDependentContext() || B.
builtAll()) &&
5859 "omp for simd loop exprs were not built");
5861 if (!CurContext->isDependentContext()) {
5864 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
5875 setFunctionHasBranchProtectedScope();
5887 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5888 auto BaseStmt = AStmt;
5889 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5891 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5892 auto S =
C->children();
5893 if (S.begin() == S.end())
5897 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5898 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5900 Diag(SectionStmt->getBeginLoc(),
5901 diag::err_omp_sections_substmt_not_section);
5904 cast<OMPSectionDirective>(SectionStmt)
5905 ->setHasCancel(
DSAStack->isCancelRegion());
5912 setFunctionHasBranchProtectedScope();
5924 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5926 setFunctionHasBranchProtectedScope();
5940 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5942 setFunctionHasBranchProtectedScope();
5948 for (
const OMPClause *Clause : Clauses) {
5952 Copyprivate = Clause;
5953 if (Copyprivate && Nowait) {
5955 diag::err_omp_single_copyprivate_with_nowait);
5970 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5972 setFunctionHasBranchProtectedScope();
5983 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5985 bool ErrorFound =
false;
5988 bool DependentHint =
false;
5990 if (
C->getClauseKind() == OMPC_hint) {
5992 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
5995 Expr *E = cast<OMPHintClause>(
C)->getHint();
5998 DependentHint =
true;
6001 HintLoc =
C->getBeginLoc();
6007 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
6008 if (Pair.first && DirName.
getName() && !DependentHint) {
6009 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6010 Diag(StartLoc, diag::err_omp_critical_with_hint);
6012 Diag(HintLoc, diag::note_omp_critical_hint_here)
6013 << 0 << Hint.toString(10,
false);
6015 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6016 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
6017 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
6019 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
6022 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6027 setFunctionHasBranchProtectedScope();
6031 if (!Pair.first && DirName.
getName() && !DependentHint)
6032 DSAStack->addCriticalWithHint(Dir, Hint);
6042 auto *CS = cast<CapturedStmt>(AStmt);
6053 unsigned NestedLoopCount =
6056 VarsWithImplicitDSA, B);
6057 if (NestedLoopCount == 0)
6060 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6061 "omp parallel for loop exprs were not built");
6063 if (!CurContext->isDependentContext()) {
6066 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6074 setFunctionHasBranchProtectedScope();
6076 NestedLoopCount, Clauses, AStmt, B,
6086 auto *CS = cast<CapturedStmt>(AStmt);
6097 unsigned NestedLoopCount =
6100 VarsWithImplicitDSA, B);
6101 if (NestedLoopCount == 0)
6104 if (!CurContext->isDependentContext()) {
6107 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6118 setFunctionHasBranchProtectedScope();
6120 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6130 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6131 auto BaseStmt = AStmt;
6132 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6134 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6135 auto S =
C->children();
6136 if (S.begin() == S.end())
6140 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6141 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6143 Diag(SectionStmt->getBeginLoc(),
6144 diag::err_omp_parallel_sections_substmt_not_section);
6147 cast<OMPSectionDirective>(SectionStmt)
6148 ->setHasCancel(
DSAStack->isCancelRegion());
6152 diag::err_omp_parallel_sections_not_compound_stmt);
6156 setFunctionHasBranchProtectedScope();
6159 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
6168 auto *CS = cast<CapturedStmt>(AStmt);
6176 setFunctionHasBranchProtectedScope();
6204 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6206 setFunctionHasBranchProtectedScope();
6210 DSAStack->getTaskgroupReductionRef());
6216 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
6225 const OMPClause *DependSourceClause =
nullptr;
6226 const OMPClause *DependSinkClause =
nullptr;
6227 bool ErrorFound =
false;
6231 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
6233 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6234 if (DependSourceClause) {
6235 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
6240 DependSourceClause =
C;
6242 if (DependSinkClause) {
6243 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6247 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6248 if (DependSourceClause) {
6249 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6253 DependSinkClause =
C;
6255 }
else if (
C->getClauseKind() == OMPC_threads) {
6256 TC = cast<OMPThreadsClause>(
C);
6257 }
else if (
C->getClauseKind() == OMPC_simd) {
6258 SC = cast<OMPSIMDClause>(
C);
6261 if (!ErrorFound && !SC &&
6266 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6268 }
else if (DependFound && (TC || SC)) {
6269 Diag(DependFound->
getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6272 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
6274 diag::err_omp_ordered_directive_without_param);
6276 }
else if (TC || Clauses.empty()) {
6277 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
6279 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6281 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6285 if ((!AStmt && !DependFound) || ErrorFound)
6289 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6291 setFunctionHasBranchProtectedScope();
6300 class OpenMPAtomicUpdateChecker {
6302 enum ExprAnalysisErrorCode {
6306 NotABinaryOrUnaryExpression,
6308 NotAnUnaryIncDecExpression,
6314 NotABinaryExpression,
6320 NotAnUpdateExpression,
6338 bool IsXLHSInRHSPart;
6343 bool IsPostfixUpdate;
6346 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
6347 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
6348 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
6356 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
6358 Expr *getX()
const {
return X; }
6360 Expr *getExpr()
const {
return E; }
6364 Expr *getUpdateExpr()
const {
return UpdateExpr; }
6367 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
6371 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
6374 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
6375 unsigned NoteId = 0);
6379 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6381 ExprAnalysisErrorCode ErrorFound = NoError;
6387 if (AtomicBinOp->
getOpcode() == BO_Assign) {
6389 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6391 if (AtomicInnerBinOp->isMultiplicativeOp() ||
6392 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6393 AtomicInnerBinOp->isBitwiseOp()) {
6394 Op = AtomicInnerBinOp->getOpcode();
6395 OpLoc = AtomicInnerBinOp->getOperatorLoc();
6396 Expr *LHS = AtomicInnerBinOp->getLHS();
6397 Expr *RHS = AtomicInnerBinOp->getRHS();
6398 llvm::FoldingSetNodeID XId, LHSId, RHSId;
6407 IsXLHSInRHSPart =
true;
6408 }
else if (XId == RHSId) {
6410 IsXLHSInRHSPart =
false;
6412 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6413 ErrorRange = AtomicInnerBinOp->getSourceRange();
6414 NoteLoc =
X->getExprLoc();
6415 NoteRange =
X->getSourceRange();
6416 ErrorFound = NotAnUpdateExpression;
6419 ErrorLoc = AtomicInnerBinOp->getExprLoc();
6420 ErrorRange = AtomicInnerBinOp->getSourceRange();
6421 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6423 ErrorFound = NotABinaryOperator;
6428 ErrorFound = NotABinaryExpression;
6435 ErrorFound = NotAnAssignmentOp;
6437 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6438 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6439 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6443 E =
X = UpdateExpr =
nullptr;
6444 return ErrorFound != NoError;
6447 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
6449 ExprAnalysisErrorCode ErrorFound = NoError;
6460 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
6461 AtomicBody = AtomicBody->IgnoreParenImpCasts();
6462 if (AtomicBody->getType()->isScalarType() ||
6463 AtomicBody->isInstantiationDependent()) {
6464 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6465 AtomicBody->IgnoreParenImpCasts())) {
6468 AtomicCompAssignOp->getOpcode());
6469 OpLoc = AtomicCompAssignOp->getOperatorLoc();
6470 E = AtomicCompAssignOp->getRHS();
6471 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6472 IsXLHSInRHSPart =
true;
6473 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6474 AtomicBody->IgnoreParenImpCasts())) {
6476 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6478 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6479 AtomicBody->IgnoreParenImpCasts())) {
6481 if (AtomicUnaryOp->isIncrementDecrementOp()) {
6482 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6483 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6484 OpLoc = AtomicUnaryOp->getOperatorLoc();
6485 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6487 IsXLHSInRHSPart =
true;
6489 ErrorFound = NotAnUnaryIncDecExpression;
6490 ErrorLoc = AtomicUnaryOp->getExprLoc();
6491 ErrorRange = AtomicUnaryOp->getSourceRange();
6492 NoteLoc = AtomicUnaryOp->getOperatorLoc();
6495 }
else if (!AtomicBody->isInstantiationDependent()) {
6496 ErrorFound = NotABinaryOrUnaryExpression;
6497 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6498 NoteRange = ErrorRange = AtomicBody->getSourceRange();
6501 ErrorFound = NotAScalarType;
6502 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6503 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6506 ErrorFound = NotAnExpression;
6508 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6510 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6511 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
6512 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6516 E =
X = UpdateExpr =
nullptr;
6517 if (ErrorFound == NoError && E &&
X) {
6527 IsXLHSInRHSPart ? OVEExpr : OVEX);
6534 UpdateExpr = Update.
get();
6536 return ErrorFound != NoError;
6546 auto *CS = cast<CapturedStmt>(AStmt);
6555 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
6556 C->getClauseKind() == OMPC_update ||
6557 C->getClauseKind() == OMPC_capture) {
6559 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6561 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6564 AtomicKind =
C->getClauseKind();
6565 AtomicKindLoc =
C->getBeginLoc();
6571 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6572 Body = EWC->getSubExpr();
6578 bool IsXLHSInRHSPart =
false;
6579 bool IsPostfixUpdate =
false;
6602 if (AtomicKind == OMPC_read) {
6609 } ErrorFound = NoError;
6614 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6615 const auto *AtomicBinOp =
6617 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6624 ErrorFound = NotAnLValue;
6632 const Expr *NotScalarExpr =
6636 ErrorFound = NotAScalarType;
6642 }
else if (!AtomicBody->isInstantiationDependent()) {
6643 ErrorFound = NotAnAssignmentOp;
6644 ErrorLoc = AtomicBody->getExprLoc();
6645 ErrorRange = AtomicBody->getSourceRange();
6647 : AtomicBody->getExprLoc();
6649 : AtomicBody->getSourceRange();
6652 ErrorFound = NotAnExpression;
6654 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6656 if (ErrorFound != NoError) {
6657 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6659 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6663 if (CurContext->isDependentContext())
6665 }
else if (AtomicKind == OMPC_write) {
6672 } ErrorFound = NoError;
6677 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6678 const auto *AtomicBinOp =
6680 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6681 X = AtomicBinOp->
getLHS();
6682 E = AtomicBinOp->
getRHS();
6686 ErrorFound = NotAnLValue;
6694 const Expr *NotScalarExpr =
6698 ErrorFound = NotAScalarType;
6704 }
else if (!AtomicBody->isInstantiationDependent()) {
6705 ErrorFound = NotAnAssignmentOp;
6706 ErrorLoc = AtomicBody->getExprLoc();
6707 ErrorRange = AtomicBody->getSourceRange();
6709 : AtomicBody->getExprLoc();
6711 : AtomicBody->getSourceRange();
6714 ErrorFound = NotAnExpression;
6716 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
6718 if (ErrorFound != NoError) {
6719 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6721 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6725 if (CurContext->isDependentContext())
6727 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
6736 OpenMPAtomicUpdateChecker Checker(*
this);
6737 if (Checker.checkStatement(
6738 Body, (AtomicKind == OMPC_update)
6739 ? diag::err_omp_atomic_update_not_expression_statement
6740 : diag::err_omp_atomic_not_expression_statement,
6741 diag::note_omp_atomic_update))
6743 if (!CurContext->isDependentContext()) {
6744 E = Checker.getExpr();
6746 UE = Checker.getUpdateExpr();
6747 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6749 }
else if (AtomicKind == OMPC_capture) {
6752 NotACompoundStatement,
6753 NotTwoSubstatements,
6754 NotASpecificExpression,
6756 } ErrorFound = NoError;
6759 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6768 const auto *AtomicBinOp =
6770 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
6771 V = AtomicBinOp->
getLHS();
6773 OpenMPAtomicUpdateChecker Checker(*
this);
6774 if (Checker.checkStatement(
6775 Body, diag::err_omp_atomic_capture_not_expression_statement,
6776 diag::note_omp_atomic_update))
6778 E = Checker.getExpr();
6780 UE = Checker.getUpdateExpr();
6781 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6782 IsPostfixUpdate = Checker.isPostfixUpdate();
6783 }
else if (!AtomicBody->isInstantiationDependent()) {
6784 ErrorLoc = AtomicBody->getExprLoc();
6785 ErrorRange = AtomicBody->getSourceRange();
6787 : AtomicBody->getExprLoc();
6789 : AtomicBody->getSourceRange();
6790 ErrorFound = NotAnAssignmentOp;
6792 if (ErrorFound != NoError) {
6793 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6795 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6798 if (CurContext->isDependentContext())
6799 UE = V = E = X =
nullptr;
6817 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
6819 if (CS->size() == 2) {
6821 Stmt *Second = CS->body_back();
6822 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
6823 First = EWC->getSubExpr()->IgnoreParenImpCasts();
6824 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6825 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6827 OpenMPAtomicUpdateChecker Checker(*
this);
6828 bool IsUpdateExprFound = !Checker.checkStatement(Second);
6830 if (IsUpdateExprFound) {
6832 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6834 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6844 llvm::FoldingSetNodeID XId, PossibleXId;
6845 Checker.getX()->Profile(XId, Context,
true);
6846 PossibleX->
Profile(PossibleXId, Context,
true);
6847 IsUpdateExprFound = XId == PossibleXId;
6848 if (IsUpdateExprFound) {
6851 E = Checker.getExpr();
6852 UE = Checker.getUpdateExpr();
6853 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6854 IsPostfixUpdate =
true;
6857 if (!IsUpdateExprFound) {
6858 IsUpdateExprFound = !Checker.checkStatement(First);
6860 if (IsUpdateExprFound) {
6862 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
6864 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6874 llvm::FoldingSetNodeID XId, PossibleXId;
6875 Checker.getX()->Profile(XId, Context,
true);
6876 PossibleX->
Profile(PossibleXId, Context,
true);
6877 IsUpdateExprFound = XId == PossibleXId;
6878 if (IsUpdateExprFound) {
6881 E = Checker.getExpr();
6882 UE = Checker.getUpdateExpr();
6883 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6884 IsPostfixUpdate =
false;
6888 if (!IsUpdateExprFound) {
6890 auto *FirstExpr = dyn_cast<
Expr>(
First);
6891 auto *SecondExpr = dyn_cast<
Expr>(Second);
6892 if (!FirstExpr || !SecondExpr ||
6893 !(FirstExpr->isInstantiationDependent() ||
6894 SecondExpr->isInstantiationDependent())) {
6896 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6897 ErrorFound = NotAnAssignmentOp;
6898 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6900 NoteRange = ErrorRange = FirstBinOp
6901 ? FirstBinOp->getSourceRange()
6905 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6906 ErrorFound = NotAnAssignmentOp;
6907 NoteLoc = ErrorLoc = SecondBinOp
6908 ? SecondBinOp->getOperatorLoc()
6910 NoteRange = ErrorRange =
6911 SecondBinOp ? SecondBinOp->getSourceRange()
6914 Expr *PossibleXRHSInFirst =
6916 Expr *PossibleXLHSInSecond =
6918 llvm::FoldingSetNodeID X1Id, X2Id;
6919 PossibleXRHSInFirst->
Profile(X1Id, Context,
6921 PossibleXLHSInSecond->
Profile(X2Id, Context,
6923 IsUpdateExprFound = X1Id == X2Id;
6924 if (IsUpdateExprFound) {
6925 V = FirstBinOp->getLHS();
6926 X = SecondBinOp->getLHS();
6927 E = SecondBinOp->getRHS();
6929 IsXLHSInRHSPart =
false;
6930 IsPostfixUpdate =
true;
6932 ErrorFound = NotASpecificExpression;
6933 ErrorLoc = FirstBinOp->getExprLoc();
6934 ErrorRange = FirstBinOp->getSourceRange();
6935 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6936 NoteRange = SecondBinOp->getRHS()->getSourceRange();
6944 NoteRange = ErrorRange =
6946 ErrorFound = NotTwoSubstatements;
6950 NoteRange = ErrorRange =
6952 ErrorFound = NotACompoundStatement;
6954 if (ErrorFound != NoError) {
6955 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6957 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6960 if (CurContext->isDependentContext())
6961 UE = V = E = X =
nullptr;
6965 setFunctionHasBranchProtectedScope();
6968 X, V, E, UE, IsXLHSInRHSPart,
6979 auto *CS = cast<CapturedStmt>(AStmt);
6986 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6987 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7001 if (
DSAStack->hasInnerTeamsRegion()) {
7003 bool OMPTeamsFound =
true;
7004 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
7005 auto I = CS->body_begin();
7006 while (I != CS->body_end()) {
7009 OMPTeamsFound =
false;
7014 assert(I != CS->body_end() &&
"Not found statement");
7020 if (!OMPTeamsFound) {
7021 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7023 diag::note_omp_nested_teams_construct_here);
7025 << isa<OMPExecutableDirective>(S);
7030 setFunctionHasBranchProtectedScope();
7042 auto *CS = cast<CapturedStmt>(AStmt);
7049 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7050 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7060 setFunctionHasBranchProtectedScope();
7072 auto *CS = cast<CapturedStmt>(AStmt);
7079 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7080 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7093 unsigned NestedLoopCount =
7096 VarsWithImplicitDSA, B);
7097 if (NestedLoopCount == 0)
7100 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7101 "omp target parallel for loop exprs were not built");
7103 if (!CurContext->isDependentContext()) {
7106 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7114 setFunctionHasBranchProtectedScope();
7116 NestedLoopCount, Clauses, AStmt,
7123 return llvm::any_of(
7127 template <
typename... Params>
7129 const Params... ClauseTypes) {
7140 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7144 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7145 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7146 <<
"'map' or 'use_device_ptr'" 7151 setFunctionHasBranchProtectedScope();
7164 auto *CS = cast<CapturedStmt>(AStmt);
7171 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7172 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7185 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7201 auto *CS = cast<CapturedStmt>(AStmt);
7208 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7209 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7222 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7238 auto *CS = cast<CapturedStmt>(AStmt);
7245 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7246 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7256 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
7257 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7270 auto *CS = cast<CapturedStmt>(AStmt);
7278 setFunctionHasBranchProtectedScope();
7280 DSAStack->setParentTeamsRegionLoc(StartLoc);
7289 if (
DSAStack->isParentNowaitRegion()) {
7290 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7293 if (
DSAStack->isParentOrderedRegion()) {
7294 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7305 if (
DSAStack->isParentNowaitRegion()) {
7306 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7309 if (
DSAStack->isParentOrderedRegion()) {
7310 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7313 DSAStack->setParentCancelRegion(
true);
7321 bool ErrorFound =
false;
7323 if (
C->getClauseKind() == OMPC_grainsize ||
7324 C->getClauseKind() == OMPC_num_tasks) {
7328 S.
Diag(
C->getBeginLoc(),
7329 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7333 diag::note_omp_previous_grainsize_num_tasks)
7344 const OMPClause *ReductionClause =
nullptr;
7345 const OMPClause *NogroupClause =
nullptr;
7347 if (
C->getClauseKind() == OMPC_reduction) {
7348 ReductionClause =
C;
7353 if (
C->getClauseKind() == OMPC_nogroup) {
7355 if (ReductionClause)
7360 if (ReductionClause && NogroupClause) {
7361 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7375 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7379 unsigned NestedLoopCount =
7382 VarsWithImplicitDSA, B);
7383 if (NestedLoopCount == 0)
7386 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7387 "omp for loop exprs were not built");
7400 setFunctionHasBranchProtectedScope();
7402 NestedLoopCount, Clauses, AStmt, B);
7411 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7415 unsigned NestedLoopCount =
7418 VarsWithImplicitDSA, B);
7419 if (NestedLoopCount == 0)
7422 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7423 "omp for loop exprs were not built");
7425 if (!CurContext->isDependentContext()) {
7428 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7449 setFunctionHasBranchProtectedScope();
7451 NestedLoopCount, Clauses, AStmt, B);
7460 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7464 unsigned NestedLoopCount =
7467 *
this, *
DSAStack, VarsWithImplicitDSA, B);
7468 if (NestedLoopCount == 0)
7471 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7472 "omp for loop exprs were not built");
7474 setFunctionHasBranchProtectedScope();
7476 NestedLoopCount, Clauses, AStmt, B);
7485 auto *CS = cast<CapturedStmt>(AStmt);
7492 for (
int ThisCaptureLevel =
7493 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7494 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7510 VarsWithImplicitDSA, B);
7511 if (NestedLoopCount == 0)
7514 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7515 "omp for loop exprs were not built");
7517 setFunctionHasBranchProtectedScope();
7519 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7529 auto *CS = cast<CapturedStmt>(AStmt);
7536 for (
int ThisCaptureLevel =
7537 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7538 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7554 VarsWithImplicitDSA, B);
7555 if (NestedLoopCount == 0)
7558 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7559 "omp for loop exprs were not built");
7561 if (!CurContext->isDependentContext()) {
7564 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7575 setFunctionHasBranchProtectedScope();
7577 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7586 auto *CS = cast<CapturedStmt>(AStmt);
7593 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7594 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7607 unsigned NestedLoopCount =
7609 nullptr , CS, *
this,
7610 *
DSAStack, VarsWithImplicitDSA, B);
7611 if (NestedLoopCount == 0)
7614 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7615 "omp for loop exprs were not built");
7617 if (!CurContext->isDependentContext()) {
7620 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7631 setFunctionHasBranchProtectedScope();
7633 NestedLoopCount, Clauses, AStmt, B);
7642 auto *CS = cast<CapturedStmt>(AStmt);
7649 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7650 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7666 VarsWithImplicitDSA, B);
7667 if (NestedLoopCount == 0)
7670 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7671 "omp target parallel for simd loop exprs were not built");
7673 if (!CurContext->isDependentContext()) {
7676 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7686 setFunctionHasBranchProtectedScope();
7688 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7697 auto *CS = cast<CapturedStmt>(AStmt);
7704 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7705 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7718 unsigned NestedLoopCount =
7721 VarsWithImplicitDSA, B);
7722 if (NestedLoopCount == 0)
7725 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7726 "omp target simd loop exprs were not built");
7728 if (!CurContext->isDependentContext()) {
7731 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7742 setFunctionHasBranchProtectedScope();
7744 NestedLoopCount, Clauses, AStmt, B);
7753 auto *CS = cast<CapturedStmt>(AStmt);
7760 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7761 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7774 unsigned NestedLoopCount =
7776 nullptr , CS, *
this,
7777 *
DSAStack, VarsWithImplicitDSA, B);
7778 if (NestedLoopCount == 0)
7781 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7782 "omp teams distribute loop exprs were not built");
7784 setFunctionHasBranchProtectedScope();
7786 DSAStack->setParentTeamsRegionLoc(StartLoc);
7789 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7798 auto *CS = cast<CapturedStmt>(AStmt);
7805 for (
int ThisCaptureLevel =
7806 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7807 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7824 VarsWithImplicitDSA, B);
7826 if (NestedLoopCount == 0)
7829 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7830 "omp teams distribute simd loop exprs were not built");
7832 if (!CurContext->isDependentContext()) {
7835 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7846 setFunctionHasBranchProtectedScope();
7848 DSAStack->setParentTeamsRegionLoc(StartLoc);
7851 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7860 auto *CS = cast<CapturedStmt>(AStmt);
7868 for (
int ThisCaptureLevel =
7869 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7870 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7886 VarsWithImplicitDSA, B);
7888 if (NestedLoopCount == 0)
7891 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7892 "omp for loop exprs were not built");
7894 if (!CurContext->isDependentContext()) {
7897 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7908 setFunctionHasBranchProtectedScope();
7910 DSAStack->setParentTeamsRegionLoc(StartLoc);
7913 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7922 auto *CS = cast<CapturedStmt>(AStmt);
7930 for (
int ThisCaptureLevel =
7931 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7932 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7948 VarsWithImplicitDSA, B);
7950 if (NestedLoopCount == 0)
7953 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7954 "omp for loop exprs were not built");
7956 setFunctionHasBranchProtectedScope();
7958 DSAStack->setParentTeamsRegionLoc(StartLoc);
7961 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7972 auto *CS = cast<CapturedStmt>(AStmt);
7980 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7981 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7990 setFunctionHasBranchProtectedScope();
8002 auto *CS = cast<CapturedStmt>(AStmt);
8009 for (
int ThisCaptureLevel =
8010 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8011 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8027 VarsWithImplicitDSA, B);
8028 if (NestedLoopCount == 0)
8031 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8032 "omp target teams distribute loop exprs were not built");
8034 setFunctionHasBranchProtectedScope();
8036 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8045 auto *CS = cast<CapturedStmt>(AStmt);
8052 for (
int ThisCaptureLevel =
8053 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8054 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8070 VarsWithImplicitDSA, B);
8071 if (NestedLoopCount == 0)
8074 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8075 "omp target teams distribute parallel for loop exprs were not built");
8077 if (!CurContext->isDependentContext()) {
8080 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8088 setFunctionHasBranchProtectedScope();
8090 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8100 auto *CS = cast<CapturedStmt>(AStmt);
8107 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(
8108 OMPD_target_teams_distribute_parallel_for_simd);
8109 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8122 unsigned NestedLoopCount =
8125 nullptr , CS, *
this,
8126 *
DSAStack, VarsWithImplicitDSA, B);
8127 if (NestedLoopCount == 0)
8130 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8131 "omp target teams distribute parallel for simd loop exprs were not " 8134 if (!CurContext->isDependentContext()) {
8137 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8148 setFunctionHasBranchProtectedScope();
8150 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8159 auto *CS = cast<CapturedStmt>(AStmt);
8166 for (
int ThisCaptureLevel =
8167 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8168 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8184 VarsWithImplicitDSA, B);
8185 if (NestedLoopCount == 0)
8188 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8189 "omp target teams distribute simd loop exprs were not built");
8191 if (!CurContext->isDependentContext()) {
8194 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8205 setFunctionHasBranchProtectedScope();
8207 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8217 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
8219 case OMPC_num_threads:
8220 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
8223 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
8226 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
8229 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
8232 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
8235 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
8237 case OMPC_num_teams:
8238 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
8240 case OMPC_thread_limit:
8241 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
8244 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
8246 case OMPC_grainsize:
8247 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
8249 case OMPC_num_tasks:
8250 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
8253 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
8257 case OMPC_proc_bind:
8260 case OMPC_firstprivate:
8261 case OMPC_lastprivate:
8263 case OMPC_reduction:
8264 case OMPC_task_reduction:
8265 case OMPC_in_reduction:
8269 case OMPC_copyprivate:
8272 case OMPC_mergeable:
8285 case OMPC_dist_schedule:
8286 case OMPC_defaultmap:
8291 case OMPC_use_device_ptr:
8292 case OMPC_is_device_ptr:
8293 case OMPC_unified_address:
8294 case OMPC_unified_shared_memory:
8295 case OMPC_reverse_offload:
8296 case OMPC_dynamic_allocators:
8297 case OMPC_atomic_default_mem_order:
8298 llvm_unreachable(
"Clause is not allowed.");
8315 case OMPD_target_parallel:
8316 case OMPD_target_parallel_for:
8317 case OMPD_target_parallel_for_simd:
8320 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
8321 CaptureRegion = OMPD_target;
8323 case OMPD_target_teams_distribute_parallel_for:
8324 case OMPD_target_teams_distribute_parallel_for_simd:
8327 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
8328 CaptureRegion = OMPD_teams;
8330 case OMPD_teams_distribute_parallel_for:
8331 case OMPD_teams_distribute_parallel_for_simd:
8332 CaptureRegion = OMPD_teams;
8334 case OMPD_target_update:
8335 case OMPD_target_enter_data:
8336 case OMPD_target_exit_data:
8337 CaptureRegion = OMPD_task;
8341 case OMPD_parallel_sections:
8342 case OMPD_parallel_for:
8343 case OMPD_parallel_for_simd:
8345 case OMPD_target_simd:
8346 case OMPD_target_teams:
8347 case OMPD_target_teams_distribute:
8348 case OMPD_target_teams_distribute_simd:
8349 case OMPD_distribute_parallel_for:
8350 case OMPD_distribute_parallel_for_simd:
8353 case OMPD_taskloop_simd:
8354 case OMPD_target_data:
8357 case OMPD_threadprivate:
8358 case OMPD_taskyield:
8361 case OMPD_cancellation_point:
8363 case OMPD_declare_reduction:
8364 case OMPD_declare_simd:
8365 case OMPD_declare_target:
8366 case OMPD_end_declare_target:
8376 case OMPD_taskgroup:
8377 case OMPD_distribute:
8380 case OMPD_distribute_simd:
8381 case OMPD_teams_distribute:
8382 case OMPD_teams_distribute_simd:
8384 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
8386 llvm_unreachable(
"Unknown OpenMP directive");
8389 case OMPC_num_threads:
8391 case OMPD_target_parallel:
8392 case OMPD_target_parallel_for:
8393 case OMPD_target_parallel_for_simd:
8394 CaptureRegion = OMPD_target;
8396 case OMPD_teams_distribute_parallel_for:
8397 case OMPD_teams_distribute_parallel_for_simd:
8398 case OMPD_target_teams_distribute_parallel_for:
8399 case OMPD_target_teams_distribute_parallel_for_simd:
8400 CaptureRegion = OMPD_teams;
8403 case OMPD_parallel_sections:
8404 case OMPD_parallel_for:
8405 case OMPD_parallel_for_simd:
8406 case OMPD_distribute_parallel_for:
8407 case OMPD_distribute_parallel_for_simd:
8410 case OMPD_target_data:
8411 case OMPD_target_enter_data:
8412 case OMPD_target_exit_data:
8413 case OMPD_target_update:
8415 case OMPD_target_simd:
8416 case OMPD_target_teams:
8417 case OMPD_target_teams_distribute:
8418 case OMPD_target_teams_distribute_simd:
8422 case OMPD_taskloop_simd:
8423 case OMPD_threadprivate:
8424 case OMPD_taskyield:
8427 case OMPD_cancellation_point:
8429 case OMPD_declare_reduction:
8430 case OMPD_declare_simd:
8431 case OMPD_declare_target:
8432 case OMPD_end_declare_target:
8442 case OMPD_taskgroup:
8443 case OMPD_distribute:
8446 case OMPD_distribute_simd:
8447 case OMPD_teams_distribute:
8448 case OMPD_teams_distribute_simd:
8450 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
8452 llvm_unreachable(
"Unknown OpenMP directive");
8455 case OMPC_num_teams:
8457 case OMPD_target_teams:
8458 case OMPD_target_teams_distribute:
8459 case OMPD_target_teams_distribute_simd:
8460 case OMPD_target_teams_distribute_parallel_for:
8461 case OMPD_target_teams_distribute_parallel_for_simd:
8462 CaptureRegion = OMPD_target;
8464 case OMPD_teams_distribute_parallel_for:
8465 case OMPD_teams_distribute_parallel_for_simd:
8467 case OMPD_teams_distribute:
8468 case OMPD_teams_distribute_simd:
8471 case OMPD_distribute_parallel_for:
8472 case OMPD_distribute_parallel_for_simd:
8475 case OMPD_taskloop_simd:
8476 case OMPD_target_data:
8477 case OMPD_target_enter_data:
8478 case OMPD_target_exit_data:
8479 case OMPD_target_update:
8482 case OMPD_parallel_sections:
8483 case OMPD_parallel_for:
8484 case OMPD_parallel_for_simd:
8486 case OMPD_target_simd:
8487 case OMPD_target_parallel:
8488 case OMPD_target_parallel_for:
8489 case OMPD_target_parallel_for_simd:
8490 case OMPD_threadprivate:
8491 case OMPD_taskyield:
8494 case OMPD_cancellation_point:
8496 case OMPD_declare_reduction:
8497 case OMPD_declare_simd:
8498 case OMPD_declare_target:
8499 case OMPD_end_declare_target:
8508 case OMPD_taskgroup:
8509 case OMPD_distribute:
8512 case OMPD_distribute_simd:
8514 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8516 llvm_unreachable(
"Unknown OpenMP directive");
8519 case OMPC_thread_limit:
8521 case OMPD_target_teams:
8522 case OMPD_target_teams_distribute:
8523 case OMPD_target_teams_distribute_simd:
8524 case OMPD_target_teams_distribute_parallel_for:
8525 case OMPD_target_teams_distribute_parallel_for_simd:
8526 CaptureRegion = OMPD_target;
8528 case OMPD_teams_distribute_parallel_for:
8529 case OMPD_teams_distribute_parallel_for_simd:
8531 case OMPD_teams_distribute:
8532 case OMPD_teams_distribute_simd:
8535 case OMPD_distribute_parallel_for:
8536 case OMPD_distribute_parallel_for_simd:
8539 case OMPD_taskloop_simd:
8540 case OMPD_target_data:
8541 case OMPD_target_enter_data:
8542 case OMPD_target_exit_data:
8543 case OMPD_target_update:
8546 case OMPD_parallel_sections:
8547 case OMPD_parallel_for:
8548 case OMPD_parallel_for_simd:
8550 case OMPD_target_simd:
8551 case OMPD_target_parallel:
8552 case OMPD_target_parallel_for:
8553 case OMPD_target_parallel_for_simd:
8554 case OMPD_threadprivate:
8555 case OMPD_taskyield:
8558 case OMPD_cancellation_point:
8560 case OMPD_declare_reduction:
8561 case OMPD_declare_simd:
8562 case OMPD_declare_target:
8563 case OMPD_end_declare_target:
8572 case OMPD_taskgroup:
8573 case OMPD_distribute:
8576 case OMPD_distribute_simd:
8578 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
8580 llvm_unreachable(
"Unknown OpenMP directive");
8585 case OMPD_parallel_for:
8586 case OMPD_parallel_for_simd:
8587 case OMPD_distribute_parallel_for:
8588 case OMPD_distribute_parallel_for_simd:
8589 case OMPD_teams_distribute_parallel_for:
8590 case OMPD_teams_distribute_parallel_for_simd:
8591 case OMPD_target_parallel_for:
8592 case OMPD_target_parallel_for_simd:
8593 case OMPD_target_teams_distribute_parallel_for:
8594 case OMPD_target_teams_distribute_parallel_for_simd:
8595 CaptureRegion = OMPD_parallel;
8603 case OMPD_taskloop_simd:
8604 case OMPD_target_data:
8605 case OMPD_target_enter_data:
8606 case OMPD_target_exit_data:
8607 case OMPD_target_update:
8609 case OMPD_teams_distribute:
8610 case OMPD_teams_distribute_simd:
8611 case OMPD_target_teams_distribute:
8612 case OMPD_target_teams_distribute_simd:
8614 case OMPD_target_simd:
8615 case OMPD_target_parallel:
8618 case OMPD_parallel_sections:
8619 case OMPD_threadprivate:
8620 case OMPD_taskyield:
8623 case OMPD_cancellation_point:
8625 case OMPD_declare_reduction:
8626 case OMPD_declare_simd:
8627 case OMPD_declare_target:
8628 case OMPD_end_declare_target:
8635 case OMPD_taskgroup:
8636 case OMPD_distribute:
8639 case OMPD_distribute_simd:
8640 case OMPD_target_teams:
8642 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8644 llvm_unreachable(
"Unknown OpenMP directive");
8647 case OMPC_dist_schedule:
8649 case OMPD_teams_distribute_parallel_for:
8650 case OMPD_teams_distribute_parallel_for_simd:
8651 case OMPD_teams_distribute:
8652 case OMPD_teams_distribute_simd:
8653 case OMPD_target_teams_distribute_parallel_for:
8654 case OMPD_target_teams_distribute_parallel_for_simd:
8655 case OMPD_target_teams_distribute:
8656 case OMPD_target_teams_distribute_simd:
8657 CaptureRegion = OMPD_teams;
8659 case OMPD_distribute_parallel_for:
8660 case OMPD_distribute_parallel_for_simd:
8661 case OMPD_distribute:
8662 case OMPD_distribute_simd:
8665 case OMPD_parallel_for:
8666 case OMPD_parallel_for_simd:
8667 case OMPD_target_parallel_for_simd:
8668 case OMPD_target_parallel_for:
8671 case OMPD_taskloop_simd:
8672 case OMPD_target_data:
8673 case OMPD_target_enter_data:
8674 case OMPD_target_exit_data:
8675 case OMPD_target_update:
8678 case OMPD_target_simd:
8679 case OMPD_target_parallel:
8682 case OMPD_parallel_sections:
8683 case OMPD_threadprivate:
8684 case OMPD_taskyield:
8687 case OMPD_cancellation_point:
8689 case OMPD_declare_reduction:
8690 case OMPD_declare_simd:
8691 case OMPD_declare_target:
8692 case OMPD_end_declare_target:
8701 case OMPD_taskgroup:
8704 case OMPD_target_teams:
8706 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
8708 llvm_unreachable(
"Unknown OpenMP directive");
8713 case OMPD_target_update:
8714 case OMPD_target_enter_data:
8715 case OMPD_target_exit_data:
8717 case OMPD_target_simd:
8718 case OMPD_target_teams:
8719 case OMPD_target_parallel:
8720 case OMPD_target_teams_distribute:
8721 case OMPD_target_teams_distribute_simd:
8722 case OMPD_target_parallel_for:
8723 case OMPD_target_parallel_for_simd:
8724 case OMPD_target_teams_distribute_parallel_for:
8725 case OMPD_target_teams_distribute_parallel_for_simd:
8726 CaptureRegion = OMPD_task;
8728 case OMPD_target_data:
8731 case OMPD_teams_distribute_parallel_for:
8732 case OMPD_teams_distribute_parallel_for_simd:
8734 case OMPD_teams_distribute:
8735 case OMPD_teams_distribute_simd:
8736 case OMPD_distribute_parallel_for:
8737 case OMPD_distribute_parallel_for_simd:
8740 case OMPD_taskloop_simd:
8743 case OMPD_parallel_sections:
8744 case OMPD_parallel_for:
8745 case OMPD_parallel_for_simd:
8746 case OMPD_threadprivate:
8747 case OMPD_taskyield:
8750 case OMPD_cancellation_point:
8752 case OMPD_declare_reduction:
8753 case OMPD_declare_simd:
8754 case OMPD_declare_target:
8755 case OMPD_end_declare_target:
8764 case OMPD_taskgroup:
8765 case OMPD_distribute:
8768 case OMPD_distribute_simd:
8770 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
8772 llvm_unreachable(
"Unknown OpenMP directive");
8775 case OMPC_firstprivate:
8776 case OMPC_lastprivate:
8777 case OMPC_reduction:
8778 case OMPC_task_reduction:
8779 case OMPC_in_reduction:
8782 case OMPC_proc_bind:
8791 case OMPC_copyprivate:
8795 case OMPC_mergeable:
8808 case OMPC_grainsize:
8810 case OMPC_num_tasks:
8812 case OMPC_defaultmap:
8817 case OMPC_use_device_ptr:
8818 case OMPC_is_device_ptr:
8819 case OMPC_unified_address:
8820 case OMPC_unified_shared_memory:
8821 case OMPC_reverse_offload:
8822 case OMPC_dynamic_allocators:
8823 case OMPC_atomic_default_mem_order:
8824 llvm_unreachable(
"Unexpected OpenMP clause.");
8826 return CaptureRegion;
8835 Expr *ValExpr = Condition;
8836 Stmt *HelperValStmt =
nullptr;
8841 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8845 ValExpr = Val.
get();
8850 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8851 ValExpr = MakeFullExpr(ValExpr).get();
8852 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8853 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8858 return new (Context)
8859 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8860 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8867 Expr *ValExpr = Condition;
8871 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8875 ValExpr = MakeFullExpr(Val.
get()).
get();
8878 return new (Context)
OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8887 IntConvertDiagnoser()
8891 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
8895 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
8900 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8909 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8918 llvm_unreachable(
"conversion functions are permitted");
8921 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8926 bool StrictlyPositive) {
8935 ValExpr = Value.
get();
8939 Result.isSigned() &&
8940 !((!StrictlyPositive && Result.isNonNegative()) ||
8941 (StrictlyPositive && Result.isStrictlyPositive()))) {
8942 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
8955 Expr *ValExpr = NumThreads;
8956 Stmt *HelperValStmt =
nullptr;
8967 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
8968 ValExpr = MakeFullExpr(ValExpr).get();
8969 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8970 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
8975 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8980 bool StrictlyPositive) {
8987 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8990 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8991 (!StrictlyPositive && !Result.isNonNegative())) {
8992 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
8997 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9002 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
9003 DSAStack->setAssociatedLoops(Result.getExtValue());
9004 else if (CKind == OMPC_ordered)
9005 DSAStack->setAssociatedLoops(Result.getExtValue());
9015 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9018 return new (Context)
9028 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9031 return new (Context)
9045 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9048 return new (Context)
9055 Expr *NumForLoops) {
9061 if (NumForLoops && LParenLoc.
isValid()) {
9063 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9066 NumForLoops = NumForLoopsResult.
get();
9068 NumForLoops =
nullptr;
9071 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
9072 StartLoc, LParenLoc, EndLoc);
9073 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
9084 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9085 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9087 case OMPC_proc_bind:
9088 Res = ActOnOpenMPProcBindClause(
9089 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
9092 case OMPC_atomic_default_mem_order:
9093 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9094 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9095 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9099 case OMPC_num_threads:
9105 case OMPC_firstprivate:
9106 case OMPC_lastprivate:
9108 case OMPC_reduction:
9109 case OMPC_task_reduction:
9110 case OMPC_in_reduction:
9114 case OMPC_copyprivate:
9118 case OMPC_mergeable:
9131 case OMPC_num_teams:
9132 case OMPC_thread_limit:
9134 case OMPC_grainsize:
9136 case OMPC_num_tasks:
9138 case OMPC_dist_schedule:
9139 case OMPC_defaultmap:
9144 case OMPC_use_device_ptr:
9145 case OMPC_is_device_ptr:
9146 case OMPC_unified_address:
9147 case OMPC_unified_shared_memory:
9148 case OMPC_reverse_offload:
9149 case OMPC_dynamic_allocators:
9150 llvm_unreachable(
"Clause is not allowed.");
9159 llvm::raw_svector_ostream Out(Buffer);
9160 unsigned Bound = Last >= 2 ? Last - 2 : 0;
9161 unsigned Skipped = Exclude.size();
9162 auto S = Exclude.begin(), E = Exclude.end();
9163 for (
unsigned I = First; I <
Last; ++I) {
9164 if (std::find(S, E, I) != E) {
9169 if (I == Bound - Skipped)
9171 else if (I != Bound + 1 - Skipped)
9184 "OMPC_DEFAULT_unknown not greater than 0");
9185 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9192 case OMPC_DEFAULT_none:
9193 DSAStack->setDefaultDSANone(KindKwLoc);
9195 case OMPC_DEFAULT_shared:
9196 DSAStack->setDefaultDSAShared(KindKwLoc);
9199 llvm_unreachable(
"Clause kind is not allowed.");
9202 return new (Context)
9212 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9218 return new (Context)
9226 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9228 OMPC_atomic_default_mem_order, 0,
9245 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
9246 assert(Argument.size() == NumberOfElements &&
9247 ArgumentLoc.size() == NumberOfElements);
9248 Res = ActOnOpenMPScheduleClause(
9249 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9250 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9251 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9252 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9253 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9256 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9257 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9258 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9261 case OMPC_dist_schedule:
9262 Res = ActOnOpenMPDistScheduleClause(
9263 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9264 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9266 case OMPC_defaultmap:
9268 Res = ActOnOpenMPDefaultmapClause(
9269 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
9270 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9271 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9275 case OMPC_num_threads:
9280 case OMPC_proc_bind:
9282 case OMPC_firstprivate:
9283 case OMPC_lastprivate:
9285 case OMPC_reduction:
9286 case OMPC_task_reduction:
9287 case OMPC_in_reduction:
9291 case OMPC_copyprivate:
9295 case OMPC_mergeable:
9308 case OMPC_num_teams:
9309 case OMPC_thread_limit:
9311 case OMPC_grainsize:
9313 case OMPC_num_tasks:
9319 case OMPC_use_device_ptr:
9320 case OMPC_is_device_ptr:
9321 case OMPC_unified_address:
9322 case OMPC_unified_shared_memory:
9323 case OMPC_reverse_offload:
9324 case OMPC_dynamic_allocators:
9325 case OMPC_atomic_default_mem_order:
9326 llvm_unreachable(
"Clause is not allowed.");
9337 Excluded.push_back(M2);
9338 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9339 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9340 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9341 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9342 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9365 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9366 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9367 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9368 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9369 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9385 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9392 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9393 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9394 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9395 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9396 diag::err_omp_schedule_nonmonotonic_static);
9399 Expr *ValExpr = ChunkSize;
9400 Stmt *HelperValStmt =
nullptr;
9407 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9411 ValExpr = Val.
get();
9418 if (Result.isSigned() && !Result.isStrictlyPositive()) {
9419 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9424 DSAStack->getCurrentDirective(), OMPC_schedule) !=
9426 !CurContext->isDependentContext()) {
9427 ValExpr = MakeFullExpr(ValExpr).get();
9428 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9429 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
9435 return new (Context)
9437 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9446 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9449 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9452 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9454 case OMPC_mergeable:
9455 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9458 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9461 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9464 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9467 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9470 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9473 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9476 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9479 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9481 case OMPC_unified_address:
9482 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
9484 case OMPC_unified_shared_memory:
9485 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9487 case OMPC_reverse_offload:
9488 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
9490 case OMPC_dynamic_allocators:
9491 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
9495 case OMPC_num_threads:
9501 case OMPC_firstprivate:
9502 case OMPC_lastprivate:
9504 case OMPC_reduction:
9505 case OMPC_task_reduction:
9506 case OMPC_in_reduction:
9510 case OMPC_copyprivate:
9512 case OMPC_proc_bind:
9518 case OMPC_num_teams:
9519 case OMPC_thread_limit:
9521 case OMPC_grainsize:
9522 case OMPC_num_tasks:
9524 case OMPC_dist_schedule:
9525 case OMPC_defaultmap:
9530 case OMPC_use_device_ptr:
9531 case OMPC_is_device_ptr:
9532 case OMPC_atomic_default_mem_order:
9533 llvm_unreachable(
"Clause is not allowed.");
9627 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9629 case OMPC_firstprivate:
9630 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9632 case OMPC_lastprivate:
9633 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9636 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9638 case OMPC_reduction:
9639 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9640 EndLoc, ReductionIdScopeSpec, ReductionId);
9642 case OMPC_task_reduction:
9643 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9644 EndLoc, ReductionIdScopeSpec,
9647 case OMPC_in_reduction:
9649 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9650 EndLoc, ReductionIdScopeSpec, ReductionId);
9653 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9654 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9657 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9661 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9663 case OMPC_copyprivate:
9664 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9667 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9670 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9671 StartLoc, LParenLoc, EndLoc);
9674 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
9675 IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
9676 VarList, StartLoc, LParenLoc, EndLoc);
9679 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9682 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9684 case OMPC_use_device_ptr:
9685 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9687 case OMPC_is_device_ptr:
9688 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9692 case OMPC_num_threads:
9697 case OMPC_proc_bind:
9702 case OMPC_mergeable:
9712 case OMPC_num_teams:
9713 case OMPC_thread_limit:
9715 case OMPC_grainsize:
9717 case OMPC_num_tasks:
9719 case OMPC_dist_schedule:
9720 case OMPC_defaultmap:
9723 case OMPC_unified_address:
9724 case OMPC_unified_shared_memory:
9725 case OMPC_reverse_offload:
9726 case OMPC_dynamic_allocators:
9727 case OMPC_atomic_default_mem_order:
9728 llvm_unreachable(
"Clause is not allowed.");
9739 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
9740 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
9745 Res = DefaultLvalueConversion(Res.
get());
9752 static std::pair<ValueDecl *, bool>
9754 SourceRange &ERange,
bool AllowArraySection =
false) {
9757 return std::make_pair(
nullptr,
true);
9769 } IsArrayExpr = NoArrayExpr;
9770 if (AllowArraySection) {
9771 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9772 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
9773 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9776 IsArrayExpr = ArraySubscript;
9777 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9778 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
9779 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9781 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9784 IsArrayExpr = OMPArraySection;
9790 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9791 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9792 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9794 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9795 !isa<FieldDecl>(ME->getMemberDecl()))) {
9796 if (IsArrayExpr != NoArrayExpr) {
9797 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9802 ? diag::err_omp_expected_var_name_member_expr_or_array_item
9803 : diag::err_omp_expected_var_name_member_expr)
9806 return std::make_pair(
nullptr,
false);
9808 return std::make_pair(
9818 for (
Expr *RefExpr : VarList) {
9819 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
9822 Expr *SimpleRefExpr = RefExpr;
9826 Vars.push_back(RefExpr);
9827 PrivateCopies.push_back(
nullptr);
9834 auto *VD = dyn_cast<
VarDecl>(D);
9839 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9861 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9862 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
9873 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9880 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9890 if (
DSAStack->checkMappableExprComponentListsForDecl(
9894 ConflictKind = WhereFoundClauseKind;
9897 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9919 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
9920 ActOnUninitializedDecl(VDPrivate);
9927 if (!VD && !CurContext->isDependentContext())
9929 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9930 Vars.push_back((VD || CurContext->isDependentContext())
9931 ? RefExpr->IgnoreParens()
9933 PrivateCopies.push_back(VDPrivateRefExpr);
9944 class DiagsUninitializedSeveretyRAII {
9948 bool IsIgnored =
false;
9953 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9955 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
9959 ~DiagsUninitializedSeveretyRAII() {
9974 bool IsImplicitClause =
9978 for (
Expr *RefExpr : VarList) {
9979 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
9982 Expr *SimpleRefExpr = RefExpr;
9986 Vars.push_back(RefExpr);
9987 PrivateCopies.push_back(
nullptr);
9988 Inits.push_back(
nullptr);
9994 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9996 auto *VD = dyn_cast<
VarDecl>(D);
10001 if (RequireCompleteType(ELoc, Type,
10002 diag::err_omp_firstprivate_incomplete_type))
10013 DSAStackTy::DSAVarData TopDVar;
10014 if (!IsImplicitClause) {
10015 DSAStackTy::DSAVarData DVar =
10019 bool IsConstant = ElemType.
isConstant(Context);
10027 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10029 DVar.CKind != OMPC_lastprivate) &&
10031 Diag(ELoc, diag::err_omp_wrong_dsa)
10049 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10050 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
10051 Diag(ELoc, diag::err_omp_wrong_dsa)
10077 DVar =
DSAStack->getImplicitDSA(D,
true);
10078 if (DVar.CKind != OMPC_shared &&
10082 Diag(ELoc, diag::err_omp_required_access)
10109 if (DVar.CKind == OMPC_reduction &&
10113 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10125 if (
DSAStack->checkMappableExprComponentListsForDecl(
10130 ConflictKind = WhereFoundClauseKind;
10133 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10146 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10153 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10162 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
10168 Expr *VDInitRefExpr =
nullptr;
10175 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10178 ".firstprivate.temp");
10193 ".firstprivate.temp");
10195 RefExpr->getExprLoc());
10196 AddInitializerToDecl(VDPrivate,
10197 DefaultLvalueConversion(VDInitRefExpr).
get(),
10201 if (IsImplicitClause) {
10202 Diag(RefExpr->getExprLoc(),
10203 diag::note_omp_task_predetermined_firstprivate_here);
10207 CurContext->addDecl(VDPrivate);
10210 RefExpr->getExprLoc());
10212 if (!VD && !CurContext->isDependentContext()) {
10213 if (TopDVar.CKind == OMPC_lastprivate) {
10214 Ref = TopDVar.PrivateCopy;
10217 if (!isOpenMPCapturedDecl(D))
10218 ExprCaptures.push_back(Ref->getDecl());
10221 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10222 Vars.push_back((VD || CurContext->isDependentContext())
10223 ? RefExpr->IgnoreParens()
10225 PrivateCopies.push_back(VDPrivateRefExpr);
10226 Inits.push_back(VDInitRefExpr);
10233 Vars, PrivateCopies, Inits,
10247 for (
Expr *RefExpr : VarList) {
10248 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
10251 Expr *SimpleRefExpr = RefExpr;
10255 Vars.push_back(RefExpr);
10256 SrcExprs.push_back(
nullptr);
10257 DstExprs.push_back(
nullptr);
10258 AssignmentOps.push_back(
nullptr);
10265 auto *VD = dyn_cast<
VarDecl>(D);
10270 if (RequireCompleteType(ELoc, Type,
10271 diag::err_omp_lastprivate_incomplete_type))
10295 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10296 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10298 DVar.CKind != OMPC_firstprivate) &&
10299 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
10300 Diag(ELoc, diag::err_omp_wrong_dsa)
10313 DSAStackTy::DSAVarData TopDVar = DVar;
10317 DVar =
DSAStack->getImplicitDSA(D,
true);
10318 if (DVar.CKind != OMPC_shared) {
10319 Diag(ELoc, diag::err_omp_required_access)
10347 ExprResult AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
10348 PseudoDstExpr, PseudoSrcExpr);
10351 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
10357 if (!VD && !CurContext->isDependentContext()) {
10358 if (TopDVar.CKind == OMPC_firstprivate) {
10359 Ref = TopDVar.PrivateCopy;
10362 if (!isOpenMPCapturedDecl(D))
10363 ExprCaptures.push_back(Ref->
getDecl());
10365 if (TopDVar.CKind == OMPC_firstprivate ||
10366 (!isOpenMPCapturedDecl(D) &&
10368 ExprResult RefRes = DefaultLvalueConversion(Ref);
10372 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10376 ExprPostUpdates.push_back(
10377 IgnoredValueConversions(PostUpdateRes.
get()).
get());
10380 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10381 Vars.push_back((VD || CurContext->isDependentContext())
10382 ? RefExpr->IgnoreParens()
10384 SrcExprs.push_back(PseudoSrcExpr);
10385 DstExprs.push_back(PseudoDstExpr);
10386 AssignmentOps.push_back(AssignmentOp.
get());
10393 Vars, SrcExprs, DstExprs, AssignmentOps,
10403 for (
Expr *RefExpr : VarList) {
10404 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
10407 Expr *SimpleRefExpr = RefExpr;
10411 Vars.push_back(RefExpr);
10417 auto *VD = dyn_cast<
VarDecl>(D);
10425 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10426 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
10435 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10437 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10438 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10439 ? RefExpr->IgnoreParens()
10450 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
10455 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
10456 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
10457 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10461 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10468 bool VisitStmt(
Stmt *S) {
10470 if (Child && Visit(Child))
10475 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10482 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
10489 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
10494 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
10495 return CapturedExpr;
10497 return BaseTransform::TransformMemberExpr(E);
10499 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
10503 template <
typename T,
typename U>
10505 const llvm::function_ref<T(
ValueDecl *)> Gen) {
10506 for (U &Set : Lookups) {
10507 for (
auto *D : Set) {
10508 if (T Res = Gen(cast<ValueDecl>(D)))
10518 for (
auto RD : D->
redecls()) {
10523 auto ND = cast<NamedDecl>(RD);
10541 AssociatedClasses);
10554 for (
auto *NS : AssociatedNamespaces) {
10567 for (
auto *D : R) {
10568 auto *Underlying = D;
10569 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
10570 Underlying = USD->getTargetDecl();
10572 if (!isa<OMPDeclareReductionDecl>(Underlying))
10579 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
10580 Underlying = USD->getTargetDecl();
10582 Lookups.emplace_back();
10583 Lookups.back().addDecl(Underlying);
10606 Lookups.emplace_back();
10607 Lookups.back().append(Lookup.
begin(), Lookup.
end());
10610 }
else if (
auto *ULE =
10611 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10613 Decl *PrevD =
nullptr;
10617 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
10618 Lookups.back().addDecl(DRD);
10625 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) {
10635 ResSet.
append(Set.begin(), Set.end());
10637 ResSet.
addDecl(Set[Set.size() - 1]);
10642 true,
true, ResSet.
begin(), ResSet.
end());
10658 Lookup.suppressDiagnostics();
10662 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
10663 TyRec->getDecl()->getDefinition()) {
10666 if (Lookup.empty()) {
10667 Lookups.emplace_back();
10668 Lookups.back().append(Lookup.begin(), Lookup.end());
10674 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10682 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
10692 if (SemaRef.
IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10694 VD->getType().getUnqualifiedType()))) {
10704 if (ReductionIdScopeSpec.
isSet()) {
10705 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10713 struct ReductionData {
10731 ReductionData() =
delete;
10733 ReductionData(
unsigned Size) {
10734 Vars.reserve(Size);
10735 Privates.reserve(Size);
10736 LHSs.reserve(Size);
10737 RHSs.reserve(Size);
10738 ReductionOps.reserve(Size);
10739 TaskgroupDescriptors.reserve(Size);
10740 ExprCaptures.reserve(Size);
10741 ExprPostUpdates.reserve(Size);
10745 void push(
Expr *Item,
Expr *ReductionOp) {
10746 Vars.emplace_back(Item);
10747 Privates.emplace_back(
nullptr);
10748 LHSs.emplace_back(
nullptr);
10749 RHSs.emplace_back(
nullptr);
10750 ReductionOps.emplace_back(ReductionOp);
10751 TaskgroupDescriptors.emplace_back(
nullptr);
10755 Expr *TaskgroupDescriptor) {
10756 Vars.emplace_back(Item);
10757 Privates.emplace_back(Private);
10758 LHSs.emplace_back(LHS);
10759 RHSs.emplace_back(RHS);
10760 ReductionOps.emplace_back(ReductionOp);
10761 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10770 if (Length ==
nullptr) {
10777 SingleElement =
true;
10778 ArraySizes.push_back(llvm::APSInt::get(1));
10784 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
10785 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10786 ArraySizes.push_back(ConstantLengthValue);
10794 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10795 Length = TempOASE->getLength();
10796 if (Length ==
nullptr) {
10803 ArraySizes.push_back(llvm::APSInt::get(1));
10809 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
10810 if (ConstantLengthValue.getSExtValue() != 1)
10813 ArraySizes.push_back(ConstantLengthValue);
10819 if (!SingleElement) {
10820 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10822 ArraySizes.push_back(llvm::APSInt::get(1));
10876 case OO_Array_Delete:
10885 case OO_GreaterEqual:
10887 case OO_MinusEqual:
10889 case OO_SlashEqual:
10890 case OO_PercentEqual:
10891 case OO_CaretEqual:
10895 case OO_GreaterGreater:
10896 case OO_LessLessEqual:
10897 case OO_GreaterGreaterEqual:
10898 case OO_EqualEqual:
10899 case OO_ExclaimEqual:
10902 case OO_MinusMinus:
10908 case OO_Conditional:
10911 llvm_unreachable(
"Unexpected reduction identifier");
10914 if (II->isStr(
"max"))
10916 else if (II->isStr(
"min"))
10922 if (ReductionIdScopeSpec.
isValid())
10928 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10929 bool FirstIter =
true;
10930 for (
Expr *RefExpr : VarList) {
10931 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
10939 if (!FirstIter && IR != ER)
10944 Expr *SimpleRefExpr = RefExpr;
10953 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10954 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10955 Expr *ReductionOp =
nullptr;
10957 (DeclareReductionRef.
isUnset() ||
10958 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
10959 ReductionOp = DeclareReductionRef.
get();
10961 RD.push(RefExpr, ReductionOp);
10967 Expr *TaskgroupDescriptor =
nullptr;
10972 Type = ASE->getType().getNonReferenceType();
10977 Type = ATy->getElementType();
10984 auto *VD = dyn_cast<
VarDecl>(D);
10990 diag::err_omp_reduction_incomplete_type))
10996 false, ASE || OASE))
11003 if (!ASE && !OASE) {
11006 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
11007 DSARefChecker Check(Stack);
11008 if (Check.Visit(VDDef->
getInit())) {
11009 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11028 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
11029 if (DVar.CKind == OMPC_reduction) {
11030 S.
Diag(ELoc, diag::err_omp_once_referenced)
11033 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11037 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
11051 DVar = Stack->getImplicitDSA(D,
true);
11052 if (DVar.CKind != OMPC_shared) {
11053 S.
Diag(ELoc, diag::err_omp_required_access)
11066 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11067 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11071 (DeclareReductionRef.
isUnset() ||
11072 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
11073 RD.push(RefExpr, DeclareReductionRef.
get());
11076 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
11078 S.
Diag(ReductionId.getBeginLoc(),
11079 diag::err_omp_unknown_reduction_identifier)
11080 << Type << ReductionIdRange;
11092 if (DeclareReductionRef.
isUnset()) {
11093 if ((BOK == BO_GT || BOK == BO_LT) &&
11094 !(Type->isScalarType() ||
11095 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11096 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11098 if (!ASE && !OASE) {
11099 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11102 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11107 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11108 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
11109 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11111 if (!ASE && !OASE) {
11112 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11115 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11122 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11131 bool ConstantLengthOASE =
false;
11133 bool SingleElement;
11136 Context, OASE, SingleElement, ArraySizes);
11139 if (ConstantLengthOASE && !SingleElement) {
11140 for (llvm::APSInt &Size : ArraySizes)
11146 if ((OASE && !ConstantLengthOASE) ||
11151 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11152 S.
Diag(ELoc, diag::note_vla_unsupported);
11164 }
else if (!ASE && !OASE &&
11172 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11174 Expr *Init =
nullptr;
11177 if (DeclareReductionRef.
isUsable()) {
11179 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11180 if (DRD->getInitializer()) {
11182 RHSVD->setInit(DRDRef);
11192 if (Type->isScalarType() || Type->isAnyComplexType())
11197 if (Type->isScalarType() || Type->isAnyComplexType()) {
11206 Type = ComplexTy->getElementType();
11207 if (Type->isRealFloatingType()) {
11208 llvm::APFloat InitValue =
11209 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
11213 }
else if (Type->isScalarType()) {
11216 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11233 if (Type->isIntegerType() || Type->isPointerType()) {
11238 llvm::APInt InitValue =
11239 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11240 : llvm::APInt::getMinValue(Size)
11241 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11242 : llvm::APInt::getMaxValue(Size);
11244 if (Type->isPointerType()) {
11250 Init = CastExpr.
get();
11252 }
else if (Type->isRealFloatingType()) {
11253 llvm::APFloat InitValue = llvm::APFloat::getLargest(
11284 llvm_unreachable(
"Unexpected reduction operation");
11287 if (Init && DeclareReductionRef.
isUnset())
11291 if (RHSVD->isInvalidDecl())
11293 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
11294 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11295 << Type << ReductionIdRange;
11296 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11299 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11305 PrivateVD->
setInit(RHSVD->getInit());
11309 if (DeclareReductionRef.
isUsable()) {
11310 QualType RedTy = DeclareReductionRef.
get()->getType();
11314 if (!BasePath.empty()) {
11318 CK_UncheckedDerivedToBase, LHS.
get(),
11319 &BasePath, LHS.
get()->getValueKind());
11321 CK_UncheckedDerivedToBase, RHS.get(),
11322 &BasePath, RHS.get()->getValueKind());
11325 QualType Params[] = {PtrRedTy, PtrRedTy};
11335 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11337 if (BOK != BO_LT && BOK != BO_GT) {
11339 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11340 BO_Assign, LHSDRE, ReductionOp.
get());
11342 auto *ConditionalOp =
new (Context)
11346 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11347 BO_Assign, LHSDRE, ConditionalOp);
11363 if (ClauseKind == OMPC_in_reduction) {
11366 const Expr *ParentReductionOp;
11367 Expr *ParentBOKTD, *ParentReductionOpTD;
11368 DSAStackTy::DSAVarData ParentBOKDSA =
11369 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11371 DSAStackTy::DSAVarData ParentReductionOpDSA =
11372 Stack->getTopMostTaskgroupReductionData(
11373 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11374 bool IsParentBOK = ParentBOKDSA.DKind !=
OMPD_unknown;
11375 bool IsParentReductionOp = ParentReductionOpDSA.DKind !=
OMPD_unknown;
11376 if (!IsParentBOK && !IsParentReductionOp) {
11377 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11380 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
11381 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
11382 IsParentReductionOp) {
11383 bool EmitError =
true;
11384 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
11385 llvm::FoldingSetNodeID RedId, ParentRedId;
11386 ParentReductionOp->
Profile(ParentRedId, Context,
true);
11387 DeclareReductionRef.
get()->Profile(RedId, Context,
11389 EmitError = RedId != ParentRedId;
11392 S.
Diag(ReductionId.getBeginLoc(),
11393 diag::err_omp_reduction_identifier_mismatch)
11394 << ReductionIdRange << RefExpr->getSourceRange();
11396 diag::note_omp_previous_reduction_identifier)
11398 << (IsParentBOK ? ParentBOKDSA.RefExpr
11399 : ParentReductionOpDSA.RefExpr)
11400 ->getSourceRange();
11404 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11405 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
11412 TransformExprToCaptures RebuildToCapture(S, D);
11414 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
11415 Ref = RebuildToCapture.getCapturedExpr();
11417 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
11420 RD.ExprCaptures.emplace_back(Ref->
getDecl());
11426 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11431 Stack->getCurrentDirective() == OMPD_taskgroup) {
11432 S.
Diag(RefExpr->getExprLoc(),
11433 diag::err_omp_reduction_non_addressable_expression)
11434 << RefExpr->getSourceRange();
11437 RD.ExprPostUpdates.emplace_back(
11444 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11445 if (CurrDir == OMPD_taskgroup) {
11446 if (DeclareReductionRef.
isUsable())
11447 Stack->addTaskgroupReductionData(D, ReductionIdRange,
11448 DeclareReductionRef.
get());
11450 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11452 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
11453 TaskgroupDescriptor);
11455 return RD.Vars.empty();
11463 ReductionData RD(VarList.size());
11465 StartLoc, LParenLoc, ColonLoc, EndLoc,
11466 ReductionIdScopeSpec, ReductionId,
11467 UnresolvedReductions, RD))
11471 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11473 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11483 ReductionData RD(VarList.size());
11485 StartLoc, LParenLoc, ColonLoc, EndLoc,
11486 ReductionIdScopeSpec, ReductionId,
11487 UnresolvedReductions, RD))
11491 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11493 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11503 ReductionData RD(VarList.size());
11505 StartLoc, LParenLoc, ColonLoc, EndLoc,
11506 ReductionIdScopeSpec, ReductionId,
11507 UnresolvedReductions, RD))
11511 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11513 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
11520 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
11522 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
11531 const auto *VD = dyn_cast_or_null<VarDecl>(D);
11533 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
11535 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
11537 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
11553 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11554 !Ty->isPointerType())) {
11555 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11561 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11578 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11579 LinKind = OMPC_LINEAR_val;
11580 for (
Expr *RefExpr : VarList) {
11581 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11584 Expr *SimpleRefExpr = RefExpr;
11588 Vars.push_back(RefExpr);
11589 Privates.push_back(
nullptr);
11590 Inits.push_back(
nullptr);
11597 auto *VD = dyn_cast<
VarDecl>(D);
11603 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
11604 if (DVar.RefExpr) {
11611 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11619 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11625 if (!VD && !CurContext->isDependentContext()) {
11627 if (!isOpenMPCapturedDecl(D)) {
11628 ExprCaptures.push_back(Ref->
getDecl());
11630 ExprResult RefRes = DefaultLvalueConversion(Ref);
11634 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
11635 SimpleRefExpr, RefRes.
get());
11638 ExprPostUpdates.push_back(
11639 IgnoredValueConversions(PostUpdateRes.
get()).
get());
11643 if (LinKind == OMPC_LINEAR_uval)
11644 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11646 InitExpr = VD ? SimpleRefExpr : Ref;
11647 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
11651 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11652 Vars.push_back((VD || CurContext->isDependentContext())
11653 ? RefExpr->IgnoreParens()
11655 Privates.push_back(PrivateRef);
11656 Inits.push_back(InitRef);
11663 Expr *CalcStepExpr =
nullptr;
11668 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11671 StepExpr = Val.
get();
11679 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11680 CalcStep = ActOnFinishFullExpr(CalcStep.get());
11686 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11687 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11688 << (Vars.size() > 1);
11689 if (!IsConstant && CalcStep.isUsable()) {
11692 CalcStepExpr = CalcStep.get();
11697 ColonLoc, EndLoc, Vars, Privates, Inits,
11698 StepExpr, CalcStepExpr,
11704 Expr *NumIterations,
Sema &SemaRef,
11705 Scope *S, DSAStackTy *Stack) {
11716 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
11717 bool HasErrors =
false;
11718 auto CurInit = Clause.inits().begin();
11719 auto CurPrivate = Clause.privates().begin();
11724 Expr *SimpleRefExpr = RefExpr;
11725 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
11727 if (Res.second || !D) {
11728 Updates.push_back(
nullptr);
11729 Finals.push_back(
nullptr);
11733 auto &&Info = Stack->isLoopControlVariable(D);
11740 diag::err_omp_linear_distribute_var_non_loop_iteration);
11741 Updates.push_back(
nullptr);
11742 Finals.push_back(
nullptr);
11746 Expr *InitExpr = *CurInit;
11749 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11751 if (LinKind == OMPC_LINEAR_uval)
11752 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11756 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11764 InitExpr, IV,
Step,
false);
11766 Update = *CurPrivate;
11775 InitExpr, NumIterations,
Step,
false);
11777 Final = *CurPrivate;
11781 if (!Update.isUsable() || !Final.isUsable()) {
11782 Updates.push_back(
nullptr);
11783 Finals.push_back(
nullptr);
11786 Updates.push_back(Update.get());
11787 Finals.push_back(Final.get());
11792 Clause.setUpdates(Updates);
11793 Clause.setFinals(Finals);
11801 for (
Expr *RefExpr : VarList) {
11802 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11805 Expr *SimpleRefExpr = RefExpr;
11809 Vars.push_back(RefExpr);
11816 auto *VD = dyn_cast<
VarDecl>(D);
11822 const Type *Ty = QType.getTypePtrOrNull();
11824 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11825 << QType << getLangOpts().CPlusPlus << ERange;
11830 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11837 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11838 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11839 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11845 if (!VD && isOpenMPCapturedDecl(D))
11847 Vars.push_back(DefaultFunctionArrayConversion(
11848 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11857 if (Alignment !=
nullptr) {
11859 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11862 Alignment = AlignResult.
get();
11868 EndLoc, Vars, Alignment);
11879 for (
Expr *RefExpr : VarList) {
11880 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
11881 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11883 Vars.push_back(RefExpr);
11884 SrcExprs.push_back(
nullptr);
11885 DstExprs.push_back(
nullptr);
11886 AssignmentOps.push_back(
nullptr);
11896 if (!DE || !isa<VarDecl>(DE->getDecl())) {
11897 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11898 << 0 << RefExpr->getSourceRange();
11902 Decl *D = DE->getDecl();
11903 auto *VD = cast<VarDecl>(D);
11906 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11908 Vars.push_back(DE);
11909 SrcExprs.push_back(
nullptr);
11910 DstExprs.push_back(
nullptr);
11911 AssignmentOps.push_back(
nullptr);
11917 if (!
DSAStack->isThreadPrivate(VD)) {
11918 Diag(ELoc, diag::err_omp_required_access)
11931 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11935 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
11936 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
11942 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11944 if (AssignmentOp.isInvalid())
11946 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11948 if (AssignmentOp.isInvalid())
11951 DSAStack->addDSA(VD, DE, OMPC_copyin);
11952 Vars.push_back(DE);
11953 SrcExprs.push_back(PseudoSrcExpr);
11954 DstExprs.push_back(PseudoDstExpr);
11955 AssignmentOps.push_back(AssignmentOp.get());
11962 SrcExprs, DstExprs, AssignmentOps);
11973 for (
Expr *RefExpr : VarList) {
11974 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
11977 Expr *SimpleRefExpr = RefExpr;
11981 Vars.push_back(RefExpr);
11982 SrcExprs.push_back(
nullptr);
11983 DstExprs.push_back(
nullptr);
11984 AssignmentOps.push_back(
nullptr);
11991 auto *VD = dyn_cast<
VarDecl>(D);
11996 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
11997 DSAStackTy::DSAVarData DVar =
11999 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12001 Diag(ELoc, diag::err_omp_wrong_dsa)
12012 DVar =
DSAStack->getImplicitDSA(D,
false);
12013 if (DVar.CKind == OMPC_shared) {
12014 Diag(ELoc, diag::err_omp_required_access)
12016 <<
"threadprivate or private in the enclosing context";
12025 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12032 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12042 .getUnqualifiedType();
12044 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.src",
12048 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.dst",
12052 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12055 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
12062 assert(VD || isOpenMPCapturedDecl(D));
12064 VD ? RefExpr->IgnoreParens()
12066 SrcExprs.push_back(PseudoSrcExpr);
12067 DstExprs.push_back(PseudoDstExpr);
12068 AssignmentOps.push_back(AssignmentOp.
get());
12075 Vars, SrcExprs, DstExprs, AssignmentOps);
12082 if (VarList.empty())
12093 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
12094 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12095 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12099 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
12101 DepKind == OMPC_DEPEND_sink)) {
12102 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
12103 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12111 llvm::APSInt DepCounter(32);
12112 llvm::APSInt TotalDepCount(32);
12113 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12114 if (
const Expr *OrderedCountExpr =
12115 DSAStack->getParentOrderedRegionParam().first) {
12116 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12117 TotalDepCount.setIsUnsigned(
true);
12120 for (
Expr *RefExpr : VarList) {
12121 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
12122 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12124 Vars.push_back(RefExpr);
12130 if (DepKind == OMPC_DEPEND_sink) {
12131 if (
DSAStack->getParentOrderedRegionParam().first &&
12132 DepCounter >= TotalDepCount) {
12133 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12145 if (CurContext->isDependentContext()) {
12147 Vars.push_back(RefExpr);
12153 Expr *LHS = SimpleExpr;
12154 Expr *RHS =
nullptr;
12155 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12157 OOLoc = BO->getOperatorLoc();
12160 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12161 OOK = OCE->getOperator();
12162 OOLoc = OCE->getOperatorLoc();
12165 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12166 OOK = MCE->getMethodDecl()
12169 .getCXXOverloadedOperator();
12170 OOLoc = MCE->getCallee()->getExprLoc();
12179 Vars.push_back(RefExpr);
12185 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
12186 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12190 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12191 RHS, OMPC_depend,
false);
12195 if (!CurContext->isDependentContext() &&
12196 DSAStack->getParentOrderedRegionParam().first &&
12197 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
12199 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12201 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12204 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12207 OpsOffs.emplace_back(RHS, OOK);
12210 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12212 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12213 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12214 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12215 << RefExpr->getSourceRange();
12218 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12219 getDiagnostics().setSuppressAllDiagnostics(
true);
12221 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12222 getDiagnostics().setSuppressAllDiagnostics(Suppress);
12223 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12224 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12225 << RefExpr->getSourceRange();
12229 Vars.push_back(RefExpr->IgnoreParenImpCasts());
12232 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12233 TotalDepCount > VarList.size() &&
12234 DSAStack->getParentOrderedRegionParam().first &&
12235 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12236 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12237 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12239 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12244 DepKind, DepLoc, ColonLoc, Vars,
12245 TotalDepCount.getZExtValue());
12246 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12247 DSAStack->isParentOrderedRegion())
12248 DSAStack->addDoacrossDependClause(
C, OpsOffs);
12255 Expr *ValExpr = Device;
12256 Stmt *HelperValStmt =
nullptr;
12267 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
12268 ValExpr = MakeFullExpr(ValExpr).get();
12269 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12270 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12274 return new (Context)
OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12275 StartLoc, LParenLoc, EndLoc);
12280 bool FullCheck =
true) {
12283 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
12288 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12303 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12304 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
12305 return ATy->getSize().getSExtValue() != 1;
12310 assert(OASE &&
"Expecting array section if not an array subscript.");
12311 const Expr *LowerBound = OASE->getLowerBound();
12312 const Expr *Length = OASE->getLength();
12321 llvm::APSInt ConstLowerBound = Result.
Val.
getInt();
12322 if (ConstLowerBound.getSExtValue())
12345 llvm::APSInt ConstLength = Result.
Val.
getInt();
12346 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12359 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12362 assert(OASE &&
"Expecting array section if not an array subscript.");
12363 const Expr *Length = OASE->getLength();
12369 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
12370 return ATy->getSize().getSExtValue() != 1;
12380 llvm::APSInt ConstLength = Result.
Val.
getInt();
12381 return ConstLength.getSExtValue() != 1;
12414 const Expr *RelevantExpr =
nullptr;
12433 bool AllowUnitySizeArraySection =
true;
12434 bool AllowWholeSizeArraySection =
true;
12436 while (!RelevantExpr) {
12439 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12440 if (!isa<VarDecl>(CurE->getDecl()))
12443 RelevantExpr = CurE;
12447 AllowUnitySizeArraySection =
false;
12448 AllowWholeSizeArraySection =
false;
12451 CurComponents.emplace_back(CurE, CurE->getDecl());
12452 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
12455 if (isa<CXXThisExpr>(BaseE))
12457 RelevantExpr = CurE;
12461 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12463 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12464 << CurE->getSourceRange();
12472 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12477 if (FD->isBitField()) {
12479 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12499 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
12500 << CurE->getSourceRange();
12513 AllowUnitySizeArraySection =
false;
12514 AllowWholeSizeArraySection =
false;
12517 CurComponents.emplace_back(CurE, FD);
12518 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
12523 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
12524 << 0 << CurE->getSourceRange();
12535 AllowWholeSizeArraySection =
false;
12537 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12539 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.
getASTContext())) {
12540 if (!Result.
Val.
getInt().isNullValue()) {
12541 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
12542 diag::err_omp_invalid_map_this_expr);
12543 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
12544 diag::note_omp_invalid_subscript_on_this_ptr_map);
12551 CurComponents.emplace_back(CurE,
nullptr);
12552 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
12553 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
12568 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
12569 << 0 << CurE->getSourceRange();
12578 if (AllowWholeSizeArraySection) {
12585 if (NotWhole || IsPointer)
12586 AllowWholeSizeArraySection =
false;
12587 }
else if (AllowUnitySizeArraySection && NotUnity) {
12591 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12592 << CurE->getSourceRange();
12596 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12599 if (CurE->getLength()->EvaluateAsInt(ResultR,
12601 if (!ResultR.
Val.
getInt().isOneValue()) {
12602 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
12603 diag::err_omp_invalid_map_this_expr);
12604 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
12605 diag::note_omp_invalid_length_on_this_ptr_mapping);
12608 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
12610 if (!ResultL.
Val.
getInt().isNullValue()) {
12611 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
12612 diag::err_omp_invalid_map_this_expr);
12613 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
12614 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
12621 CurComponents.emplace_back(CurE,
nullptr);
12626 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12633 return RelevantExpr;
12640 bool CurrentRegionOnly,
12651 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
12652 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12653 "Map clause expression with unexpected base!");
12656 bool IsEnclosedByDataEnvironmentExpr =
false;
12657 const Expr *EnclosingExpr =
nullptr;
12659 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12660 VD, CurrentRegionOnly,
12661 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12662 ERange, CKind, &EnclosingExpr,
12666 assert(!StackComponents.empty() &&
12667 "Map clause expression with no components!");
12668 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12669 "Map clause expression with unexpected base!");
12673 const Expr *RE = StackComponents.front().getAssociatedExpression();
12679 auto CI = CurComponents.rbegin();
12680 auto CE = CurComponents.rend();
12681 auto SI = StackComponents.rbegin();
12682 auto SE = StackComponents.rend();
12683 for (; CI != CE && SI != SE; ++CI, ++SI) {
12688 if (CurrentRegionOnly &&
12689 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12690 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12691 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12692 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12693 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
12694 diag::err_omp_multiple_array_items_in_map_clause)
12695 << CI->getAssociatedExpression()->getSourceRange();
12696 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
12697 diag::note_used_here)
12698 << SI->getAssociatedExpression()->getSourceRange();
12703 if (CI->getAssociatedExpression()->getStmtClass() !=
12704 SI->getAssociatedExpression()->getStmtClass())
12708 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12714 for (; SI != SE; ++SI) {
12716 if (
const auto *ASE =
12717 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12718 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12719 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12720 SI->getAssociatedExpression())) {
12727 SemaRef, SI->getAssociatedExpression(), Type))
12737 if (CI == CE && SI == SE) {
12738 if (CurrentRegionOnly) {
12739 if (CKind == OMPC_map) {
12740 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12742 assert(CKind == OMPC_to || CKind == OMPC_from);
12743 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12746 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12747 << RE->getSourceRange();
12752 IsEnclosedByDataEnvironmentExpr =
true;
12757 std::prev(CI)->getAssociatedDeclaration()->getType();
12759 std::prev(CI)->getAssociatedExpression()->getExprLoc();
12778 if (CI == CE || SI == SE) {
12781 diag::err_omp_pointer_mapped_along_with_derived_section)
12783 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12784 << RE->getSourceRange();
12787 if (CI->getAssociatedExpression()->getStmtClass() !=
12788 SI->getAssociatedExpression()->getStmtClass() ||
12789 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12790 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12791 assert(CI != CE && SI != SE);
12792 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12794 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12795 << RE->getSourceRange();
12805 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12806 if (CKind == OMPC_map) {
12807 if (CI != CE || SI != SE) {
12811 CI != CE ? CurComponents.begin() : StackComponents.begin();
12812 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
12814 while (It !=
End && !It->getAssociatedDeclaration())
12815 std::advance(It, 1);
12816 assert(It !=
End &&
12817 "Expected at least one component with the declaration.");
12818 if (It !=
Begin && It->getAssociatedDeclaration()
12820 .getCanonicalType()
12821 ->isAnyPointerType()) {
12822 IsEnclosedByDataEnvironmentExpr =
false;
12823 EnclosingExpr =
nullptr;
12827 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12829 assert(CKind == OMPC_to || CKind == OMPC_from);
12830 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12833 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
12834 << RE->getSourceRange();
12840 if (!CurrentRegionOnly && SI != SE)
12841 EnclosingExpr = RE;
12845 IsEnclosedByDataEnvironmentExpr |=
12846 (!CurrentRegionOnly && CI != CE && SI == SE);
12851 if (CurrentRegionOnly)
12865 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12867 diag::err_omp_original_storage_is_shared_and_does_not_contain)
12880 struct MappableVarListInfo {
12893 VarComponents.reserve(VarList.size());
12894 VarBaseDeclarations.reserve(VarList.size());
12909 bool IsMapTypeImplicit =
false) {
12911 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12912 "Unexpected clause kind with mappable expressions!");
12920 for (
Expr *RE : MVLI.VarList) {
12921 assert(RE &&
"Null expr in omp to/from/map clause");
12931 MVLI.ProcessedVarList.push_back(RE);
12939 diag::err_omp_expected_named_var_member_or_array_expression)
12950 SemaRef, SimpleExpr, CurComponents, CKind,
false);
12954 assert(!CurComponents.empty() &&
12955 "Invalid mappable expression information.");
12957 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
12959 DSAS->addMappedClassesQualTypes(TE->getType());
12961 MVLI.ProcessedVarList.push_back(RE);
12962 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12963 MVLI.VarComponents.back().append(CurComponents.begin(),
12964 CurComponents.end());
12965 MVLI.VarBaseDeclarations.push_back(
nullptr);
12972 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12973 assert(CurDeclaration &&
"Null decl on map clause.");
12976 "Expecting components to have associated only canonical declarations.");
12978 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
12979 const auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
12981 assert((VD || FD) &&
"Only variables or fields are expected here!");
12988 if (VD && DSAS->isThreadPrivate(VD)) {
12989 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
12990 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
13005 true, CurComponents, CKind))
13007 if (CKind == OMPC_map &&
13009 false, CurComponents, CKind))
13016 auto I = llvm::find_if(
13021 assert(I != CurComponents.end() &&
"Null decl on map clause.");
13023 I->getAssociatedDeclaration()->getType().getNonReferenceType();
13033 if (CKind == OMPC_map) {
13039 if (DKind == OMPD_target_enter_data &&
13040 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13041 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13042 << (IsMapTypeImplicit ? 1 : 0)
13052 if (DKind == OMPD_target_exit_data &&
13053 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13054 MapType == OMPC_MAP_delete)) {
13055 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13056 << (IsMapTypeImplicit ? 1 : 0)
13066 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
13068 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13079 MVLI.ProcessedVarList.push_back(RE);
13083 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13089 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13090 MVLI.VarComponents.back().append(CurComponents.begin(),
13091 CurComponents.end());
13092 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 13104 MappableVarListInfo MVLI(VarList);
13106 MapType, IsMapTypeImplicit);
13113 unsigned Count = 0;
13114 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
13115 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13116 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13117 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13121 "Modifiers exceed the allowed number of map type modifiers");
13122 Modifiers[Count] = MapTypeModifiers[I];
13123 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13130 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13131 MVLI.VarComponents, Modifiers, ModifiersLoc,
13132 MapType, IsMapTypeImplicit, MapLoc);
13139 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
13140 if (ReductionType.isNull())
13147 if (ReductionType.hasQualifiers()) {
13148 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13152 if (ReductionType->isFunctionType()) {
13153 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13156 if (ReductionType->isReferenceType()) {
13157 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13160 if (ReductionType->isArrayType()) {
13161 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13164 return ReductionType;
13169 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
13172 Decls.reserve(ReductionTypes.size());
13175 forRedeclarationInCurContext());
13180 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13182 bool InCompoundScope =
true;
13183 if (S !=
nullptr) {
13189 LookupName(Lookup, S);
13190 FilterLookupForScope(Lookup, DC, S,
false,
13192 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13195 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.
next());
13196 if (InCompoundScope) {
13197 auto I = UsedAsPrevious.find(PrevDecl);
13198 if (I == UsedAsPrevious.end())
13199 UsedAsPrevious[PrevDecl] =
false;
13201 UsedAsPrevious[D] =
true;
13203 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13204 PrevDecl->getLocation();
13207 if (InCompoundScope) {
13208 for (
const auto &PrevData : UsedAsPrevious) {
13209 if (!PrevData.second) {
13210 PrevDRD = PrevData.first;
13215 }
else if (PrevDeclInScope !=
nullptr) {
13216 auto *PrevDRDInScope = PrevDRD =
13217 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13219 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13221 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13222 }
while (PrevDRDInScope !=
nullptr);
13224 for (
const auto &TyData : ReductionTypes) {
13225 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13226 bool Invalid =
false;
13227 if (I != PreviousRedeclTypes.end()) {
13228 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13230 Diag(I->second, diag::note_previous_definition);
13233 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13235 Name, TyData.first, PrevDRD);
13237 DRD->setAccess(AS);
13238 Decls.push_back(DRD);
13240 DRD->setInvalidDecl();
13245 return DeclGroupPtrTy::make(
13250 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13253 PushFunctionScope();
13254 setFunctionHasBranchProtectedScope();
13255 getCurFunction()->setHasOMPDeclareReductionCombiner();
13258 PushDeclContext(S, DRD);
13262 PushExpressionEvaluationContext(
13263 ExpressionEvaluationContext::PotentiallyEvaluated);
13265 QualType ReductionType = DRD->getType();
13282 if (S !=
nullptr) {
13283 PushOnScopeChains(OmpInParm, S);
13284 PushOnScopeChains(OmpOutParm, S);
13286 DRD->addDecl(OmpInParm);
13287 DRD->addDecl(OmpOutParm);
13293 DRD->setCombinerData(InE, OutE);
13297 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13298 DiscardCleanupsInEvaluationContext();
13299 PopExpressionEvaluationContext();
13302 PopFunctionScopeInfo();
13304 if (Combiner !=
nullptr)
13305 DRD->setCombiner(Combiner);
13307 DRD->setInvalidDecl();
13311 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13314 PushFunctionScope();
13315 setFunctionHasBranchProtectedScope();
13318 PushDeclContext(S, DRD);
13322 PushExpressionEvaluationContext(
13323 ExpressionEvaluationContext::PotentiallyEvaluated);
13325 QualType ReductionType = DRD->getType();
13342 if (S !=
nullptr) {
13343 PushOnScopeChains(OmpPrivParm, S);
13344 PushOnScopeChains(OmpOrigParm, S);
13346 DRD->addDecl(OmpPrivParm);
13347 DRD->addDecl(OmpOrigParm);
13353 DRD->setInitializerData(OrigE, PrivE);
13354 return OmpPrivParm;
13359 auto *DRD = cast<OMPDeclareReductionDecl>(D);
13360 DiscardCleanupsInEvaluationContext();
13361 PopExpressionEvaluationContext();
13364 PopFunctionScopeInfo();
13366 if (Initializer !=
nullptr) {
13368 }
else if (OmpPrivParm->
hasInit()) {
13369 DRD->setInitializer(OmpPrivParm->
getInit(),
13374 DRD->setInvalidDecl();
13380 for (
Decl *D : DeclReductions.
get()) {
13383 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
13389 return DeclReductions;
13396 Expr *ValExpr = NumTeams;
13397 Stmt *HelperValStmt =
nullptr;
13408 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
13409 ValExpr = MakeFullExpr(ValExpr).get();
13410 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13411 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13416 StartLoc, LParenLoc, EndLoc);
13423 Expr *ValExpr = ThreadLimit;
13424 Stmt *HelperValStmt =
nullptr;
13435 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
13436 ValExpr = MakeFullExpr(ValExpr).get();
13437 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13438 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13443 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13450 Expr *ValExpr = Priority;
13465 Expr *ValExpr = Grainsize;
13481 Expr *ValExpr = NumTasks;
13499 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
13502 return new (Context)
13511 std::string Values;
13515 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13519 Expr *ValExpr = ChunkSize;
13520 Stmt *HelperValStmt =
nullptr;
13527 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13531 ValExpr = Val.
get();
13538 if (Result.isSigned() && !Result.isStrictlyPositive()) {
13539 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13544 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
13546 !CurContext->isDependentContext()) {
13547 ValExpr = MakeFullExpr(ValExpr).get();
13548 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13549 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13555 return new (Context)
13557 Kind, ValExpr, HelperValStmt);
13565 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
13569 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
13571 OMPC_DEFAULTMAP_MODIFIER_tofrom);
13575 OMPC_DEFAULTMAP_scalar);
13579 Diag(Loc, diag::err_omp_unexpected_clause_value)
13583 DSAStack->setDefaultDMAToFromScalar(StartLoc);
13585 return new (Context)
13590 DeclContext *CurLexicalContext = getCurLexicalContext();
13594 !isa<CXXRecordDecl>(CurLexicalContext) &&
13595 !isa<ClassTemplateDecl>(CurLexicalContext) &&
13596 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
13597 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
13598 Diag(Loc, diag::err_omp_region_not_file_context);
13601 ++DeclareTargetNestingLevel;
13606 assert(DeclareTargetNestingLevel > 0 &&
13607 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
13608 --DeclareTargetNestingLevel;
13614 OMPDeclareTargetDeclAttr::MapTypeTy MT,
13617 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
13625 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr,
13626 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
13627 CTK_ErrorRecovery)) {
13628 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
13630 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
13639 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
13640 isa<FunctionTemplateDecl>(ND)) {
13644 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
13645 cast<ValueDecl>(ND));
13647 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13650 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13651 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Id.
getLoc());
13652 }
else if (*Res != MT) {
13653 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
13663 if (!D || !isa<VarDecl>(D))
13665 auto *VD = cast<VarDecl>(D);
13666 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
13668 SemaRef.
Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
13669 SemaRef.
Diag(SL, diag::note_used_here) << SR;
13673 Sema &SemaRef, DSAStackTy *Stack,
13675 return VD->
hasAttr<OMPDeclareTargetDeclAttr>() ||
13686 if (
auto *VD = dyn_cast<VarDecl>(D)) {
13688 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
13689 !VD->isStaticDataMember())
13693 if (
DSAStack->isThreadPrivate(VD)) {
13694 Diag(SL, diag::err_omp_threadprivate_in_target);
13699 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13700 D = FTD->getTemplatedDecl();
13701 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
13703 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
13704 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
13705 assert(IdLoc.
isValid() &&
"Source location is expected");
13706 Diag(IdLoc, diag::err_omp_function_in_link_clause);
13707 Diag(FD->getLocation(), diag::note_defined_here) << FD;
13711 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
13717 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
13719 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13720 isa<FunctionTemplateDecl>(D)) {
13721 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13722 Context, OMPDeclareTargetDeclAttr::MT_To);
13725 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13739 MappableVarListInfo MVLI(VarList);
13741 if (MVLI.ProcessedVarList.empty())
13745 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13746 MVLI.VarComponents);
13753 MappableVarListInfo MVLI(VarList);
13755 if (MVLI.ProcessedVarList.empty())
13759 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13760 MVLI.VarComponents);
13767 MappableVarListInfo MVLI(VarList);
13771 for (
Expr *RefExpr : VarList) {
13772 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
13775 Expr *SimpleRefExpr = RefExpr;
13779 MVLI.ProcessedVarList.push_back(RefExpr);
13780 PrivateCopies.push_back(
nullptr);
13781 Inits.push_back(
nullptr);
13790 auto *VD = dyn_cast<
VarDecl>(D);
13794 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13795 << 0 << RefExpr->getSourceRange();
13803 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
13804 if (VDPrivate->isInvalidDecl())
13807 CurContext->addDecl(VDPrivate);
13809 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13813 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
13815 *
this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13816 AddInitializerToDecl(VDPrivate,
13817 DefaultLvalueConversion(VDInitRefExpr).
get(),
13825 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13826 PrivateCopies.push_back(VDPrivateRefExpr);
13827 Inits.push_back(VDInitRefExpr);
13832 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13836 MVLI.VarBaseDeclarations.push_back(D);
13837 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13838 MVLI.VarComponents.back().push_back(
13842 if (MVLI.ProcessedVarList.empty())
13846 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13847 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13854 MappableVarListInfo MVLI(VarList);
13855 for (
Expr *RefExpr : VarList) {
13856 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
13859 Expr *SimpleRefExpr = RefExpr;
13863 MVLI.ProcessedVarList.push_back(RefExpr);
13873 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13874 << 0 << RefExpr->getSourceRange();
13880 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
13882 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13890 const Expr *ConflictExpr;
13891 if (
DSAStack->checkMappableExprComponentListsForDecl(
13896 ConflictExpr = R.front().getAssociatedExpression();
13899 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13908 DSAStack->addMappableExpressionComponents(
13909 D, MC, OMPC_is_device_ptr);
13912 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13917 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13918 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13919 "Unexpected device pointer expression!");
13920 MVLI.VarBaseDeclarations.push_back(
13921 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
13922 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13923 MVLI.VarComponents.back().push_back(MC);
13926 if (MVLI.ProcessedVarList.empty())
13930 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13931 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...
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.
ExprResult ActOnFinishFullExpr(Expr *Expr)
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.