34 using namespace clang;
50 class DSAStackTy final {
52 struct DSAVarData final {
55 Expr *RefExpr =
nullptr;
64 struct DSAInfo final {
68 llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
71 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
72 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
73 typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
74 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
77 struct MappedExprComponentTy {
81 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
82 MappedExprComponentsTy;
83 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
85 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
88 struct SharingMapTy final {
89 DeclSAMapTy SharingMap;
90 AlignedMapTy AlignedMap;
91 MappedExprComponentsTy MappedExprComponents;
92 LoopControlVariablesMapTy LCVMap;
97 Scope *CurScope =
nullptr;
102 DoacrossDependMapTy DoacrossDepends;
106 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
107 bool NowaitRegion =
false;
108 bool CancelRegion =
false;
109 unsigned AssociatedLoops = 1;
113 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
121 DeclSAMapTy Threadprivates;
128 bool ForceCapturing =
false;
129 CriticalsWithHintsTy Criticals;
133 DSAVarData getDSA(StackTy::reverse_iterator &Iter,
ValueDecl *D);
136 bool isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter);
138 bool isStackEmpty()
const {
139 return Stack.empty() ||
140 Stack.back().second != CurrentNonCapturingFunctionScope ||
141 Stack.back().first.empty();
145 explicit DSAStackTy(
Sema &
S) : SemaRef(S) {}
147 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
150 bool isForceVarCapturing()
const {
return ForceCapturing; }
151 void setForceVarCapturing(
bool V) { ForceCapturing = V; }
156 Stack.back().second != CurrentNonCapturingFunctionScope)
157 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
158 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
159 Stack.back().first.back().DefaultAttrLoc = Loc;
163 assert(!
Stack.back().first.empty() &&
164 "Data-sharing attributes stack is empty!");
165 Stack.back().first.pop_back();
169 void pushFunction() {
171 assert(!isa<CapturingScopeInfo>(CurFnScope));
172 CurrentNonCapturingFunctionScope = CurFnScope;
176 if (!
Stack.empty() &&
Stack.back().second == OldFSI) {
177 assert(
Stack.back().first.empty());
180 CurrentNonCapturingFunctionScope =
nullptr;
182 if (!isa<CapturingScopeInfo>(FSI)) {
183 CurrentNonCapturingFunctionScope = FSI;
192 const std::pair<OMPCriticalDirective *, llvm::APSInt>
195 if (
I != Criticals.end())
197 return std::make_pair(
nullptr, llvm::APSInt());
210 LCDeclInfo isLoopControlVariable(
ValueDecl *D);
215 LCDeclInfo isParentLoopControlVariable(
ValueDecl *D);
218 ValueDecl *getParentLoopControlVariable(
unsigned I);
226 DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
228 DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent);
249 unsigned Level,
bool NotLastprivate =
false);
253 bool hasExplicitDirective(
269 if (isStackEmpty() ||
Stack.back().first.size() == 1)
276 assert(!isStackEmpty());
277 Stack.back().first.back().DefaultAttr = DSA_none;
278 Stack.back().first.back().DefaultAttrLoc = Loc;
282 assert(!isStackEmpty());
283 Stack.back().first.back().DefaultAttr = DSA_shared;
284 Stack.back().first.back().DefaultAttrLoc = Loc;
288 return isStackEmpty() ? DSA_unspecified
289 :
Stack.back().first.back().DefaultAttr;
293 :
Stack.back().first.back().DefaultAttrLoc;
297 bool isThreadPrivate(
VarDecl *D) {
298 DSAVarData DVar = getTopDSA(D,
false);
303 void setOrderedRegion(
bool IsOrdered,
Expr *Param) {
304 assert(!isStackEmpty());
305 Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
306 Stack.back().first.back().OrderedRegion.setPointer(Param);
310 bool isParentOrderedRegion()
const {
311 if (isStackEmpty() ||
Stack.back().first.size() == 1)
313 return std::next(
Stack.back().first.rbegin())->OrderedRegion.getInt();
316 Expr *getParentOrderedRegionParam()
const {
317 if (isStackEmpty() ||
Stack.back().first.size() == 1)
319 return std::next(
Stack.back().first.rbegin())->OrderedRegion.getPointer();
322 void setNowaitRegion(
bool IsNowait =
true) {
323 assert(!isStackEmpty());
324 Stack.back().first.back().NowaitRegion = IsNowait;
328 bool isParentNowaitRegion()
const {
329 if (isStackEmpty() ||
Stack.back().first.size() == 1)
331 return std::next(
Stack.back().first.rbegin())->NowaitRegion;
334 void setParentCancelRegion(
bool Cancel =
true) {
335 if (!isStackEmpty() &&
Stack.back().first.size() > 1) {
336 auto &StackElemRef = *std::next(
Stack.back().first.rbegin());
337 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
341 bool isCancelRegion()
const {
342 return isStackEmpty() ?
false :
Stack.back().first.back().CancelRegion;
346 void setAssociatedLoops(
unsigned Val) {
347 assert(!isStackEmpty());
348 Stack.back().first.back().AssociatedLoops = Val;
351 unsigned getAssociatedLoops()
const {
352 return isStackEmpty() ? 0 :
Stack.back().first.back().AssociatedLoops;
358 if (!isStackEmpty() &&
Stack.back().first.size() > 1) {
359 std::next(
Stack.back().first.rbegin())->InnerTeamsRegionLoc =
364 bool hasInnerTeamsRegion()
const {
365 return getInnerTeamsRegionLoc().
isValid();
370 :
Stack.back().first.back().InnerTeamsRegionLoc;
373 Scope *getCurScope()
const {
374 return isStackEmpty() ?
nullptr :
Stack.back().first.back().CurScope;
376 Scope *getCurScope() {
377 return isStackEmpty() ?
nullptr :
Stack.back().first.back().CurScope;
381 :
Stack.back().first.back().ConstructLoc;
386 bool checkMappableExprComponentListsForDecl(
388 const llvm::function_ref<
393 auto SI =
Stack.back().first.rbegin();
394 auto SE =
Stack.back().first.rend();
399 if (CurrentRegionOnly) {
405 for (; SI != SE; ++SI) {
406 auto MI = SI->MappedExprComponents.find(VD);
407 if (MI != SI->MappedExprComponents.end())
408 for (
auto &L : MI->second.Components)
409 if (Check(L, MI->second.Kind))
417 bool checkMappableExprComponentListsForDeclAtLevel(
419 const llvm::function_ref<
425 auto StartI =
Stack.back().first.begin();
426 auto EndI =
Stack.back().first.end();
429 std::advance(StartI, Level);
431 auto MI = StartI->MappedExprComponents.find(VD);
432 if (MI != StartI->MappedExprComponents.end())
433 for (
auto &L : MI->second.Components)
434 if (Check(L, MI->second.Kind))
441 void addMappableExpressionComponents(
445 assert(!isStackEmpty() &&
446 "Not expecting to retrieve components from a empty stack!");
447 auto &MEC =
Stack.back().first.back().MappedExprComponents[VD];
449 MEC.Components.resize(MEC.Components.size() + 1);
450 MEC.Components.back().append(Components.begin(), Components.end());
451 MEC.Kind = WhereFoundClauseKind;
454 unsigned getNestingLevel()
const {
455 assert(!isStackEmpty());
456 return Stack.back().first.size() - 1;
458 void addDoacrossDependClause(
OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
459 assert(!isStackEmpty() &&
Stack.back().first.size() > 1);
460 auto &StackElem = *std::next(
Stack.back().first.rbegin());
462 StackElem.DoacrossDepends.insert({C, OpsOffs});
464 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
465 getDoacrossDependClauses()
const {
466 assert(!isStackEmpty());
467 auto &StackElem =
Stack.back().first.back();
469 auto &Ref = StackElem.DoacrossDepends;
470 return llvm::make_range(Ref.begin(), Ref.end());
472 return llvm::make_range(StackElem.DoacrossDepends.end(),
473 StackElem.DoacrossDepends.end());
483 auto *VD = dyn_cast<
VarDecl>(D);
490 FD = FD->getCanonicalDecl();
496 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
499 auto *VD = dyn_cast<
VarDecl>(D);
502 if (isStackEmpty() || Iter ==
Stack.back().first.rend()) {
508 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
509 DVar.CKind = OMPC_shared;
515 if (VD && VD->hasGlobalStorage())
516 DVar.CKind = OMPC_shared;
520 DVar.CKind = OMPC_shared;
525 DVar.DKind = Iter->Directive;
530 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
531 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
532 DVar.CKind = OMPC_private;
538 if (Iter->SharingMap.count(D)) {
539 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
540 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
541 DVar.CKind = Iter->SharingMap[D].Attributes;
542 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
550 switch (Iter->DefaultAttr) {
552 DVar.CKind = OMPC_shared;
553 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
557 case DSA_unspecified:
562 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
565 DVar.CKind = OMPC_shared;
576 auto I = Iter,
E =
Stack.back().first.rend();
584 DVarTemp = getDSA(
I, D);
585 if (DVarTemp.CKind != OMPC_shared) {
586 DVar.RefExpr =
nullptr;
587 DVar.CKind = OMPC_firstprivate;
590 }
while (
I != E && !isParallelOrTaskRegion(
I->Directive));
592 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
601 return getDSA(++Iter, D);
605 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
607 auto &StackElem =
Stack.back().first.back();
608 auto It = StackElem.AlignedMap.find(D);
609 if (It == StackElem.AlignedMap.end()) {
610 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
611 StackElem.AlignedMap[D] = NewDE;
614 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
621 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
623 auto &StackElem =
Stack.back().first.back();
624 StackElem.LCVMap.insert(
625 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
628 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(
ValueDecl *D) {
629 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
631 auto &StackElem =
Stack.back().first.back();
632 auto It = StackElem.LCVMap.find(D);
633 if (It != StackElem.LCVMap.end())
638 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(
ValueDecl *D) {
639 assert(!isStackEmpty() &&
Stack.back().first.size() > 1 &&
640 "Data-sharing attributes stack is empty");
642 auto &StackElem = *std::next(
Stack.back().first.rbegin());
643 auto It = StackElem.LCVMap.find(D);
644 if (It != StackElem.LCVMap.end())
649 ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I) {
650 assert(!isStackEmpty() &&
Stack.back().first.size() > 1 &&
651 "Data-sharing attributes stack is empty");
652 auto &StackElem = *std::next(
Stack.back().first.rbegin());
653 if (StackElem.LCVMap.size() <
I)
655 for (
auto &Pair : StackElem.LCVMap)
656 if (Pair.second.first == I)
665 auto &Data = Threadprivates[D];
667 Data.RefExpr.setPointer(E);
668 Data.PrivateCopy =
nullptr;
670 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
671 auto &Data =
Stack.back().first.back().SharingMap[D];
672 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
673 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
674 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
675 (isLoopControlVariable(D).first && A == OMPC_private));
676 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
677 Data.RefExpr.setInt(
true);
680 const bool IsLastprivate =
681 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
683 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
684 Data.PrivateCopy = PrivateCopy;
686 auto &Data =
Stack.back().first.back().SharingMap[PrivateCopy->
getDecl()];
688 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
689 Data.PrivateCopy =
nullptr;
694 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, StackTy::reverse_iterator Iter) {
696 if (!isStackEmpty() &&
Stack.back().first.size() > 1) {
697 reverse_iterator I = Iter, E =
Stack.back().first.rend();
698 Scope *TopScope =
nullptr;
699 while (I != E && !isParallelOrTaskRegion(I->Directive))
703 TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
704 Scope *CurScope = getCurScope();
705 while (CurScope != TopScope && !CurScope->
isDeclScope(D))
707 return CurScope != TopScope;
714 StringRef Name,
const AttrVec *Attrs =
nullptr) {
731 bool RefersToCapture =
false) {
739 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
bool FromParent) {
746 auto *VD = dyn_cast<
VarDecl>(D);
747 if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
748 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
749 SemaRef.getLangOpts().OpenMPUseTLS &&
750 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
752 VD->
hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
757 auto TI = Threadprivates.find(D);
758 if (TI != Threadprivates.end()) {
759 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
776 if (VD && VD->isStaticDataMember()) {
777 DSAVarData DVarTemp = hasDSA(D,
isOpenMPPrivate, MatchesAlways, FromParent);
781 DVar.CKind = OMPC_shared;
786 bool IsConstant = Type.
isConstant(SemaRef.getASTContext());
787 Type = SemaRef.getASTContext().getBaseElementType(Type);
794 if (
auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
795 if (
auto *CTD = CTSD->getSpecializedTemplate())
796 RD = CTD->getTemplatedDecl();
798 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->
hasDefinition() &&
802 DSAVarData DVarTemp = hasDSA(
804 MatchesAlways, FromParent);
805 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
808 DVar.CKind = OMPC_shared;
814 auto StartI = std::next(
Stack.back().first.rbegin());
815 auto EndI =
Stack.back().first.rend();
816 if (FromParent && StartI != EndI)
817 StartI = std::next(StartI);
818 auto I = std::prev(StartI);
819 if (I->SharingMap.count(D)) {
820 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
821 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
822 DVar.CKind = I->SharingMap[D].Attributes;
823 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
829 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
831 if (isStackEmpty()) {
832 StackTy::reverse_iterator
I;
836 auto StartI =
Stack.back().first.rbegin();
837 auto EndI =
Stack.back().first.rend();
838 if (FromParent && StartI != EndI)
839 StartI = std::next(StartI);
840 return getDSA(StartI, D);
843 DSAStackTy::DSAVarData
851 auto I = (FromParent &&
Stack.back().first.size() > 1)
852 ? std::next(
Stack.back().first.rbegin())
853 :
Stack.back().first.rbegin();
854 auto EndI =
Stack.back().first.rend();
857 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
859 DSAVarData DVar = getDSA(I, D);
860 if (CPred(DVar.CKind))
866 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
873 auto StartI = std::next(
Stack.back().first.rbegin());
874 auto EndI =
Stack.back().first.rend();
875 if (FromParent && StartI != EndI)
876 StartI = std::next(StartI);
877 if (StartI == EndI || !DPred(StartI->Directive))
879 DSAVarData DVar = getDSA(StartI, D);
880 return CPred(DVar.CKind) ? DVar : DSAVarData();
883 bool DSAStackTy::hasExplicitDSA(
885 unsigned Level,
bool NotLastprivate) {
886 if (CPred(ClauseKindMode))
891 auto StartI =
Stack.back().first.begin();
892 auto EndI =
Stack.back().first.end();
895 std::advance(StartI, Level);
896 return (StartI->SharingMap.count(D) > 0) &&
897 StartI->SharingMap[D].RefExpr.getPointer() &&
898 CPred(StartI->SharingMap[D].Attributes) &&
899 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
902 bool DSAStackTy::hasExplicitDirective(
907 auto StartI =
Stack.back().first.begin();
908 auto EndI =
Stack.back().first.end();
911 std::advance(StartI, Level);
912 return DPred(StartI->Directive);
915 bool DSAStackTy::hasDirective(
923 auto StartI = std::next(
Stack.back().first.rbegin());
924 auto EndI =
Stack.back().first.rend();
925 if (FromParent && StartI != EndI)
926 StartI = std::next(StartI);
927 for (
auto I = StartI, EE = EndI; I != EE; ++
I) {
928 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
934 void Sema::InitDataSharingAttributesStack() {
935 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
938 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
940 void Sema::pushOpenMPFunctionRegion() {
949 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1012 if (Ty->isReferenceType())
1018 bool IsVariableUsedInMapClause =
false;
1019 bool IsVariableAssociatedWithSection =
false;
1021 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1028 if (WhereFoundClauseKind != OMPC_map)
1031 auto EI = MapExprComponents.rbegin();
1032 auto EE = MapExprComponents.rend();
1034 assert(EI != EE &&
"Invalid map expression!");
1036 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1037 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1043 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1044 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1045 isa<MemberExpr>(EI->getAssociatedExpression())) {
1046 IsVariableAssociatedWithSection =
true;
1055 if (IsVariableUsedInMapClause) {
1058 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1061 IsByRef = !Ty->isScalarType();
1065 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1066 IsByRef = !
DSAStack->hasExplicitDSA(
1076 (Ctx.getTypeSizeInChars(Ty) >
1077 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1078 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1085 unsigned Sema::getOpenMPNestingLevel()
const {
1087 return DSAStack->getNestingLevel();
1091 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1101 auto *VD = dyn_cast<
VarDecl>(D);
1102 if (VD && !VD->hasLocalStorage()) {
1103 if (
DSAStack->getCurrentDirective() == OMPD_target &&
1116 (!
DSAStack->isClauseParsingMode() ||
1118 auto &&Info =
DSAStack->isLoopControlVariable(D);
1120 (VD && VD->hasLocalStorage() &&
1121 isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) ||
1122 (VD &&
DSAStack->isForceVarCapturing()))
1123 return VD ? VD : Info.second;
1124 auto DVarPrivate =
DSAStack->getTopDSA(D,
DSAStack->isClauseParsingMode());
1126 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1131 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1137 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1143 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
1146 auto *VD = dyn_cast<
VarDecl>(D);
1147 return VD && !VD->hasLocalStorage() &&
1152 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1157 DSAStack->push(DKind, DirName, CurScope, Loc);
1176 if (
auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1177 for (
auto *C : D->clauses()) {
1178 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1180 for (
auto *DE : Clause->varlists()) {
1181 if (DE->isValueDependent() || DE->isTypeDependent()) {
1182 PrivateCopies.push_back(
nullptr);
1185 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1186 VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1187 QualType Type = VD->getType().getNonReferenceType();
1188 auto DVar =
DSAStack->getTopDSA(VD,
false);
1189 if (DVar.CKind == OMPC_lastprivate) {
1196 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
1197 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
1199 if (VDPrivate->isInvalidDecl())
1202 *
this, VDPrivate, DE->getType(), DE->getExprLoc()));
1206 PrivateCopies.push_back(
nullptr);
1210 if (PrivateCopies.size() == Clause->varlist_size())
1211 Clause->setPrivateCopies(PrivateCopies);
1222 Expr *NumIterations,
Sema &SemaRef,
1232 explicit VarDeclFilterCCC(
Sema &
S) : SemaRef(S) {}
1233 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1235 if (
auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1236 return VD->hasGlobalStorage() &&
1237 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1238 SemaRef.getCurScope());
1249 explicit VarOrFuncDeclFilterCCC(
Sema &
S) : SemaRef(S) {}
1250 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
1252 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
1253 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1254 SemaRef.getCurScope());
1278 ? diag::err_undeclared_var_use_suggest
1279 : diag::err_omp_expected_var_arg_suggest)
1281 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
1284 : diag::err_omp_expected_var_arg)
1300 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
1305 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1311 NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1322 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1337 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1353 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1367 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1399 class LocalVarRefChecker :
public ConstStmtVisitor<LocalVarRefChecker, bool> {
1404 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1405 if (VD->hasLocalStorage()) {
1407 diag::err_omp_local_var_in_threadprivate_init)
1409 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
1416 bool VisitStmt(
const Stmt *
S) {
1418 if (Child && Visit(Child))
1423 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
1430 for (
auto &RefExpr : VarList) {
1436 VD->setReferenced();
1449 diag::err_omp_threadprivate_incomplete_type)) {
1455 if (VD->getType()->isReferenceType()) {
1456 Diag(ILoc, diag::err_omp_ref_type_arg)
1460 Diag(VD->getLocation(),
1461 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1469 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1472 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1473 !VD->isLocalVarDecl())) {
1474 Diag(ILoc, diag::err_omp_var_thread_local)
1478 Diag(VD->getLocation(),
1479 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1486 if (
auto Init = VD->getAnyInitializer()) {
1487 LocalVarRefChecker Checker(*
this);
1488 if (Checker.Visit(Init))
1492 Vars.push_back(RefExpr);
1494 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1497 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1500 if (!Vars.empty()) {
1509 const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1510 bool IsLoopIterVar =
false) {
1512 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1517 PDSA_StaticMemberShared,
1518 PDSA_StaticLocalVarShared,
1519 PDSA_LoopIterVarPrivate,
1520 PDSA_LoopIterVarLinear,
1521 PDSA_LoopIterVarLastprivate,
1522 PDSA_ConstVarShared,
1523 PDSA_GlobalVarShared,
1524 PDSA_TaskVarFirstprivate,
1525 PDSA_LocalVarPrivate,
1527 } Reason = PDSA_Implicit;
1528 bool ReportHint =
false;
1530 auto *VD = dyn_cast<
VarDecl>(D);
1531 if (IsLoopIterVar) {
1532 if (DVar.CKind == OMPC_private)
1533 Reason = PDSA_LoopIterVarPrivate;
1534 else if (DVar.CKind == OMPC_lastprivate)
1535 Reason = PDSA_LoopIterVarLastprivate;
1537 Reason = PDSA_LoopIterVarLinear;
1539 DVar.CKind == OMPC_firstprivate) {
1540 Reason = PDSA_TaskVarFirstprivate;
1541 ReportLoc = DVar.ImplicitDSALoc;
1542 }
else if (VD && VD->isStaticLocal())
1543 Reason = PDSA_StaticLocalVarShared;
1544 else if (VD && VD->isStaticDataMember())
1545 Reason = PDSA_StaticMemberShared;
1546 else if (VD && VD->isFileVarDecl())
1547 Reason = PDSA_GlobalVarShared;
1549 Reason = PDSA_ConstVarShared;
1550 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1552 Reason = PDSA_LocalVarPrivate;
1554 if (Reason != PDSA_Implicit) {
1555 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1556 << Reason << ReportHint
1558 }
else if (DVar.ImplicitDSALoc.isValid()) {
1559 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1565 class DSAAttrChecker :
public StmtVisitor<DSAAttrChecker, void> {
1571 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1578 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
1580 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD))
1583 auto DVar =
Stack->getTopDSA(VD,
false);
1589 auto DKind =
Stack->getCurrentDirective();
1595 isParallelOrTaskRegion(DKind) &&
1596 VarsWithInheritedDSA.count(VD) == 0) {
1597 VarsWithInheritedDSA[VD] =
E;
1605 DVar =
Stack->hasInnermostDSA(
1614 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1620 DVar =
Stack->getImplicitDSA(VD,
false);
1622 !
Stack->isLoopControlVariable(VD).first)
1623 ImplicitFirstprivate.push_back(E);
1632 auto DVar =
Stack->getTopDSA(FD,
false);
1639 auto DKind =
Stack->getCurrentDirective();
1644 DVar =
Stack->hasInnermostDSA(
1654 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1660 DVar =
Stack->getImplicitDSA(FD,
false);
1662 !
Stack->isLoopControlVariable(FD).first)
1663 ImplicitFirstprivate.push_back(E);
1669 for (
auto *C : S->
clauses()) {
1672 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid()))
1673 for (
auto *CC : C->children()) {
1679 void VisitStmt(
Stmt *S) {
1681 if (C && !isa<OMPExecutableDirective>(C))
1686 bool isErrorFound() {
return ErrorFound; }
1687 ArrayRef<Expr *> getImplicitFirstprivate() {
return ImplicitFirstprivate; }
1688 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
1689 return VarsWithInheritedDSA;
1693 :
Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {}
1700 case OMPD_parallel_for:
1701 case OMPD_parallel_for_simd:
1702 case OMPD_parallel_sections:
1708 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1709 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1710 std::make_pair(StringRef(),
QualType())
1716 case OMPD_target_teams:
1717 case OMPD_target_parallel: {
1719 std::make_pair(StringRef(),
QualType())
1728 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1729 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1730 std::make_pair(StringRef(),
QualType())
1735 ParamsTeamsOrParallel);
1746 case OMPD_taskgroup:
1747 case OMPD_distribute:
1750 case OMPD_target_data:
1752 case OMPD_target_parallel_for:
1753 case OMPD_target_parallel_for_simd:
1754 case OMPD_target_simd: {
1756 std::make_pair(StringRef(),
QualType())
1769 std::make_pair(
".global_tid.", KmpInt32Ty),
1772 std::make_pair(
".copy_fn.",
1775 std::make_pair(StringRef(),
QualType())
1782 AlwaysInlineAttr::CreateImplicit(
1787 case OMPD_taskloop_simd: {
1799 std::make_pair(
".global_tid.", KmpInt32Ty),
1801 std::make_pair(
".privates.",
1807 std::make_pair(
".lb.", KmpUInt64Ty),
1808 std::make_pair(
".ub.", KmpUInt64Ty), std::make_pair(
".st.", KmpInt64Ty),
1809 std::make_pair(
".liter.", KmpInt32Ty),
1810 std::make_pair(
".reductions.",
1812 std::make_pair(StringRef(),
QualType())
1819 AlwaysInlineAttr::CreateImplicit(
1823 case OMPD_distribute_parallel_for_simd:
1824 case OMPD_distribute_simd:
1825 case OMPD_distribute_parallel_for:
1826 case OMPD_teams_distribute:
1827 case OMPD_teams_distribute_simd:
1828 case OMPD_teams_distribute_parallel_for_simd:
1829 case OMPD_teams_distribute_parallel_for:
1830 case OMPD_target_teams_distribute:
1831 case OMPD_target_teams_distribute_parallel_for:
1832 case OMPD_target_teams_distribute_parallel_for_simd:
1833 case OMPD_target_teams_distribute_simd: {
1838 std::make_pair(
".global_tid.", KmpInt32PtrTy),
1839 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
1842 std::make_pair(StringRef(),
QualType())
1848 case OMPD_threadprivate:
1849 case OMPD_taskyield:
1852 case OMPD_cancellation_point:
1855 case OMPD_target_enter_data:
1856 case OMPD_target_exit_data:
1857 case OMPD_declare_reduction:
1858 case OMPD_declare_simd:
1859 case OMPD_declare_target:
1860 case OMPD_end_declare_target:
1861 case OMPD_target_update:
1862 llvm_unreachable(
"OpenMP Directive is not allowed");
1864 llvm_unreachable(
"Unknown OpenMP directive");
1871 return CaptureRegions.size();
1875 Expr *CaptureExpr,
bool WithInit,
1876 bool AsExpression) {
1877 assert(CaptureExpr);
1907 CD = cast<OMPCapturedExprDecl>(VD);
1919 CaptureExpr,
true,
true);
1942 class CaptureRegionUnwinderRAII {
1949 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
1951 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
1952 ~CaptureRegionUnwinderRAII() {
1954 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
1955 while (--ThisCaptureLevel >= 0)
1956 S.ActOnCapturedRegionError();
1964 bool ErrorFound =
false;
1965 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
1966 *
this, ErrorFound,
DSAStack->getCurrentDirective());
1977 for (
auto *Clause : Clauses) {
1979 Clause->getClauseKind() == OMPC_copyprivate ||
1982 Clause->getClauseKind() == OMPC_copyin)) {
1983 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
1985 for (
auto *VarRef : Clause->children()) {
1986 if (
auto *E = cast_or_null<Expr>(VarRef)) {
1990 DSAStack->setForceVarCapturing(
false);
1991 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) {
1995 if (
auto *E = C->getPostUpdateExpr())
1999 if (Clause->getClauseKind() == OMPC_schedule)
2000 SC = cast<OMPScheduleClause>(Clause);
2001 else if (Clause->getClauseKind() == OMPC_ordered)
2002 OC = cast<OMPOrderedClause>(Clause);
2003 else if (Clause->getClauseKind() == OMPC_linear)
2004 LCs.push_back(cast<OMPLinearClause>(Clause));
2012 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2017 diag::err_omp_schedule_nonmonotonic_ordered)
2022 for (
auto *C : LCs) {
2023 Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2041 for (
auto ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2045 if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective())) {
2046 for (
auto *C : PICs) {
2053 if (CaptureRegion == ThisCaptureRegion ||
2055 if (
auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2056 for (
auto *D : DS->decls())
2071 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2074 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2075 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2078 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2088 if (Stack->getCurScope()) {
2089 auto ParentRegion = Stack->getParentDirective();
2090 auto OffendingRegion = ParentRegion;
2091 bool NestingProhibited =
false;
2092 bool CloseNesting =
true;
2093 bool OrphanSeen =
false;
2096 ShouldBeInParallelRegion,
2097 ShouldBeInOrderedRegion,
2098 ShouldBeInTargetRegion,
2099 ShouldBeInTeamsRegion
2100 } Recommend = NoRecommend;
2110 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
2111 ? diag::err_omp_prohibited_region_simd
2112 : diag::warn_omp_nesting_simd);
2113 return CurrentRegion != OMPD_simd;
2115 if (ParentRegion == OMPD_atomic) {
2118 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2121 if (CurrentRegion == OMPD_section) {
2126 if (ParentRegion != OMPD_sections &&
2127 ParentRegion != OMPD_parallel_sections) {
2128 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2141 if (CurrentRegion == OMPD_cancellation_point ||
2142 CurrentRegion == OMPD_cancel) {
2155 !((CancelRegion == OMPD_parallel &&
2156 (ParentRegion == OMPD_parallel ||
2157 ParentRegion == OMPD_target_parallel)) ||
2158 (CancelRegion == OMPD_for &&
2159 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2160 ParentRegion == OMPD_target_parallel_for)) ||
2161 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2162 (CancelRegion == OMPD_sections &&
2163 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2164 ParentRegion == OMPD_parallel_sections)));
2165 }
else if (CurrentRegion == OMPD_master) {
2171 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
2177 bool DeadLock = Stack->hasDirective(
2181 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
2182 PreviousCriticalLoc = Loc;
2189 SemaRef.
Diag(StartLoc,
2190 diag::err_omp_prohibited_region_critical_same_name)
2192 if (PreviousCriticalLoc.
isValid())
2193 SemaRef.
Diag(PreviousCriticalLoc,
2194 diag::note_omp_previous_critical_region);
2197 }
else if (CurrentRegion == OMPD_barrier) {
2203 ParentRegion == OMPD_master ||
2204 ParentRegion == OMPD_critical ||
2205 ParentRegion == OMPD_ordered;
2214 ParentRegion == OMPD_master ||
2215 ParentRegion == OMPD_critical ||
2216 ParentRegion == OMPD_ordered;
2217 Recommend = ShouldBeInParallelRegion;
2218 }
else if (CurrentRegion == OMPD_ordered) {
2227 NestingProhibited = ParentRegion == OMPD_critical ||
2230 Stack->isParentOrderedRegion());
2231 Recommend = ShouldBeInOrderedRegion;
2236 NestingProhibited = ParentRegion != OMPD_target;
2238 Recommend = ShouldBeInTargetRegion;
2239 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc());
2241 if (!NestingProhibited &&
2244 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2251 Recommend = ShouldBeInParallelRegion;
2253 if (!NestingProhibited &&
2259 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2260 Recommend = ShouldBeInTeamsRegion;
2262 if (!NestingProhibited &&
2269 NestingProhibited = Stack->hasDirective(
2273 OffendingRegion = K;
2279 CloseNesting =
false;
2281 if (NestingProhibited) {
2283 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2286 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
2299 bool ErrorFound =
false;
2300 unsigned NamedModifiersNumber = 0;
2304 for (
const auto *C : Clauses) {
2305 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2309 if (FoundNameModifiers[CurNM]) {
2310 S.
Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2315 NameModifierLoc.push_back(IC->getNameModifierLoc());
2316 ++NamedModifiersNumber;
2318 FoundNameModifiers[CurNM] = IC;
2325 bool MatchFound =
false;
2326 for (
auto NM : AllowedNameModifiers) {
2333 S.
Diag(IC->getNameModifierLoc(),
2334 diag::err_omp_wrong_if_directive_name_modifier)
2342 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
2343 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2345 diag::err_omp_no_more_if_clause);
2348 std::string Sep(
", ");
2349 unsigned AllowedCnt = 0;
2350 unsigned TotalAllowedNum =
2351 AllowedNameModifiers.size() - NamedModifiersNumber;
2352 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
2355 if (!FoundNameModifiers[NM]) {
2359 if (AllowedCnt + 2 == TotalAllowedNum)
2361 else if (AllowedCnt + 1 != TotalAllowedNum)
2367 diag::err_omp_unnamed_if_clause)
2368 << (TotalAllowedNum > 1) << Values;
2370 for (
auto Loc : NameModifierLoc) {
2371 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
2390 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2391 bool ErrorFound =
false;
2392 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2394 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
2397 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
2400 while (--ThisCaptureLevel >= 0)
2401 S = cast<CapturedStmt>(
S)->getCapturedStmt();
2402 DSAChecker.Visit(S);
2403 if (DSAChecker.isErrorFound())
2406 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2408 if (!DSAChecker.getImplicitFirstprivate().empty()) {
2412 ClausesWithImplicit.push_back(Implicit);
2413 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2414 DSAChecker.getImplicitFirstprivate().size();
2425 AllowedNameModifiers.push_back(OMPD_parallel);
2429 VarsWithInheritedDSA);
2433 VarsWithInheritedDSA);
2437 EndLoc, VarsWithInheritedDSA);
2444 assert(ClausesWithImplicit.empty() &&
2445 "No clauses are allowed for 'omp section' directive");
2453 assert(ClausesWithImplicit.empty() &&
2454 "No clauses are allowed for 'omp master' directive");
2461 case OMPD_parallel_for:
2463 EndLoc, VarsWithInheritedDSA);
2464 AllowedNameModifiers.push_back(OMPD_parallel);
2466 case OMPD_parallel_for_simd:
2468 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2469 AllowedNameModifiers.push_back(OMPD_parallel);
2471 case OMPD_parallel_sections:
2474 AllowedNameModifiers.push_back(OMPD_parallel);
2479 AllowedNameModifiers.push_back(OMPD_task);
2481 case OMPD_taskyield:
2482 assert(ClausesWithImplicit.empty() &&
2483 "No clauses are allowed for 'omp taskyield' directive");
2484 assert(AStmt ==
nullptr &&
2485 "No associated statement allowed for 'omp taskyield' directive");
2489 assert(ClausesWithImplicit.empty() &&
2490 "No clauses are allowed for 'omp barrier' directive");
2491 assert(AStmt ==
nullptr &&
2492 "No associated statement allowed for 'omp barrier' directive");
2496 assert(ClausesWithImplicit.empty() &&
2497 "No clauses are allowed for 'omp taskwait' directive");
2498 assert(AStmt ==
nullptr &&
2499 "No associated statement allowed for 'omp taskwait' directive");
2502 case OMPD_taskgroup:
2507 assert(AStmt ==
nullptr &&
2508 "No associated statement allowed for 'omp flush' directive");
2526 AllowedNameModifiers.push_back(OMPD_target);
2528 case OMPD_target_parallel:
2531 AllowedNameModifiers.push_back(OMPD_target);
2532 AllowedNameModifiers.push_back(OMPD_parallel);
2534 case OMPD_target_parallel_for:
2536 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2537 AllowedNameModifiers.push_back(OMPD_target);
2538 AllowedNameModifiers.push_back(OMPD_parallel);
2540 case OMPD_cancellation_point:
2541 assert(ClausesWithImplicit.empty() &&
2542 "No clauses are allowed for 'omp cancellation point' directive");
2543 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp "
2544 "cancellation point' directive");
2548 assert(AStmt ==
nullptr &&
2549 "No associated statement allowed for 'omp cancel' directive");
2552 AllowedNameModifiers.push_back(OMPD_cancel);
2554 case OMPD_target_data:
2557 AllowedNameModifiers.push_back(OMPD_target_data);
2559 case OMPD_target_enter_data:
2562 AllowedNameModifiers.push_back(OMPD_target_enter_data);
2564 case OMPD_target_exit_data:
2567 AllowedNameModifiers.push_back(OMPD_target_exit_data);
2571 EndLoc, VarsWithInheritedDSA);
2572 AllowedNameModifiers.push_back(OMPD_taskloop);
2574 case OMPD_taskloop_simd:
2576 EndLoc, VarsWithInheritedDSA);
2577 AllowedNameModifiers.push_back(OMPD_taskloop);
2579 case OMPD_distribute:
2581 EndLoc, VarsWithInheritedDSA);
2583 case OMPD_target_update:
2584 assert(!AStmt &&
"Statement is not allowed for target update");
2587 AllowedNameModifiers.push_back(OMPD_target_update);
2589 case OMPD_distribute_parallel_for:
2591 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2592 AllowedNameModifiers.push_back(OMPD_parallel);
2594 case OMPD_distribute_parallel_for_simd:
2596 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2597 AllowedNameModifiers.push_back(OMPD_parallel);
2599 case OMPD_distribute_simd:
2601 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2603 case OMPD_target_parallel_for_simd:
2605 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2606 AllowedNameModifiers.push_back(OMPD_target);
2607 AllowedNameModifiers.push_back(OMPD_parallel);
2609 case OMPD_target_simd:
2611 EndLoc, VarsWithInheritedDSA);
2612 AllowedNameModifiers.push_back(OMPD_target);
2614 case OMPD_teams_distribute:
2616 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2618 case OMPD_teams_distribute_simd:
2620 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2622 case OMPD_teams_distribute_parallel_for_simd:
2624 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2625 AllowedNameModifiers.push_back(OMPD_parallel);
2627 case OMPD_teams_distribute_parallel_for:
2629 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2630 AllowedNameModifiers.push_back(OMPD_parallel);
2632 case OMPD_target_teams:
2635 AllowedNameModifiers.push_back(OMPD_target);
2637 case OMPD_target_teams_distribute:
2639 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2640 AllowedNameModifiers.push_back(OMPD_target);
2642 case OMPD_target_teams_distribute_parallel_for:
2644 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2645 AllowedNameModifiers.push_back(OMPD_target);
2646 AllowedNameModifiers.push_back(OMPD_parallel);
2648 case OMPD_target_teams_distribute_parallel_for_simd:
2650 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2651 AllowedNameModifiers.push_back(OMPD_target);
2652 AllowedNameModifiers.push_back(OMPD_parallel);
2654 case OMPD_target_teams_distribute_simd:
2656 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2657 AllowedNameModifiers.push_back(OMPD_target);
2659 case OMPD_declare_target:
2660 case OMPD_end_declare_target:
2661 case OMPD_threadprivate:
2662 case OMPD_declare_reduction:
2663 case OMPD_declare_simd:
2664 llvm_unreachable(
"OpenMP Directive is not allowed");
2666 llvm_unreachable(
"Unknown OpenMP directive");
2669 for (
auto P : VarsWithInheritedDSA) {
2670 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
2671 <<
P.first <<
P.second->getSourceRange();
2673 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
2675 if (!AllowedNameModifiers.empty())
2676 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
2689 assert(Aligneds.size() == Alignments.size());
2690 assert(Linears.size() == LinModifiers.size());
2691 assert(Linears.size() == Steps.size());
2692 if (!DG || DG.
get().isNull())
2695 if (!DG.
get().isSingleDecl()) {
2696 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
2699 auto *ADecl = DG.
get().getSingleDecl();
2700 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
2701 ADecl = FTD->getTemplatedDecl();
2705 Diag(ADecl->getLocation(), diag::err_omp_function_expected);
2714 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
2721 llvm::DenseMap<Decl *, Expr *> UniformedArgs;
2722 Expr *UniformedLinearThis =
nullptr;
2723 for (
auto *E : Uniforms) {
2725 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
2726 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
2727 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
2728 FD->getParamDecl(PVD->getFunctionScopeIndex())
2730 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(),
E));
2733 if (isa<CXXThisExpr>(E)) {
2734 UniformedLinearThis =
E;
2738 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
2748 llvm::DenseMap<Decl *, Expr *> AlignedArgs;
2749 Expr *AlignedThis =
nullptr;
2750 for (
auto *E : Aligneds) {
2752 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
2753 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
2754 auto *CanonPVD = PVD->getCanonicalDecl();
2755 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
2756 FD->getParamDecl(PVD->getFunctionScopeIndex())
2760 if (AlignedArgs.count(CanonPVD) > 0) {
2763 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
2764 diag::note_omp_explicit_dsa)
2768 AlignedArgs[CanonPVD] =
E;
2770 .getNonReferenceType()
2771 .getUnqualifiedType()
2772 .getCanonicalType();
2775 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
2777 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
2782 if (isa<CXXThisExpr>(E)) {
2793 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
2800 for (
auto *E : Alignments) {
2803 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
2804 NewAligns.push_back(Align.
get());
2815 llvm::DenseMap<Decl *, Expr *> LinearArgs;
2816 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
2817 auto MI = LinModifiers.begin();
2818 for (
auto *E : Linears) {
2822 if (
auto *DRE = dyn_cast<DeclRefExpr>(E))
2823 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
2824 auto *CanonPVD = PVD->getCanonicalDecl();
2825 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
2826 FD->getParamDecl(PVD->getFunctionScopeIndex())
2830 if (LinearArgs.count(CanonPVD) > 0) {
2834 Diag(LinearArgs[CanonPVD]->getExprLoc(),
2835 diag::note_omp_explicit_dsa)
2840 if (UniformedArgs.count(CanonPVD) > 0) {
2844 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
2845 diag::note_omp_explicit_dsa)
2849 LinearArgs[CanonPVD] =
E;
2855 PVD->getOriginalType());
2859 if (isa<CXXThisExpr>(E)) {
2860 if (UniformedLinearThis) {
2865 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
2870 UniformedLinearThis =
E;
2879 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
2882 Expr *NewStep =
nullptr;
2884 for (
auto *E : Steps) {
2886 if (Step == E || !E) {
2887 NewSteps.push_back(E ? NewStep :
nullptr);
2891 if (
auto *DRE = dyn_cast<DeclRefExpr>(Step))
2892 if (
auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
2893 auto *CanonPVD = PVD->getCanonicalDecl();
2894 if (UniformedArgs.count(CanonPVD) == 0) {
2900 CanonPVD->getType()->hasIntegerRepresentation())
2901 NewSteps.push_back(Step);
2917 NewSteps.push_back(NewStep);
2919 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
2921 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
2922 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
2923 const_cast<Expr **
>(Linears.data()), Linears.size(),
2924 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
2925 NewSteps.data(), NewSteps.size(), SR);
2926 ADecl->addAttr(NewAttr);
2955 class OpenMPIterationSpaceChecker {
2971 Expr *LCRef =
nullptr;
2983 bool TestIsLessOp =
false;
2985 bool TestIsStrictOp =
false;
2987 bool SubtractStep =
false;
2991 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
2994 bool CheckInit(
Stmt *S,
bool EmitDiags =
true);
2997 bool CheckCond(
Expr *S);
3000 bool CheckInc(
Expr *S);
3002 ValueDecl *GetLoopDecl()
const {
return LCDecl; }
3004 Expr *GetLoopDeclRefExpr()
const {
return LCRef; }
3006 SourceRange GetInitSrcRange()
const {
return InitSrcRange; }
3008 SourceRange GetConditionSrcRange()
const {
return ConditionSrcRange; }
3010 SourceRange GetIncrementSrcRange()
const {
return IncrementSrcRange; }
3012 bool ShouldSubtractStep()
const {
return SubtractStep; }
3015 BuildNumIterations(
Scope *S,
const bool LimitedType,
3016 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3019 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const;
3021 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3022 DSAStackTy &DSA)
const;
3025 Expr *BuildPrivateCounterVar()
const;
3029 Expr *BuildCounterStep()
const;
3031 bool Dependent()
const;
3036 bool CheckIncRHS(
Expr *RHS);
3043 bool SetStep(
Expr *NewStep,
bool Subtract);
3046 bool OpenMPIterationSpaceChecker::Dependent()
const {
3048 assert(!LB && !UB && !
Step);
3051 return LCDecl->getType()->isDependentType() ||
3052 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3053 (
Step &&
Step->isValueDependent());
3056 static Expr *getExprAsWritten(
Expr *E) {
3057 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
3058 E = ExprTemp->getSubExpr();
3060 if (
auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
3061 E = MTE->GetTemporaryExpr();
3063 while (
auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
3064 E = Binder->getSubExpr();
3066 if (
auto *ICE = dyn_cast<ImplicitCastExpr>(E))
3067 E = ICE->getSubExprAsWritten();
3071 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(
ValueDecl *NewLCDecl,
3075 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
3076 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3077 if (!NewLCDecl || !NewLB)
3080 LCRef = NewLCRefExpr;
3081 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3083 if ((Ctor->isCopyOrMoveConstructor() ||
3084 Ctor->isConvertingConstructor(
false)) &&
3085 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3091 bool OpenMPIterationSpaceChecker::SetUB(
Expr *NewUB,
bool LessOp,
bool StrictOp,
3094 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
3095 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
3099 TestIsLessOp = LessOp;
3100 TestIsStrictOp = StrictOp;
3101 ConditionSrcRange = SR;
3106 bool OpenMPIterationSpaceChecker::SetStep(
Expr *NewStep,
bool Subtract) {
3108 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
3115 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
3118 NewStep = Val.
get();
3135 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3137 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3138 bool IsConstZero = IsConstant && !Result.getBoolValue();
3139 if (UB && (IsConstZero ||
3140 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3141 : (IsConstPos || (IsUnsigned && !Subtract))))) {
3143 diag::err_omp_loop_incr_not_compatible)
3145 SemaRef.Diag(ConditionLoc,
3146 diag::note_omp_loop_cond_requres_compatible_incr)
3147 << TestIsLessOp << ConditionSrcRange;
3150 if (TestIsLessOp == Subtract) {
3152 SemaRef.CreateBuiltinUnaryOp(NewStep->
getExprLoc(), UO_Minus, NewStep)
3154 Subtract = !Subtract;
3159 SubtractStep = Subtract;
3163 bool OpenMPIterationSpaceChecker::CheckInit(
Stmt *S,
bool EmitDiags) {
3174 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3178 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3179 if (!ExprTemp->cleanupsHaveSideEffects())
3180 S = ExprTemp->getSubExpr();
3183 if (
Expr *E = dyn_cast<Expr>(S))
3185 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3186 if (BO->getOpcode() == BO_Assign) {
3188 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3189 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3190 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3191 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3192 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3194 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3195 if (ME->isArrow() &&
3196 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3197 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3200 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
3201 if (DS->isSingleDecl()) {
3202 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3203 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3207 diag::ext_omp_loop_not_canonical_init)
3209 return SetLCDeclAndLB(Var,
nullptr, Var->getInit());
3213 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3214 if (CE->getOperator() == OO_Equal) {
3215 auto *LHS = CE->getArg(0);
3216 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3217 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3218 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3219 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3220 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3222 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
3223 if (ME->isArrow() &&
3224 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3225 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3230 if (Dependent() || SemaRef.CurContext->isDependentContext())
3233 SemaRef.Diag(S->
getLocStart(), diag::err_omp_loop_not_canonical_init)
3244 E = getExprAsWritten(E);
3245 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3247 if ((Ctor->isCopyOrMoveConstructor() ||
3248 Ctor->isConvertingConstructor(
false)) &&
3249 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
3251 if (
auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3252 if (
auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
3253 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3254 if (
auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3259 if (
auto *ME = dyn_cast_or_null<MemberExpr>(E))
3260 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3265 bool OpenMPIterationSpaceChecker::CheckCond(
Expr *S) {
3273 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3276 S = getExprAsWritten(S);
3278 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3279 if (BO->isRelationalOp()) {
3280 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3281 return SetUB(BO->getRHS(),
3282 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3283 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3284 BO->getSourceRange(), BO->getOperatorLoc());
3285 if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3286 return SetUB(BO->getLHS(),
3287 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3288 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3289 BO->getSourceRange(), BO->getOperatorLoc());
3291 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3292 if (CE->getNumArgs() == 2) {
3293 auto Op = CE->getOperator();
3296 case OO_GreaterEqual:
3299 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3300 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3301 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3302 CE->getOperatorLoc());
3303 if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3304 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3305 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3306 CE->getOperatorLoc());
3313 if (Dependent() || SemaRef.CurContext->isDependentContext())
3315 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3320 bool OpenMPIterationSpaceChecker::CheckIncRHS(
Expr *RHS) {
3327 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3328 if (BO->isAdditiveOp()) {
3329 bool IsAdd = BO->getOpcode() == BO_Add;
3330 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3331 return SetStep(BO->getRHS(), !IsAdd);
3332 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3333 return SetStep(BO->getLHS(),
false);
3335 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3336 bool IsAdd = CE->getOperator() == OO_Plus;
3337 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3338 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3339 return SetStep(CE->getArg(1), !IsAdd);
3340 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3341 return SetStep(CE->getArg(0),
false);
3344 if (Dependent() || SemaRef.CurContext->isDependentContext())
3346 SemaRef.Diag(RHS->
getLocStart(), diag::err_omp_loop_not_canonical_incr)
3351 bool OpenMPIterationSpaceChecker::CheckInc(
Expr *S) {
3366 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3369 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3370 if (!ExprTemp->cleanupsHaveSideEffects())
3371 S = ExprTemp->getSubExpr();
3375 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
3376 if (UO->isIncrementDecrementOp() &&
3377 GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3378 return SetStep(SemaRef
3380 (UO->isDecrementOp() ? -1 : 1))
3383 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
3384 switch (BO->getOpcode()) {
3387 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3388 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3391 if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3392 return CheckIncRHS(BO->getRHS());
3397 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3398 switch (CE->getOperator()) {
3401 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3402 return SetStep(SemaRef
3405 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3411 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3412 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3415 if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3416 return CheckIncRHS(CE->getArg(1));
3422 if (Dependent() || SemaRef.CurContext->isDependentContext())
3424 SemaRef.Diag(S->
getLocStart(), diag::err_omp_loop_not_canonical_incr)
3430 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
3431 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3438 auto I = Captures.find(Capture);
3439 if (I != Captures.end())
3443 Captures[Capture] = Ref;
3448 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3449 Scope *S,
const bool LimitedType,
3450 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
3452 auto VarType = LCDecl->getType().getNonReferenceType();
3453 if (VarType->isIntegerType() || VarType->isPointerType() ||
3456 auto *UBExpr = TestIsLessOp ? UB : LB;
3457 auto *LBExpr = TestIsLessOp ? LB : UB;
3458 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3459 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3460 if (!Upper || !Lower)
3463 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3465 if (!Diff.
isUsable() && VarType->getAsCXXRecordDecl()) {
3480 S, DefaultLoc, BO_Sub, Diff.
get(),
3486 auto NewStep = tryBuildCapture(SemaRef,
Step, Captures);
3487 if (!NewStep.isUsable())
3489 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.get());
3499 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.get());
3506 bool UseVarType = VarType->hasIntegerRepresentation() &&
3510 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3511 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3513 Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3522 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3523 if (NewSize != C.getTypeSize(Type)) {
3524 if (NewSize < C.getTypeSize(Type)) {
3525 assert(NewSize == 64 &&
"incorrect loop var size");
3526 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3527 << InitSrcRange << ConditionSrcRange;
3529 QualType NewType = C.getIntTypeForBitwidth(
3531 C.getTypeSize(Type) < NewSize);
3544 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
3546 llvm::MapVector<Expr *, DeclRefExpr *> &Captures)
const {
3551 auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
3552 auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
3553 if (!NewLB.isUsable() || !NewUB.isUsable())
3557 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
3558 : (TestIsStrictOp ? BO_GT : BO_GE),
3559 NewLB.get(), NewUB.get());
3560 if (CondExpr.isUsable()) {
3569 return CondExpr.isUsable() ? CondExpr.get() : Cond;
3573 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
3574 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA)
const {
3575 auto *VD = dyn_cast<
VarDecl>(LCDecl);
3580 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl,
false);
3584 Captures.insert(std::make_pair(LCRef, Ref));
3591 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar()
const {
3592 if (LCDecl && !LCDecl->isInvalidDecl()) {
3593 auto Type = LCDecl->getType().getNonReferenceType();
3595 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
3596 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr);
3597 if (PrivateVar->isInvalidDecl())
3608 Expr *OpenMPIterationSpaceChecker::BuildCounterStep()
const {
return Step; }
3611 struct LoopIterationSpace final {
3613 Expr *PreCond =
nullptr;
3616 Expr *NumIterations =
nullptr;
3618 Expr *CounterVar =
nullptr;
3620 Expr *PrivateCounterVar =
nullptr;
3622 Expr *CounterInit =
nullptr;
3625 Expr *CounterStep =
nullptr;
3627 bool Subtract =
false;
3639 assert(
getLangOpts().OpenMP &&
"OpenMP is not active.");
3640 assert(Init &&
"Expected loop in canonical form.");
3641 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
3642 if (AssociatedLoops > 0 &&
3644 OpenMPIterationSpaceChecker ISC(*
this, ForLoc);
3645 if (!ISC.CheckInit(Init,
false)) {
3646 if (
auto *D = ISC.GetLoopDecl()) {
3647 auto *VD = dyn_cast<
VarDecl>(D);
3652 auto *Ref =
buildCapture(*
this, D, ISC.GetLoopDeclRefExpr(),
3654 VD = cast<VarDecl>(Ref->getDecl());
3657 DSAStack->addLoopControlVariable(D, VD);
3660 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
3668 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
3669 Expr *CollapseLoopCountExpr,
Expr *OrderedLoopCountExpr,
3670 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
3671 LoopIterationSpace &ResultIterSpace,
3672 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3675 auto *For = dyn_cast_or_null<ForStmt>(
S);
3678 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
3680 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
3681 if (NestedLoopCount > 1) {
3682 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
3683 SemaRef.
Diag(DSA.getConstructLoc(),
3684 diag::note_omp_collapse_ordered_expr)
3687 else if (CollapseLoopCountExpr)
3689 diag::note_omp_collapse_ordered_expr)
3693 diag::note_omp_collapse_ordered_expr)
3698 assert(For->getBody());
3700 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
3703 auto Init = For->getInit();
3704 if (ISC.CheckInit(Init))
3707 bool HasErrors =
false;
3710 if (
auto *LCDecl = ISC.GetLoopDecl()) {
3711 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
3718 auto VarType = LCDecl->getType().getNonReferenceType();
3719 if (!VarType->isDependentType() && !VarType->isIntegerType() &&
3720 !VarType->isPointerType() &&
3721 !(SemaRef.
getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
3722 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
3736 VarsWithImplicitDSA.erase(LCDecl);
3746 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl,
false);
3749 auto PredeterminedCKind =
3751 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
3754 DVar.CKind != PredeterminedCKind) ||
3758 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
3759 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
3760 SemaRef.
Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
3763 if (DVar.RefExpr ==
nullptr)
3764 DVar.CKind = PredeterminedCKind;
3767 }
else if (LoopDeclRefExpr !=
nullptr) {
3776 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
3782 HasErrors |= ISC.CheckCond(For->getCond());
3785 HasErrors |= ISC.CheckInc(For->getInc());
3792 ResultIterSpace.PreCond =
3793 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
3794 ResultIterSpace.NumIterations = ISC.BuildNumIterations(
3799 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
3800 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
3801 ResultIterSpace.CounterInit = ISC.BuildCounterInit();
3802 ResultIterSpace.CounterStep = ISC.BuildCounterStep();
3803 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
3804 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
3805 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
3806 ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
3808 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
3809 ResultIterSpace.NumIterations ==
nullptr ||
3810 ResultIterSpace.CounterVar ==
nullptr ||
3811 ResultIterSpace.PrivateCounterVar ==
nullptr ||
3812 ResultIterSpace.CounterInit ==
nullptr ||
3813 ResultIterSpace.CounterStep ==
nullptr);
3822 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3824 auto NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
3825 if (!NewStart.isUsable())
3832 if (!NewStart.isUsable())
3837 SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), NewStart.get());
3846 llvm::MapVector<Expr *, DeclRefExpr *> *Captures =
nullptr) {
3855 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
3867 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
3883 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
3884 VarRef.
get(), SavedUpdate.
get());
3895 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
3896 NewStart.
get(), SavedUpdate.
get());
3908 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
3920 unsigned HasBits = C.getTypeSize(OldType);
3921 if (HasBits >= Bits)
3924 QualType NewType = C.getIntTypeForBitwidth(Bits,
true);
3936 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
3943 if (!PreInits.empty()) {
3953 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3954 if (!Captures.empty()) {
3956 for (
auto &Pair : Captures)
3957 PreInits.push_back(Pair.second->getDecl());
3965 Expr *PostUpdate =
nullptr;
3966 if (!PostUpdates.empty()) {
3967 for (
auto *E : PostUpdates) {
3973 PostUpdate = PostUpdate
3988 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
3990 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
3992 unsigned NestedLoopCount = 1;
3993 if (CollapseLoopCountExpr) {
3997 NestedLoopCount = Result.getLimitedValue();
3999 if (OrderedLoopCountExpr) {
4003 if (Result.getLimitedValue() < NestedLoopCount) {
4005 diag::err_omp_wrong_ordered_loop_count)
4008 diag::note_collapse_loop_count)
4011 NestedLoopCount = Result.getLimitedValue();
4016 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4018 IterSpaces.resize(NestedLoopCount);
4020 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4022 NestedLoopCount, CollapseLoopCountExpr,
4023 OrderedLoopCountExpr, VarsWithImplicitDSA,
4024 IterSpaces[Cnt], Captures))
4034 Built.
clear( NestedLoopCount);
4037 return NestedLoopCount;
4070 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
4071 auto N0 = IterSpaces[0].NumIterations;
4075 N0->IgnoreImpCasts(), N0->getType(),
4082 N0->IgnoreImpCasts(), N0->getType(),
4087 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
4088 return NestedLoopCount;
4091 bool AllCountsNeedLessThan32Bits = C.
getTypeSize(N0->getType()) < 32;
4093 Scope *CurScope = DSA.getCurScope();
4094 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4095 if (PreCond.isUsable()) {
4097 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4098 PreCond.get(), IterSpaces[Cnt].PreCond);
4100 auto N = IterSpaces[Cnt].NumIterations;
4102 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4105 CurScope, Loc, BO_Mul, LastIteration32.
get(),
4111 if (LastIteration64.isUsable())
4113 CurScope, Loc, BO_Mul, LastIteration64.get(),
4124 C.getTypeSize(LastIteration32.
get()->
getType()) == 32 &&
4125 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4129 LastIteration64.get(), SemaRef)))
4130 LastIteration = LastIteration32;
4149 LastIteration.
get(),
4163 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
4164 LastIteration = SaveRef;
4177 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4204 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
4213 UB.
get(), LastIteration.
get());
4215 InitLoc, InitLoc, IsUBGreater.
get(), LastIteration.
get(), UB.
get());
4216 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
4242 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
4245 LastIteration.
get(), CombUB.
get());
4246 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
4250 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4253 assert(CD->getNumParams() >= 4 &&
4254 "Unexpected number of parameters in loop combined directive");
4258 auto *PrevLBDecl = CD->getParam(2);
4259 auto *PrevUBDecl = CD->getParam(3);
4281 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), RHS);
4292 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.
get(), CombRHS);
4304 NumIterations.
get());
4317 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.
get(), Inc.
get());
4326 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4355 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
4366 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
4381 DistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LE, IV.
get(), UB.
get());
4382 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
4386 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
4387 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.
get(),
4390 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
4398 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
4399 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
4405 bool HasErrors =
false;
4406 Built.
Counters.resize(NestedLoopCount);
4407 Built.
Inits.resize(NestedLoopCount);
4408 Built.
Updates.resize(NestedLoopCount);
4409 Built.
Finals.resize(NestedLoopCount);
4414 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4415 LoopIterationSpace &IS = IterSpaces[Cnt];
4425 assert((Cnt == (
int)NestedLoopCount - 1) &&
4426 "unusable div expected on first iteration only");
4430 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.
get(),
4438 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4440 IS.CounterVar->getExprLoc(),
4443 IS.CounterInit, Captures);
4444 if (!Init.isUsable()) {
4449 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4450 IS.CounterStep, IS.Subtract, &Captures);
4458 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4459 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4468 Div = IS.NumIterations;
4470 Div = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.
get(),
4475 Div = tryBuildCapture(SemaRef, Div.
get(), Captures);
4480 LoopMultipliers.push_back(Div.
get());
4487 Built.
Counters[Cnt] = IS.CounterVar;
4489 Built.
Inits[Cnt] = Init.get();
4504 Built.
PreCond = PreCond.get();
4509 Built.
LB = LB.
get();
4510 Built.
UB = UB.
get();
4511 Built.
IL = IL.
get();
4512 Built.
ST = ST.
get();
4514 Built.
NLB = NextLB.
get();
4515 Built.
NUB = NextUB.
get();
4530 for (
auto Pair : DSA.getDoacrossDependClauses()) {
4531 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4532 Pair.first->setCounterValue(CounterVal);
4534 if (NestedLoopCount != Pair.second.size() ||
4535 NestedLoopCount != LoopMultipliers.size() + 1) {
4537 Pair.first->setCounterValue(CounterVal);
4540 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
4541 auto I = Pair.second.rbegin();
4542 auto IS = IterSpaces.rbegin();
4543 auto ILM = LoopMultipliers.rbegin();
4544 Expr *UpCounterVal = CounterVal;
4545 Expr *Multiplier =
nullptr;
4546 for (
int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4548 assert(IS->CounterStep);
4549 Expr *NormalizedOffset =
4551 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
4552 I->first, IS->CounterStep)
4557 .
BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
4558 NormalizedOffset, Multiplier)
4561 assert(I->second == OO_Plus || I->second == OO_Minus);
4563 UpCounterVal = SemaRef
4564 .
BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
4565 UpCounterVal, NormalizedOffset)
4573 Pair.first->setCounterValue(UpCounterVal);
4577 return NestedLoopCount;
4581 auto CollapseClauses =
4582 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
4583 if (CollapseClauses.begin() != CollapseClauses.end())
4584 return (*CollapseClauses.begin())->getNumForLoops();
4589 auto OrderedClauses =
4590 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
4591 if (OrderedClauses.begin() != OrderedClauses.end())
4592 return (*OrderedClauses.begin())->getNumForLoops();
4601 for (
auto *Clause : Clauses) {
4602 if (Clause->getClauseKind() == OMPC_safelen)
4603 Safelen = cast<OMPSafelenClause>(Clause);
4604 else if (Clause->getClauseKind() == OMPC_simdlen)
4605 Simdlen = cast<OMPSimdlenClause>(Clause);
4606 if (Safelen && Simdlen)
4610 if (Simdlen && Safelen) {
4611 llvm::APSInt SimdlenRes, SafelenRes;
4614 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
4615 SimdlenLength->isInstantiationDependent() ||
4616 SimdlenLength->containsUnexpandedParameterPack())
4618 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
4619 SafelenLength->isInstantiationDependent() ||
4620 SafelenLength->containsUnexpandedParameterPack())
4623 SafelenLength->EvaluateAsInt(SafelenRes, S.
Context);
4628 if (SimdlenRes > SafelenRes) {
4629 S.
Diag(SimdlenLength->getExprLoc(),
4630 diag::err_omp_wrong_simdlen_safelen_values)
4631 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
4641 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
4645 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4651 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
4652 if (NestedLoopCount == 0)
4656 "omp simd loop exprs were not built");
4660 for (
auto C : Clauses) {
4661 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
4680 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
4684 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4690 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
4691 if (NestedLoopCount == 0)
4695 "omp for loop exprs were not built");
4699 for (
auto C : Clauses) {
4700 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
4710 Clauses, AStmt, B,
DSAStack->isCancelRegion());
4716 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
4720 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4724 unsigned NestedLoopCount =
4727 VarsWithImplicitDSA, B);
4728 if (NestedLoopCount == 0)
4732 "omp for simd loop exprs were not built");
4736 for (
auto C : Clauses) {
4737 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
4760 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4761 auto BaseStmt = AStmt;
4762 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
4763 BaseStmt = CS->getCapturedStmt();
4764 if (
auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
4765 auto S = C->children();
4766 if (S.begin() == S.end())
4770 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
4771 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
4773 Diag(SectionStmt->getLocStart(),
4774 diag::err_omp_sections_substmt_not_section);
4777 cast<OMPSectionDirective>(SectionStmt)
4778 ->setHasCancel(
DSAStack->isCancelRegion());
4797 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4813 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4821 for (
auto *Clause : Clauses) {
4822 if (Clause->getClauseKind() == OMPC_nowait)
4824 else if (Clause->getClauseKind() == OMPC_copyprivate)
4825 Copyprivate = Clause;
4826 if (Copyprivate && Nowait) {
4828 diag::err_omp_single_copyprivate_with_nowait);
4843 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4856 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4858 bool ErrorFound =
false;
4861 bool DependentHint =
false;
4862 for (
auto *C : Clauses) {
4863 if (C->getClauseKind() == OMPC_hint) {
4865 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
4868 Expr *E = cast<OMPHintClause>(C)->getHint();
4871 DependentHint =
true;
4874 HintLoc = C->getLocStart();
4880 auto Pair =
DSAStack->getCriticalWithHint(DirName);
4881 if (Pair.first && DirName.
getName() && !DependentHint) {
4882 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
4883 Diag(StartLoc, diag::err_omp_critical_with_hint);
4885 Diag(HintLoc, diag::note_omp_critical_hint_here)
4886 << 0 << Hint.toString(10,
false);
4888 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
4889 if (
auto *C = Pair.first->getSingleClause<
OMPHintClause>()) {
4890 Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
4892 << C->getHint()->EvaluateKnownConstInt(
Context).toString(
4895 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
4903 if (!Pair.first && DirName.
getName() && !DependentHint)
4904 DSAStack->addCriticalWithHint(Dir, Hint);
4911 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
4926 unsigned NestedLoopCount =
4929 VarsWithImplicitDSA, B);
4930 if (NestedLoopCount == 0)
4934 "omp parallel for loop exprs were not built");
4938 for (
auto C : Clauses) {
4939 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
4949 NestedLoopCount, Clauses, AStmt, B,
4956 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
4971 unsigned NestedLoopCount =
4974 VarsWithImplicitDSA, B);
4975 if (NestedLoopCount == 0)
4980 for (
auto C : Clauses) {
4981 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
4994 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5004 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5005 auto BaseStmt = AStmt;
5006 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5007 BaseStmt = CS->getCapturedStmt();
5008 if (
auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5009 auto S = C->children();
5010 if (S.begin() == S.end())
5014 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5015 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5017 Diag(SectionStmt->getLocStart(),
5018 diag::err_omp_parallel_sections_substmt_not_section);
5021 cast<OMPSectionDirective>(SectionStmt)
5022 ->setHasCancel(
DSAStack->isCancelRegion());
5026 diag::err_omp_parallel_sections_not_compound_stmt);
5033 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
5042 auto *CS = cast<CapturedStmt>(AStmt);
5048 CS->getCapturedDecl()->setNothrow();
5078 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5089 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
5098 OMPClause *DependSourceClause =
nullptr;
5100 bool ErrorFound =
false;
5103 for (
auto *C : Clauses) {
5104 if (
auto *DC = dyn_cast<OMPDependClause>(C)) {
5106 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5107 if (DependSourceClause) {
5108 Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5113 DependSourceClause = C;
5114 if (DependSinkClause) {
5115 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5119 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5120 if (DependSourceClause) {
5121 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5125 DependSinkClause = C;
5127 }
else if (C->getClauseKind() == OMPC_threads)
5128 TC = cast<OMPThreadsClause>(C);
5129 else if (C->getClauseKind() == OMPC_simd)
5130 SC = cast<OMPSIMDClause>(C);
5132 if (!ErrorFound && !SC &&
5137 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5139 }
else if (DependFound && (TC || SC)) {
5140 Diag(DependFound->
getLocStart(), diag::err_omp_depend_clause_thread_simd)
5143 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam()) {
5145 diag::err_omp_ordered_directive_without_param);
5147 }
else if (TC || Clauses.empty()) {
5148 if (
auto *Param =
DSAStack->getParentOrderedRegionParam()) {
5150 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5156 if ((!AStmt && !DependFound) || ErrorFound)
5160 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5171 class OpenMPAtomicUpdateChecker {
5173 enum ExprAnalysisErrorCode {
5177 NotABinaryOrUnaryExpression,
5179 NotAnUnaryIncDecExpression,
5185 NotABinaryExpression,
5191 NotAnUpdateExpression,
5209 bool IsXLHSInRHSPart;
5214 bool IsPostfixUpdate;
5217 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
5218 : SemaRef(SemaRef),
X(nullptr), E(nullptr), UpdateExpr(nullptr),
5219 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
5227 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
5229 Expr *getX()
const {
return X; }
5231 Expr *getExpr()
const {
return E; }
5235 Expr *getUpdateExpr()
const {
return UpdateExpr; }
5238 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
5242 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
5245 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
5246 unsigned NoteId = 0);
5250 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5252 ExprAnalysisErrorCode ErrorFound = NoError;
5258 if (AtomicBinOp->
getOpcode() == BO_Assign) {
5260 if (
auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5262 if (AtomicInnerBinOp->isMultiplicativeOp() ||
5263 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5264 AtomicInnerBinOp->isBitwiseOp()) {
5265 Op = AtomicInnerBinOp->getOpcode();
5266 OpLoc = AtomicInnerBinOp->getOperatorLoc();
5267 auto *LHS = AtomicInnerBinOp->getLHS();
5268 auto *RHS = AtomicInnerBinOp->getRHS();
5269 llvm::FoldingSetNodeID XId, LHSId, RHSId;
5272 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.
getASTContext(),
5278 IsXLHSInRHSPart =
true;
5279 }
else if (XId == RHSId) {
5281 IsXLHSInRHSPart =
false;
5283 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5284 ErrorRange = AtomicInnerBinOp->getSourceRange();
5285 NoteLoc =
X->getExprLoc();
5286 NoteRange =
X->getSourceRange();
5287 ErrorFound = NotAnUpdateExpression;
5290 ErrorLoc = AtomicInnerBinOp->getExprLoc();
5291 ErrorRange = AtomicInnerBinOp->getSourceRange();
5292 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5294 ErrorFound = NotABinaryOperator;
5299 ErrorFound = NotABinaryExpression;
5306 ErrorFound = NotAnAssignmentOp;
5308 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5309 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
5310 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5313 E =
X = UpdateExpr =
nullptr;
5314 return ErrorFound != NoError;
5317 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
5319 ExprAnalysisErrorCode ErrorFound = NoError;
5330 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
5331 AtomicBody = AtomicBody->IgnoreParenImpCasts();
5332 if (AtomicBody->getType()->isScalarType() ||
5333 AtomicBody->isInstantiationDependent()) {
5334 if (
auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5335 AtomicBody->IgnoreParenImpCasts())) {
5338 AtomicCompAssignOp->getOpcode());
5339 OpLoc = AtomicCompAssignOp->getOperatorLoc();
5340 E = AtomicCompAssignOp->getRHS();
5341 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5342 IsXLHSInRHSPart =
true;
5343 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5344 AtomicBody->IgnoreParenImpCasts())) {
5346 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5348 }
else if (
auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5349 AtomicBody->IgnoreParenImpCasts())) {
5351 if (AtomicUnaryOp->isIncrementDecrementOp()) {
5352 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5353 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5354 OpLoc = AtomicUnaryOp->getOperatorLoc();
5355 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5357 IsXLHSInRHSPart =
true;
5359 ErrorFound = NotAnUnaryIncDecExpression;
5360 ErrorLoc = AtomicUnaryOp->getExprLoc();
5361 ErrorRange = AtomicUnaryOp->getSourceRange();
5362 NoteLoc = AtomicUnaryOp->getOperatorLoc();
5365 }
else if (!AtomicBody->isInstantiationDependent()) {
5366 ErrorFound = NotABinaryOrUnaryExpression;
5367 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5368 NoteRange = ErrorRange = AtomicBody->getSourceRange();
5371 ErrorFound = NotAScalarType;
5372 NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5373 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5376 ErrorFound = NotAnExpression;
5378 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5380 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5381 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
5382 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5385 E =
X = UpdateExpr =
nullptr;
5386 if (ErrorFound == NoError && E &&
X) {
5396 IsXLHSInRHSPart ? OVEExpr : OVEX);
5397 if (Update.isInvalid())
5401 if (Update.isInvalid())
5403 UpdateExpr = Update.
get();
5405 return ErrorFound != NoError;
5415 auto *CS = cast<CapturedStmt>(AStmt);
5423 for (
auto *C : Clauses) {
5424 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5425 C->getClauseKind() == OMPC_update ||
5426 C->getClauseKind() == OMPC_capture) {
5428 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5430 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5433 AtomicKind = C->getClauseKind();
5434 AtomicKindLoc = C->getLocStart();
5439 auto Body = CS->getCapturedStmt();
5440 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5441 Body = EWC->getSubExpr();
5447 bool IsXLHSInRHSPart =
false;
5448 bool IsPostfixUpdate =
false;
5471 if (AtomicKind == OMPC_read) {
5478 } ErrorFound = NoError;
5483 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
5486 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
5492 auto NotLValueExpr = X->
isLValue() ? V :
X;
5493 ErrorFound = NotAnLValue;
5496 NoteLoc = NotLValueExpr->getExprLoc();
5497 NoteRange = NotLValueExpr->getSourceRange();
5501 auto NotScalarExpr =
5505 ErrorFound = NotAScalarType;
5508 NoteLoc = NotScalarExpr->getExprLoc();
5509 NoteRange = NotScalarExpr->getSourceRange();
5511 }
else if (!AtomicBody->isInstantiationDependent()) {
5512 ErrorFound = NotAnAssignmentOp;
5513 ErrorLoc = AtomicBody->getExprLoc();
5514 ErrorRange = AtomicBody->getSourceRange();
5516 : AtomicBody->getExprLoc();
5518 : AtomicBody->getSourceRange();
5521 ErrorFound = NotAnExpression;
5522 NoteLoc = ErrorLoc = Body->getLocStart();
5523 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5525 if (ErrorFound != NoError) {
5526 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5528 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5533 }
else if (AtomicKind == OMPC_write) {
5540 } ErrorFound = NoError;
5545 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
5548 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
5549 X = AtomicBinOp->
getLHS();
5550 E = AtomicBinOp->
getRHS();
5554 ErrorFound = NotAnLValue;
5562 auto NotScalarExpr =
5566 ErrorFound = NotAScalarType;
5569 NoteLoc = NotScalarExpr->getExprLoc();
5570 NoteRange = NotScalarExpr->getSourceRange();
5572 }
else if (!AtomicBody->isInstantiationDependent()) {
5573 ErrorFound = NotAnAssignmentOp;
5574 ErrorLoc = AtomicBody->getExprLoc();
5575 ErrorRange = AtomicBody->getSourceRange();
5577 : AtomicBody->getExprLoc();
5579 : AtomicBody->getSourceRange();
5582 ErrorFound = NotAnExpression;
5583 NoteLoc = ErrorLoc = Body->getLocStart();
5584 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
5586 if (ErrorFound != NoError) {
5587 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
5589 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5594 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
5603 OpenMPAtomicUpdateChecker Checker(*
this);
5604 if (Checker.checkStatement(
5605 Body, (AtomicKind == OMPC_update)
5606 ? diag::err_omp_atomic_update_not_expression_statement
5607 : diag::err_omp_atomic_not_expression_statement,
5608 diag::note_omp_atomic_update))
5611 E = Checker.getExpr();
5613 UE = Checker.getUpdateExpr();
5614 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5616 }
else if (AtomicKind == OMPC_capture) {
5619 NotACompoundStatement,
5620 NotTwoSubstatements,
5621 NotASpecificExpression,
5623 } ErrorFound = NoError;
5626 if (
auto *AtomicBody = dyn_cast<Expr>(Body)) {
5637 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
5638 V = AtomicBinOp->
getLHS();
5640 OpenMPAtomicUpdateChecker Checker(*
this);
5641 if (Checker.checkStatement(
5642 Body, diag::err_omp_atomic_capture_not_expression_statement,
5643 diag::note_omp_atomic_update))
5645 E = Checker.getExpr();
5647 UE = Checker.getUpdateExpr();
5648 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5649 IsPostfixUpdate = Checker.isPostfixUpdate();
5650 }
else if (!AtomicBody->isInstantiationDependent()) {
5651 ErrorLoc = AtomicBody->getExprLoc();
5652 ErrorRange = AtomicBody->getSourceRange();
5654 : AtomicBody->getExprLoc();
5656 : AtomicBody->getSourceRange();
5657 ErrorFound = NotAnAssignmentOp;
5659 if (ErrorFound != NoError) {
5660 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
5662 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5665 UE = V = E = X =
nullptr;
5684 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
5686 if (CS->size() == 2) {
5687 auto *First = CS->body_front();
5688 auto *Second = CS->body_back();
5689 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
5691 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
5694 OpenMPAtomicUpdateChecker Checker(*
this);
5695 bool IsUpdateExprFound = !Checker.checkStatement(Second);
5697 if (IsUpdateExprFound) {
5699 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
5711 llvm::FoldingSetNodeID XId, PossibleXId;
5712 Checker.getX()->Profile(XId,
Context,
true);
5713 PossibleX->Profile(PossibleXId,
Context,
true);
5714 IsUpdateExprFound = XId == PossibleXId;
5715 if (IsUpdateExprFound) {
5718 E = Checker.getExpr();
5719 UE = Checker.getUpdateExpr();
5720 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5721 IsPostfixUpdate =
true;
5724 if (!IsUpdateExprFound) {
5725 IsUpdateExprFound = !Checker.checkStatement(First);
5727 if (IsUpdateExprFound) {
5729 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
5741 llvm::FoldingSetNodeID XId, PossibleXId;
5742 Checker.getX()->Profile(XId,
Context,
true);
5743 PossibleX->Profile(PossibleXId,
Context,
true);
5744 IsUpdateExprFound = XId == PossibleXId;
5745 if (IsUpdateExprFound) {
5748 E = Checker.getExpr();
5749 UE = Checker.getUpdateExpr();
5750 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
5751 IsPostfixUpdate =
false;
5755 if (!IsUpdateExprFound) {
5757 auto *FirstExpr = dyn_cast<
Expr>(First);
5758 auto *SecondExpr = dyn_cast<
Expr>(Second);
5759 if (!FirstExpr || !SecondExpr ||
5760 !(FirstExpr->isInstantiationDependent() ||
5761 SecondExpr->isInstantiationDependent())) {
5763 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
5764 ErrorFound = NotAnAssignmentOp;
5765 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
5766 : First->getLocStart();
5767 NoteRange = ErrorRange = FirstBinOp
5768 ? FirstBinOp->getSourceRange()
5772 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
5773 ErrorFound = NotAnAssignmentOp;
5774 NoteLoc = ErrorLoc = SecondBinOp
5775 ? SecondBinOp->getOperatorLoc()
5776 : Second->getLocStart();
5777 NoteRange = ErrorRange =
5778 SecondBinOp ? SecondBinOp->getSourceRange()
5781 auto *PossibleXRHSInFirst =
5782 FirstBinOp->getRHS()->IgnoreParenImpCasts();
5783 auto *PossibleXLHSInSecond =
5784 SecondBinOp->getLHS()->IgnoreParenImpCasts();
5785 llvm::FoldingSetNodeID X1Id, X2Id;
5786 PossibleXRHSInFirst->Profile(X1Id,
Context,
5788 PossibleXLHSInSecond->Profile(X2Id,
Context,
5790 IsUpdateExprFound = X1Id == X2Id;
5791 if (IsUpdateExprFound) {
5792 V = FirstBinOp->getLHS();
5793 X = SecondBinOp->getLHS();
5794 E = SecondBinOp->getRHS();
5796 IsXLHSInRHSPart =
false;
5797 IsPostfixUpdate =
true;
5799 ErrorFound = NotASpecificExpression;
5800 ErrorLoc = FirstBinOp->getExprLoc();
5801 ErrorRange = FirstBinOp->getSourceRange();
5802 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
5803 NoteRange = SecondBinOp->getRHS()->getSourceRange();
5810 NoteLoc = ErrorLoc = Body->getLocStart();
5811 NoteRange = ErrorRange =
5812 SourceRange(Body->getLocStart(), Body->getLocStart());
5813 ErrorFound = NotTwoSubstatements;
5816 NoteLoc = ErrorLoc = Body->getLocStart();
5817 NoteRange = ErrorRange =
5818 SourceRange(Body->getLocStart(), Body->getLocStart());
5819 ErrorFound = NotACompoundStatement;
5821 if (ErrorFound != NoError) {
5822 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
5824 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
5827 UE = V = E = X =
nullptr;
5835 X, V, E, UE, IsXLHSInRHSPart,
5858 if (
DSAStack->hasInnerTeamsRegion()) {
5860 bool OMPTeamsFound =
true;
5861 if (
auto *CS = dyn_cast<CompoundStmt>(S)) {
5862 auto I = CS->body_begin();
5863 while (I != CS->body_end()) {
5866 OMPTeamsFound =
false;
5871 assert(I != CS->body_end() &&
"Not found statement");
5877 if (!OMPTeamsFound) {
5878 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
5880 diag::note_omp_nested_teams_construct_here);
5882 << isa<OMPExecutableDirective>(S);
5916 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5931 unsigned NestedLoopCount =
5934 VarsWithImplicitDSA, B);
5935 if (NestedLoopCount == 0)
5939 "omp target parallel for loop exprs were not built");
5943 for (
auto C : Clauses) {
5944 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
5954 NestedLoopCount, Clauses, AStmt,
5961 return llvm::any_of(
5965 template <
typename... Params>
5967 const Params... ClauseTypes) {
5978 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
5982 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
5983 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
5984 <<
"'map' or 'use_device_ptr'"
6002 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6018 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6029 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
6030 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6059 if (
DSAStack->isParentNowaitRegion()) {
6060 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6063 if (
DSAStack->isParentOrderedRegion()) {
6064 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6075 if (
DSAStack->isParentNowaitRegion()) {
6076 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6079 if (
DSAStack->isParentOrderedRegion()) {
6080 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6083 DSAStack->setParentCancelRegion(
true);
6091 bool ErrorFound =
false;
6092 for (
auto *C : Clauses) {
6093 if (C->getClauseKind() == OMPC_grainsize ||
6094 C->getClauseKind() == OMPC_num_tasks) {
6097 else if (PrevClause->
getClauseKind() != C->getClauseKind()) {
6098 S.
Diag(C->getLocStart(),
6099 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6103 diag::note_omp_previous_grainsize_num_tasks)
6116 for (
auto *C : Clauses) {
6117 if (C->getClauseKind() == OMPC_reduction) {
6118 ReductionClause = C;
6123 if (C->getClauseKind() == OMPC_nogroup) {
6125 if (ReductionClause)
6130 if (ReductionClause && NogroupClause) {
6131 S.
Diag(ReductionClause->
getLocStart(), diag::err_omp_reduction_with_nogroup)
6142 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6146 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6150 unsigned NestedLoopCount =
6153 VarsWithImplicitDSA, B);
6154 if (NestedLoopCount == 0)
6158 "omp for loop exprs were not built");
6173 NestedLoopCount, Clauses, AStmt, B);
6179 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6183 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6187 unsigned NestedLoopCount =
6190 VarsWithImplicitDSA, B);
6191 if (NestedLoopCount == 0)
6195 "omp for loop exprs were not built");
6199 for (
auto C : Clauses) {
6200 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6221 NestedLoopCount, Clauses, AStmt, B);
6227 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6231 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6235 unsigned NestedLoopCount =
6238 *
this, *
DSAStack, VarsWithImplicitDSA, B);
6239 if (NestedLoopCount == 0)
6243 "omp for loop exprs were not built");
6247 NestedLoopCount, Clauses, AStmt, B);
6253 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6271 VarsWithImplicitDSA, B);
6272 if (NestedLoopCount == 0)
6276 "omp for loop exprs were not built");
6280 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6286 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6304 VarsWithImplicitDSA, B);
6305 if (NestedLoopCount == 0)
6309 "omp for loop exprs were not built");
6316 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6322 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6337 unsigned NestedLoopCount =
6340 *
this, *
DSAStack, VarsWithImplicitDSA, B);
6341 if (NestedLoopCount == 0)
6345 "omp for loop exprs were not built");
6352 NestedLoopCount, Clauses, AStmt, B);
6358 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6376 VarsWithImplicitDSA, B);
6377 if (NestedLoopCount == 0)
6381 "omp target parallel for simd loop exprs were not built");
6385 for (
auto C : Clauses) {
6386 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6398 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6404 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6419 unsigned NestedLoopCount =
6422 VarsWithImplicitDSA, B);
6423 if (NestedLoopCount == 0)
6427 "omp target simd loop exprs were not built");
6431 for (
auto C : Clauses) {
6432 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6445 NestedLoopCount, Clauses, AStmt, B);
6451 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6466 unsigned NestedLoopCount =
6469 *
this, *
DSAStack, VarsWithImplicitDSA, B);
6470 if (NestedLoopCount == 0)
6474 "omp teams distribute loop exprs were not built");
6478 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6484 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6502 VarsWithImplicitDSA, B);
6504 if (NestedLoopCount == 0)
6508 "omp teams distribute simd loop exprs were not built");
6512 for (
auto C : Clauses) {
6513 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6526 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6532 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6550 VarsWithImplicitDSA, B);
6552 if (NestedLoopCount == 0)
6556 "omp for loop exprs were not built");
6560 for (
auto C : Clauses) {
6561 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6574 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6580 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6598 VarsWithImplicitDSA, B);
6600 if (NestedLoopCount == 0)
6604 "omp for loop exprs were not built");
6608 for (
auto C : Clauses) {
6609 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6619 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6646 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6662 OMPD_target_teams_distribute,
6665 VarsWithImplicitDSA, B);
6666 if (NestedLoopCount == 0)
6670 "omp target teams distribute loop exprs were not built");
6674 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6680 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6696 OMPD_target_teams_distribute_parallel_for,
6699 VarsWithImplicitDSA, B);
6700 if (NestedLoopCount == 0)
6704 "omp target teams distribute parallel for loop exprs were not built");
6708 for (
auto C : Clauses) {
6709 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6719 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6725 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6741 OMPD_target_teams_distribute_parallel_for_simd,
6744 VarsWithImplicitDSA, B);
6745 if (NestedLoopCount == 0)
6749 "omp target teams distribute parallel for simd loop exprs were not "
6754 for (
auto C : Clauses) {
6755 if (
auto *LC = dyn_cast<OMPLinearClause>(C))
6765 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6771 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6775 auto *CS = cast<CapturedStmt>(AStmt);
6781 CS->getCapturedDecl()->setNothrow();
6789 VarsWithImplicitDSA, B);
6790 if (NestedLoopCount == 0)
6794 "omp target teams distribute simd loop exprs were not built");
6798 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6810 case OMPC_num_threads:
6828 case OMPC_num_teams:
6831 case OMPC_thread_limit:
6837 case OMPC_grainsize:
6840 case OMPC_num_tasks:
6848 case OMPC_proc_bind:
6851 case OMPC_firstprivate:
6852 case OMPC_lastprivate:
6854 case OMPC_reduction:
6855 case OMPC_task_reduction:
6859 case OMPC_copyprivate:
6862 case OMPC_mergeable:
6875 case OMPC_dist_schedule:
6876 case OMPC_defaultmap:
6881 case OMPC_use_device_ptr:
6882 case OMPC_is_device_ptr:
6883 llvm_unreachable(
"Clause is not allowed.");
6901 case OMPD_target_parallel:
6904 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
6905 CaptureRegion = OMPD_target;
6909 case OMPD_parallel_sections:
6910 case OMPD_parallel_for:
6911 case OMPD_parallel_for_simd:
6913 case OMPD_target_simd:
6914 case OMPD_target_parallel_for:
6915 case OMPD_target_parallel_for_simd:
6916 case OMPD_target_teams:
6917 case OMPD_target_teams_distribute:
6918 case OMPD_target_teams_distribute_simd:
6919 case OMPD_target_teams_distribute_parallel_for:
6920 case OMPD_target_teams_distribute_parallel_for_simd:
6921 case OMPD_teams_distribute_parallel_for:
6922 case OMPD_teams_distribute_parallel_for_simd:
6923 case OMPD_distribute_parallel_for:
6924 case OMPD_distribute_parallel_for_simd:
6927 case OMPD_taskloop_simd:
6928 case OMPD_target_data:
6929 case OMPD_target_enter_data:
6930 case OMPD_target_exit_data:
6931 case OMPD_target_update:
6934 case OMPD_threadprivate:
6935 case OMPD_taskyield:
6938 case OMPD_cancellation_point:
6940 case OMPD_declare_reduction:
6941 case OMPD_declare_simd:
6942 case OMPD_declare_target:
6943 case OMPD_end_declare_target:
6953 case OMPD_taskgroup:
6954 case OMPD_distribute:
6957 case OMPD_distribute_simd:
6958 case OMPD_teams_distribute:
6959 case OMPD_teams_distribute_simd:
6960 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
6962 llvm_unreachable(
"Unknown OpenMP directive");
6965 case OMPC_num_threads:
6967 case OMPD_target_parallel:
6968 CaptureRegion = OMPD_target;
6972 case OMPD_parallel_sections:
6973 case OMPD_parallel_for:
6974 case OMPD_parallel_for_simd:
6976 case OMPD_target_simd:
6977 case OMPD_target_parallel_for:
6978 case OMPD_target_parallel_for_simd:
6979 case OMPD_target_teams:
6980 case OMPD_target_teams_distribute:
6981 case OMPD_target_teams_distribute_simd:
6982 case OMPD_target_teams_distribute_parallel_for:
6983 case OMPD_target_teams_distribute_parallel_for_simd:
6984 case OMPD_teams_distribute_parallel_for:
6985 case OMPD_teams_distribute_parallel_for_simd:
6986 case OMPD_distribute_parallel_for:
6987 case OMPD_distribute_parallel_for_simd:
6990 case OMPD_taskloop_simd:
6991 case OMPD_target_data:
6992 case OMPD_target_enter_data:
6993 case OMPD_target_exit_data:
6994 case OMPD_target_update:
6997 case OMPD_threadprivate:
6998 case OMPD_taskyield:
7001 case OMPD_cancellation_point:
7003 case OMPD_declare_reduction:
7004 case OMPD_declare_simd:
7005 case OMPD_declare_target:
7006 case OMPD_end_declare_target:
7016 case OMPD_taskgroup:
7017 case OMPD_distribute:
7020 case OMPD_distribute_simd:
7021 case OMPD_teams_distribute:
7022 case OMPD_teams_distribute_simd:
7023 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
7025 llvm_unreachable(
"Unknown OpenMP directive");
7028 case OMPC_num_teams:
7030 case OMPD_target_teams:
7031 CaptureRegion = OMPD_target;
7035 case OMPD_parallel_sections:
7036 case OMPD_parallel_for:
7037 case OMPD_parallel_for_simd:
7039 case OMPD_target_simd:
7040 case OMPD_target_parallel:
7041 case OMPD_target_parallel_for:
7042 case OMPD_target_parallel_for_simd:
7043 case OMPD_target_teams_distribute:
7044 case OMPD_target_teams_distribute_simd:
7045 case OMPD_target_teams_distribute_parallel_for:
7046 case OMPD_target_teams_distribute_parallel_for_simd:
7047 case OMPD_teams_distribute_parallel_for:
7048 case OMPD_teams_distribute_parallel_for_simd:
7049 case OMPD_distribute_parallel_for:
7050 case OMPD_distribute_parallel_for_simd:
7053 case OMPD_taskloop_simd:
7054 case OMPD_target_data:
7055 case OMPD_target_enter_data:
7056 case OMPD_target_exit_data:
7057 case OMPD_target_update:
7059 case OMPD_teams_distribute:
7060 case OMPD_teams_distribute_simd:
7063 case OMPD_threadprivate:
7064 case OMPD_taskyield:
7067 case OMPD_cancellation_point:
7069 case OMPD_declare_reduction:
7070 case OMPD_declare_simd:
7071 case OMPD_declare_target:
7072 case OMPD_end_declare_target:
7081 case OMPD_taskgroup:
7082 case OMPD_distribute:
7085 case OMPD_distribute_simd:
7086 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
7088 llvm_unreachable(
"Unknown OpenMP directive");
7091 case OMPC_thread_limit:
7093 case OMPD_target_teams:
7094 CaptureRegion = OMPD_target;
7098 case OMPD_parallel_sections:
7099 case OMPD_parallel_for:
7100 case OMPD_parallel_for_simd:
7102 case OMPD_target_simd:
7103 case OMPD_target_parallel:
7104 case OMPD_target_parallel_for:
7105 case OMPD_target_parallel_for_simd:
7106 case OMPD_target_teams_distribute:
7107 case OMPD_target_teams_distribute_simd:
7108 case OMPD_target_teams_distribute_parallel_for:
7109 case OMPD_target_teams_distribute_parallel_for_simd:
7110 case OMPD_teams_distribute_parallel_for:
7111 case OMPD_teams_distribute_parallel_for_simd:
7112 case OMPD_distribute_parallel_for:
7113 case OMPD_distribute_parallel_for_simd:
7116 case OMPD_taskloop_simd:
7117 case OMPD_target_data:
7118 case OMPD_target_enter_data:
7119 case OMPD_target_exit_data:
7120 case OMPD_target_update:
7122 case OMPD_teams_distribute:
7123 case OMPD_teams_distribute_simd:
7126 case OMPD_threadprivate:
7127 case OMPD_taskyield:
7130 case OMPD_cancellation_point:
7132 case OMPD_declare_reduction:
7133 case OMPD_declare_simd:
7134 case OMPD_declare_target:
7135 case OMPD_end_declare_target:
7144 case OMPD_taskgroup:
7145 case OMPD_distribute:
7148 case OMPD_distribute_simd:
7149 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
7151 llvm_unreachable(
"Unknown OpenMP directive");
7155 case OMPC_dist_schedule:
7156 case OMPC_firstprivate:
7157 case OMPC_lastprivate:
7158 case OMPC_reduction:
7159 case OMPC_task_reduction:
7162 case OMPC_proc_bind:
7171 case OMPC_copyprivate:
7175 case OMPC_mergeable:
7189 case OMPC_grainsize:
7191 case OMPC_num_tasks:
7193 case OMPC_defaultmap:
7198 case OMPC_use_device_ptr:
7199 case OMPC_is_device_ptr:
7200 llvm_unreachable(
"Unexpected OpenMP clause.");
7202 return CaptureRegion;
7211 Expr *ValExpr = Condition;
7212 Stmt *HelperValStmt =
nullptr;
7227 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
7228 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
7234 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
7235 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
7242 Expr *ValExpr = Condition;
7262 IntConvertDiagnoser()
7266 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
7270 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
7275 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
7284 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
7293 llvm_unreachable(
"conversion functions are permitted");
7301 bool StrictlyPositive) {
7310 ValExpr = Value.
get();
7314 Result.isSigned() &&
7315 !((!StrictlyPositive && Result.isNonNegative()) ||
7316 (StrictlyPositive && Result.isStrictlyPositive()))) {
7317 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
7330 Expr *ValExpr = NumThreads;
7331 Stmt *HelperValStmt =
nullptr;
7343 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
7344 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
7349 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
7354 bool StrictlyPositive) {
7364 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
7365 (!StrictlyPositive && !Result.isNonNegative())) {
7366 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
7371 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
7376 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
7377 DSAStack->setAssociatedLoops(Result.getExtValue());
7378 else if (CKind == OMPC_ordered)
7379 DSAStack->setAssociatedLoops(Result.getExtValue());
7389 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
7402 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
7419 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
7429 Expr *NumForLoops) {
7435 if (NumForLoops && LParenLoc.
isValid()) {
7437 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
7440 NumForLoops = NumForLoopsResult.
get();
7442 NumForLoops =
nullptr;
7443 DSAStack->setOrderedRegion(
true, NumForLoops);
7456 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
7458 case OMPC_proc_bind:
7460 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
7465 case OMPC_num_threads:
7471 case OMPC_firstprivate:
7472 case OMPC_lastprivate:
7474 case OMPC_reduction:
7475 case OMPC_task_reduction:
7479 case OMPC_copyprivate:
7483 case OMPC_mergeable:
7496 case OMPC_num_teams:
7497 case OMPC_thread_limit:
7499 case OMPC_grainsize:
7501 case OMPC_num_tasks:
7503 case OMPC_dist_schedule:
7504 case OMPC_defaultmap:
7509 case OMPC_use_device_ptr:
7510 case OMPC_is_device_ptr:
7511 llvm_unreachable(
"Clause is not allowed.");
7520 unsigned Bound = Last >= 2 ? Last - 2 : 0;
7521 unsigned Skipped = Exclude.size();
7522 auto S = Exclude.begin(), E = Exclude.end();
7523 for (
unsigned i = First; i < Last; ++i) {
7524 if (std::find(S, E, i) != E) {
7531 if (i == Bound - Skipped)
7533 else if (i != Bound + 1 - Skipped)
7546 "OMPC_DEFAULT_unknown not greater than 0");
7547 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7554 case OMPC_DEFAULT_none:
7555 DSAStack->setDefaultDSANone(KindKwLoc);
7557 case OMPC_DEFAULT_shared:
7558 DSAStack->setDefaultDSAShared(KindKwLoc);
7561 llvm_unreachable(
"Clause kind is not allowed.");
7574 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
7592 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
7593 assert(Argument.size() == NumberOfElements &&
7594 ArgumentLoc.size() == NumberOfElements);
7596 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
7597 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
7598 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
7599 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
7600 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
7603 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
7605 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
7608 case OMPC_dist_schedule:
7610 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
7611 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
7613 case OMPC_defaultmap:
7616 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
7617 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
7618 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
7622 case OMPC_num_threads:
7627 case OMPC_proc_bind:
7629 case OMPC_firstprivate:
7630 case OMPC_lastprivate:
7632 case OMPC_reduction:
7633 case OMPC_task_reduction:
7637 case OMPC_copyprivate:
7641 case OMPC_mergeable:
7654 case OMPC_num_teams:
7655 case OMPC_thread_limit:
7657 case OMPC_grainsize:
7659 case OMPC_num_tasks:
7665 case OMPC_use_device_ptr:
7666 case OMPC_is_device_ptr:
7667 llvm_unreachable(
"Clause is not allowed.");
7678 Excluded.push_back(M2);
7679 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
7680 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
7681 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
7682 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
7683 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
7706 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
7707 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
7708 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
7709 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
7710 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
7726 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
7733 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
7734 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
7735 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
7736 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
7737 diag::err_omp_schedule_nonmonotonic_static);
7740 Expr *ValExpr = ChunkSize;
7741 Stmt *HelperValStmt =
nullptr;
7752 ValExpr = Val.
get();
7759 if (Result.isSigned() && !Result.isStrictlyPositive()) {
7760 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
7764 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
7766 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
7767 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
7775 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
7792 case OMPC_mergeable:
7821 case OMPC_num_threads:
7827 case OMPC_firstprivate:
7828 case OMPC_lastprivate:
7830 case OMPC_reduction:
7831 case OMPC_task_reduction:
7835 case OMPC_copyprivate:
7837 case OMPC_proc_bind:
7843 case OMPC_num_teams:
7844 case OMPC_thread_limit:
7846 case OMPC_grainsize:
7847 case OMPC_num_tasks:
7849 case OMPC_dist_schedule:
7850 case OMPC_defaultmap:
7855 case OMPC_use_device_ptr:
7856 case OMPC_is_device_ptr:
7857 llvm_unreachable(
"Clause is not allowed.");
7931 case OMPC_firstprivate:
7934 case OMPC_lastprivate:
7940 case OMPC_reduction:
7942 EndLoc, ReductionIdScopeSpec, ReductionId);
7944 case OMPC_task_reduction:
7946 EndLoc, ReductionIdScopeSpec,
7951 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
7960 case OMPC_copyprivate:
7968 StartLoc, LParenLoc, EndLoc);
7972 DepLinMapLoc, ColonLoc, VarList, StartLoc,
7981 case OMPC_use_device_ptr:
7984 case OMPC_is_device_ptr:
7989 case OMPC_num_threads:
7994 case OMPC_proc_bind:
7999 case OMPC_mergeable:
8009 case OMPC_num_teams:
8010 case OMPC_thread_limit:
8012 case OMPC_grainsize:
8014 case OMPC_num_tasks:
8016 case OMPC_dist_schedule:
8017 case OMPC_defaultmap:
8020 llvm_unreachable(
"Clause is not allowed.");
8044 static std::pair<ValueDecl *, bool>
8046 SourceRange &ERange,
bool AllowArraySection =
false) {
8049 return std::make_pair(
nullptr,
true);
8061 } IsArrayExpr = NoArrayExpr;
8062 if (AllowArraySection) {
8063 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8064 auto *
Base = ASE->getBase()->IgnoreParenImpCasts();
8065 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8066 Base = TempASE->getBase()->IgnoreParenImpCasts();
8068 IsArrayExpr = ArraySubscript;
8069 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8070 auto *
Base = OASE->getBase()->IgnoreParenImpCasts();
8071 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(
Base))
8072 Base = TempOASE->getBase()->IgnoreParenImpCasts();
8073 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(
Base))
8074 Base = TempASE->getBase()->IgnoreParenImpCasts();
8076 IsArrayExpr = OMPArraySection;
8082 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
8083 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
8084 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
8086 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
8087 !isa<FieldDecl>(ME->getMemberDecl()))) {
8088 if (IsArrayExpr != NoArrayExpr)
8089 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
8094 ? diag::err_omp_expected_var_name_member_expr_or_array_item
8095 : diag::err_omp_expected_var_name_member_expr)
8098 return std::make_pair(
nullptr,
false);
8100 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(),
false);
8109 for (
auto &RefExpr : VarList) {
8110 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
8113 Expr *SimpleRefExpr = RefExpr;
8117 Vars.push_back(RefExpr);
8118 PrivateCopies.push_back(
nullptr);
8125 auto *VD = dyn_cast<
VarDecl>(D);
8141 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8142 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
8149 auto CurrDir =
DSAStack->getCurrentDirective();
8153 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8160 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8168 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
8169 CurrDir == OMPD_target_teams ||
8170 CurrDir == OMPD_target_teams_distribute ||
8171 CurrDir == OMPD_target_teams_distribute_parallel_for ||
8172 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
8173 CurrDir == OMPD_target_teams_distribute_simd ||
8174 CurrDir == OMPD_target_parallel_for_simd ||
8175 CurrDir == OMPD_target_parallel_for) {
8177 if (
DSAStack->checkMappableExprComponentListsForDecl(
8181 ConflictKind = WhereFoundClauseKind;
8184 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
8206 if (VDPrivate->isInvalidDecl())
8209 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
8214 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
8216 ? RefExpr->IgnoreParens()
8218 PrivateCopies.push_back(VDPrivateRefExpr);
8229 class DiagsUninitializedSeveretyRAII {
8238 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
8240 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
8244 ~DiagsUninitializedSeveretyRAII() {
8259 bool IsImplicitClause =
8261 auto ImplicitClauseLoc =
DSAStack->getConstructLoc();
8263 for (
auto &RefExpr : VarList) {
8264 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
8267 Expr *SimpleRefExpr = RefExpr;
8271 Vars.push_back(RefExpr);
8272 PrivateCopies.push_back(
nullptr);
8273 Inits.push_back(
nullptr);
8279 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
8281 auto *VD = dyn_cast<
VarDecl>(D);
8287 diag::err_omp_firstprivate_incomplete_type))
8298 DSAStackTy::DSAVarData TopDVar;
8299 if (!IsImplicitClause) {
8300 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8302 bool IsConstant = ElemType.isConstant(
Context);
8307 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
8308 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
8309 Diag(ELoc, diag::err_omp_wrong_dsa)
8327 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
8328 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
8329 Diag(ELoc, diag::err_omp_wrong_dsa)
8345 DVar =
DSAStack->getImplicitDSA(D,
true);
8346 if (DVar.CKind != OMPC_shared &&
8349 Diag(ELoc, diag::err_omp_required_access)
8375 if (DVar.CKind == OMPC_reduction &&
8378 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
8398 if (CurrDir == OMPD_distribute) {
8406 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams);
8416 if (DVar.CKind == OMPC_reduction &&
8418 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction);
8422 DVar =
DSAStack->getTopDSA(D,
false);
8423 if (DVar.CKind == OMPC_lastprivate) {
8424 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8432 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
8433 CurrDir == OMPD_target_teams ||
8434 CurrDir == OMPD_target_teams_distribute ||
8435 CurrDir == OMPD_target_teams_distribute_parallel_for ||
8436 CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
8437 CurrDir == OMPD_target_teams_distribute_simd ||
8438 CurrDir == OMPD_target_parallel_for_simd ||
8439 CurrDir == OMPD_target_parallel_for) {
8441 if (
DSAStack->checkMappableExprComponentListsForDecl(
8445 ConflictKind = WhereFoundClauseKind;
8448 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
8461 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
8468 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
8481 Expr *VDInitRefExpr =
nullptr;
8489 ElemType = ElemType.getUnqualifiedType();
8490 auto *VDInitTemp =
buildVarDecl(*
this, RefExpr->getExprLoc(), ElemType,
8491 ".firstprivate.temp");
8499 VDPrivate->setInvalidDecl();
8501 VDPrivate->setInit(Result.
getAs<
Expr>());
8505 auto *VDInit =
buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
8506 ".firstprivate.temp");
8508 RefExpr->getExprLoc());
8513 if (VDPrivate->isInvalidDecl()) {
8514 if (IsImplicitClause) {
8515 Diag(RefExpr->getExprLoc(),
8516 diag::note_omp_task_predetermined_firstprivate_here);
8522 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
8523 RefExpr->getExprLoc());
8526 if (TopDVar.CKind == OMPC_lastprivate)
8527 Ref = TopDVar.PrivateCopy;
8531 ExprCaptures.push_back(Ref->getDecl());
8534 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
8536 ? RefExpr->IgnoreParens()
8538 PrivateCopies.push_back(VDPrivateRefExpr);
8539 Inits.push_back(VDInitRefExpr);
8546 Vars, PrivateCopies,
Inits,
8560 for (
auto &RefExpr : VarList) {
8561 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
8564 Expr *SimpleRefExpr = RefExpr;
8568 Vars.push_back(RefExpr);
8569 SrcExprs.push_back(
nullptr);
8570 DstExprs.push_back(
nullptr);
8571 AssignmentOps.push_back(
nullptr);
8578 auto *VD = dyn_cast<
VarDecl>(D);
8584 diag::err_omp_lastprivate_incomplete_type))
8593 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8594 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
8595 DVar.CKind != OMPC_firstprivate &&
8596 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
8597 Diag(ELoc, diag::err_omp_wrong_dsa)
8611 DSAStackTy::DSAVarData TopDVar = DVar;
8615 DVar =
DSAStack->getImplicitDSA(D,
true);
8616 if (DVar.CKind != OMPC_shared) {
8617 Diag(ELoc, diag::err_omp_required_access)
8628 if (CurrDir == OMPD_distribute) {
8629 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8630 if (DVar.CKind == OMPC_firstprivate) {
8631 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
8649 auto *PseudoSrcExpr =
8657 auto AssignmentOp =
BuildBinOp(
nullptr, ELoc, BO_Assign,
8658 PseudoDstExpr, PseudoSrcExpr);
8659 if (AssignmentOp.isInvalid())
8663 if (AssignmentOp.isInvalid())
8668 if (TopDVar.CKind == OMPC_firstprivate)
8669 Ref = TopDVar.PrivateCopy;
8673 ExprCaptures.push_back(Ref->
getDecl());
8675 if (TopDVar.CKind == OMPC_firstprivate ||
8686 ExprPostUpdates.push_back(
8690 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
8692 ? RefExpr->IgnoreParens()
8694 SrcExprs.push_back(PseudoSrcExpr);
8695 DstExprs.push_back(PseudoDstExpr);
8696 AssignmentOps.push_back(AssignmentOp.get());
8703 Vars, SrcExprs, DstExprs, AssignmentOps,
8713 for (
auto &RefExpr : VarList) {
8714 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
8717 Expr *SimpleRefExpr = RefExpr;
8721 Vars.push_back(RefExpr);
8727 auto *VD = dyn_cast<
VarDecl>(D);
8735 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
8736 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
8747 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
8749 ? RefExpr->IgnoreParens()
8760 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
8766 DSAStackTy::DSAVarData DVar =
Stack->getTopDSA(VD,
false);
8767 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
8771 DSAStackTy::DSAVarData DVarPrivate =
Stack->hasDSA(
8780 bool VisitStmt(
Stmt *S) {
8782 if (Child && Visit(Child))
8787 explicit DSARefChecker(DSAStackTy *S) :
Stack(S) {}
8794 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
8801 : BaseTransform(SemaRef),
Field(FieldDecl), CapturedExpr(nullptr) {}
8807 return CapturedExpr;
8809 return BaseTransform::TransformMemberExpr(E);
8811 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
8815 template <
typename T>
8817 const llvm::function_ref<T(
ValueDecl *)> &Gen) {
8818 for (
auto &Set : Lookups) {
8819 for (
auto *D : Set) {
8820 if (
auto Res = Gen(cast<ValueDecl>(D)))
8846 Lookups.back().append(Lookup.
begin(), Lookup.
end());
8849 }
else if (
auto *ULE =
8850 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
8852 Decl *PrevD =
nullptr;
8853 for (
auto *D : ULE->decls()) {
8856 else if (
auto *DRD = cast<OMPDeclareReductionDecl>(D))
8857 Lookups.back().addDecl(DRD);
8863 filterLookupForUDR<bool>(Lookups, [](
ValueDecl *D) ->
bool {
8870 for (
auto &Set : Lookups) {
8871 ResSet.
append(Set.begin(), Set.end());
8873 ResSet.
addDecl(Set[Set.size() - 1]);
8878 true,
true, ResSet.
begin(), ResSet.
end());
8880 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
8888 if (
auto *VD = filterLookupForUDR<ValueDecl *>(
8910 if (ReductionIdScopeSpec.
isSet()) {
8911 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
8919 struct ReductionData {
8934 ReductionData() =
delete;
8936 ReductionData(
unsigned Size) {
8941 ReductionOps.reserve(Size);
8942 ExprCaptures.reserve(Size);
8943 ExprPostUpdates.reserve(Size);
8947 void push(
Expr *Item,
Expr *ReductionOp) {
8948 Vars.emplace_back(Item);
8950 LHSs.emplace_back(
nullptr);
8951 RHSs.emplace_back(
nullptr);
8952 ReductionOps.emplace_back(ReductionOp);
8956 Expr *ReductionOp) {
8957 Vars.emplace_back(Item);
8959 LHSs.emplace_back(LHS);
8960 RHSs.emplace_back(RHS);
8961 ReductionOps.emplace_back(ReductionOp);
8972 auto DN = ReductionId.
getName();
9011 case OO_Array_Delete:
9020 case OO_GreaterEqual:
9025 case OO_PercentEqual:
9030 case OO_GreaterGreater:
9031 case OO_LessLessEqual:
9032 case OO_GreaterGreaterEqual:
9034 case OO_ExclaimEqual:
9042 case OO_Conditional:
9045 llvm_unreachable(
"Unexpected reduction identifier");
9047 if (
auto II = DN.getAsIdentifierInfo()) {
9048 if (II->isStr(
"max"))
9050 else if (II->isStr(
"min"))
9056 if (ReductionIdScopeSpec.
isValid())
9060 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
9061 bool FirstIter =
true;
9062 for (
auto RefExpr : VarList) {
9063 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
9071 if (!FirstIter && IR != ER)
9076 Expr *SimpleRefExpr = RefExpr;
9085 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
9086 ReductionId, Type, BasePath, IR == ER ?
nullptr : *IR);
9087 Expr *ReductionOp =
nullptr;
9089 (DeclareReductionRef.
isUnset() ||
9090 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
9091 ReductionOp = DeclareReductionRef.
get();
9093 RD.push(RefExpr, ReductionOp);
9103 Type = ASE->getType().getNonReferenceType();
9106 if (
auto *ATy = BaseType->getAsArrayTypeUnsafe())
9107 Type = ATy->getElementType();
9113 auto *VD = dyn_cast<
VarDecl>(D);
9119 diag::err_omp_reduction_incomplete_type))
9125 S.
Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
9126 if (!ASE && !OASE) {
9127 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
9130 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9138 if (!ASE && !OASE && VD) {
9139 VarDecl *VDDef = VD->getDefinition();
9141 DSARefChecker Check(Stack);
9142 if (Check.Visit(VDDef->
getInit())) {
9143 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
9162 DSAStackTy::DSAVarData DVar;
9163 DVar = Stack->getTopDSA(D,
false);
9164 if (DVar.CKind == OMPC_reduction) {
9165 S.
Diag(ELoc, diag::err_omp_once_referenced)
9168 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
9170 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
9185 DVar = Stack->getImplicitDSA(D,
true);
9186 if (DVar.CKind != OMPC_shared) {
9187 S.
Diag(ELoc, diag::err_omp_required_access)
9199 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
9200 ReductionId, Type, BasePath, IR == ER ?
nullptr : *IR);
9204 (DeclareReductionRef.
isUnset() ||
9205 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
9206 RD.push(RefExpr, DeclareReductionRef.
get());
9209 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
9211 S.
Diag(ReductionId.getLocStart(),
9212 diag::err_omp_unknown_reduction_identifier)
9213 << Type << ReductionIdRange;
9225 if (DeclareReductionRef.
isUnset()) {
9226 if ((BOK == BO_GT || BOK == BO_LT) &&
9227 !(Type->isScalarType() ||
9228 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
9229 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
9231 if (!ASE && !OASE) {
9232 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
9235 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9240 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
9241 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
9242 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
9244 if (!ASE && !OASE) {
9245 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
9248 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9255 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
9256 auto *LHSVD =
buildVarDecl(S, ELoc, Type,
".reduction.lhs",
9260 auto PrivateTy = Type;
9274 }
else if (!ASE && !OASE &&
9281 Expr *Init =
nullptr;
9284 if (DeclareReductionRef.
isUsable()) {
9286 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
9287 if (DRD->getInitializer()) {
9289 RHSVD->setInit(DRDRef);
9299 if (Type->isScalarType() || Type->isAnyComplexType())
9304 if (Type->isScalarType() || Type->isAnyComplexType()) {
9313 Type = ComplexTy->getElementType();
9314 if (Type->isRealFloatingType()) {
9315 llvm::APFloat InitValue =
9316 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
9320 }
else if (Type->isScalarType()) {
9323 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
9340 if (Type->isIntegerType() || Type->isPointerType()) {
9345 llvm::APInt InitValue =
9346 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
9347 : llvm::APInt::getMinValue(Size)
9348 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
9349 : llvm::APInt::getMaxValue(Size);
9351 if (Type->isPointerType()) {
9360 }
else if (Type->isRealFloatingType()) {
9361 llvm::APFloat InitValue = llvm::APFloat::getLargest(
9391 llvm_unreachable(
"Unexpected reduction operation");
9394 if (Init && DeclareReductionRef.
isUnset())
9398 if (RHSVD->isInvalidDecl())
9400 if (!RHSVD->hasInit() && DeclareReductionRef.
isUnset()) {
9401 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
9402 << Type << ReductionIdRange;
9403 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
9406 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9412 PrivateVD->setInit(RHSVD->getInit());
9413 PrivateVD->setInitStyle(RHSVD->getInitStyle());
9416 if (DeclareReductionRef.
isUsable()) {
9421 if (!BasePath.empty()) {
9425 CK_UncheckedDerivedToBase, LHS.
get(),
9428 CK_UncheckedDerivedToBase, RHS.get(),
9429 &BasePath, RHS.get()->getValueKind());
9432 QualType Params[] = {PtrRedTy, PtrRedTy};
9442 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
9444 if (BOK != BO_LT && BOK != BO_GT) {
9446 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
9447 BO_Assign, LHSDRE, ReductionOp.
get());
9453 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
9454 BO_Assign, LHSDRE, ConditionalOp);
9466 TransformExprToCaptures RebuildToCapture(S, D);
9468 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
9469 Ref = RebuildToCapture.getCapturedExpr();
9471 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
9474 RD.ExprCaptures.emplace_back(Ref->
getDecl());
9480 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9485 Stack->getCurrentDirective() == OMPD_taskgroup) {
9486 S.
Diag(RefExpr->getExprLoc(),
9487 diag::err_omp_reduction_non_addressable_expression)
9488 << RefExpr->getSourceRange();
9491 RD.ExprPostUpdates.emplace_back(
9498 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
9499 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get());
9501 return RD.Vars.empty();
9509 ReductionData RD(VarList.size());
9512 StartLoc, LParenLoc, ColonLoc, EndLoc,
9513 ReductionIdScopeSpec, ReductionId,
9514 UnresolvedReductions, RD))
9518 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
9520 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
9530 ReductionData RD(VarList.size());
9533 VarList, StartLoc, LParenLoc, ColonLoc,
9534 EndLoc, ReductionIdScopeSpec, ReductionId,
9535 UnresolvedReductions, RD))
9539 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
9541 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
9548 if ((!
LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
9550 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) <<
LangOpts.CPlusPlus;
9559 auto *VD = dyn_cast_or_null<VarDecl>(D);
9563 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
9565 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
9573 Diag(ELoc, diag::err_omp_const_variable)
9580 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9589 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(
Context) &&
9590 !Ty->isPointerType())) {
9591 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
9597 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9615 LinKind = OMPC_LINEAR_val;
9616 for (
auto &RefExpr : VarList) {
9617 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
9620 Expr *SimpleRefExpr = RefExpr;
9625 Vars.push_back(RefExpr);
9626 Privates.push_back(
nullptr);
9627 Inits.push_back(
nullptr);
9634 auto *VD = dyn_cast<
VarDecl>(D);
9640 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
9663 ExprCaptures.push_back(Ref->
getDecl());
9670 SimpleRefExpr, RefRes.
get());
9673 ExprPostUpdates.push_back(
9678 if (LinKind == OMPC_LINEAR_uval)
9679 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
9681 InitExpr = VD ? SimpleRefExpr : Ref;
9686 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
9688 ? RefExpr->IgnoreParens()
9690 Privates.push_back(PrivateRef);
9691 Inits.push_back(InitRef);
9698 Expr *CalcStepExpr =
nullptr;
9706 StepExpr = Val.
get();
9714 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
9721 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
9722 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
9723 << (Vars.size() > 1);
9724 if (!IsConstant && CalcStep.isUsable()) {
9727 CalcStepExpr = CalcStep.get();
9732 ColonLoc, EndLoc, Vars, Privates, Inits,
9733 StepExpr, CalcStepExpr,
9739 Expr *NumIterations,
Sema &SemaRef,
9748 if (Step ==
nullptr)
9750 else if (CalcStep) {
9751 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
9753 bool HasErrors =
false;
9754 auto CurInit = Clause.inits().begin();
9755 auto CurPrivate = Clause.privates().begin();
9756 auto LinKind = Clause.getModifier();
9757 for (
auto &RefExpr : Clause.
varlists()) {
9760 Expr *SimpleRefExpr = RefExpr;
9764 if (Res.second || !D) {
9765 Updates.push_back(
nullptr);
9766 Finals.push_back(
nullptr);
9770 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) {
9771 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts())
9774 auto &&Info = Stack->isLoopControlVariable(D);
9775 Expr *InitExpr = *CurInit;
9778 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
9780 if (LinKind == OMPC_LINEAR_uval)
9781 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
9785 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
9793 InitExpr, IV,
Step,
false);
9795 Update = *CurPrivate;
9803 InitExpr, NumIterations,
Step,
9806 Final = *CurPrivate;
9810 if (!Update.isUsable() || !Final.
isUsable()) {
9811 Updates.push_back(
nullptr);
9812 Finals.push_back(
nullptr);
9815 Updates.push_back(Update.get());
9816 Finals.push_back(Final.
get());
9821 Clause.setUpdates(Updates);
9822 Clause.setFinals(Finals);
9831 for (
auto &RefExpr : VarList) {
9832 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
9835 Expr *SimpleRefExpr = RefExpr;
9840 Vars.push_back(RefExpr);
9847 auto *VD = dyn_cast<
VarDecl>(D);
9855 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
9861 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9868 if (
Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
9869 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
9870 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
9879 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
9888 if (Alignment !=
nullptr) {
9890 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
9893 Alignment = AlignResult.
get();
9899 EndLoc, Vars, Alignment);
9910 for (
auto &RefExpr : VarList) {
9911 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
9912 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
9914 Vars.push_back(RefExpr);
9915 SrcExprs.push_back(
nullptr);
9916 DstExprs.push_back(
nullptr);
9917 AssignmentOps.push_back(
nullptr);
9927 if (!DE || !isa<VarDecl>(DE->
getDecl())) {
9928 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
9929 << 0 << RefExpr->getSourceRange();
9934 VarDecl *VD = cast<VarDecl>(D);
9937 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
9940 SrcExprs.push_back(
nullptr);
9941 DstExprs.push_back(
nullptr);
9942 AssignmentOps.push_back(
nullptr);
9948 if (!
DSAStack->isThreadPrivate(VD)) {
9949 Diag(ELoc, diag::err_omp_required_access)
9964 *
this, SrcVD, ElemType.getUnqualifiedType(), DE->
getExprLoc());
9968 auto *PseudoDstExpr =
9973 PseudoDstExpr, PseudoSrcExpr);
9974 if (AssignmentOp.isInvalid())
9978 if (AssignmentOp.isInvalid())
9981 DSAStack->addDSA(VD, DE, OMPC_copyin);
9983 SrcExprs.push_back(PseudoSrcExpr);
9984 DstExprs.push_back(PseudoDstExpr);
9985 AssignmentOps.push_back(AssignmentOp.get());
9992 SrcExprs, DstExprs, AssignmentOps);
10003 for (
auto &RefExpr : VarList) {
10004 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
10007 Expr *SimpleRefExpr = RefExpr;
10012 Vars.push_back(RefExpr);
10013 SrcExprs.push_back(
nullptr);
10014 DstExprs.push_back(
nullptr);
10015 AssignmentOps.push_back(
nullptr);
10022 auto *VD = dyn_cast<
VarDecl>(D);
10027 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
10028 auto DVar =
DSAStack->getTopDSA(D,
false);
10029 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
10031 Diag(ELoc, diag::err_omp_wrong_dsa)
10042 DVar =
DSAStack->getImplicitDSA(D,
false);
10043 if (DVar.CKind == OMPC_shared) {
10044 Diag(ELoc, diag::err_omp_required_access)
10046 <<
"threadprivate or private in the enclosing context";
10055 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10062 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10072 .getUnqualifiedType();
10074 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.src",
10078 buildVarDecl(*
this, RefExpr->getLocStart(), Type,
".copyprivate.dst",
10082 PseudoDstExpr, PseudoSrcExpr);
10083 if (AssignmentOp.isInvalid())
10087 if (AssignmentOp.isInvalid())
10094 VD ? RefExpr->IgnoreParens()
10096 SrcExprs.push_back(PseudoSrcExpr);
10097 DstExprs.push_back(PseudoDstExpr);
10098 AssignmentOps.push_back(AssignmentOp.get());
10105 Vars, SrcExprs, DstExprs, AssignmentOps);
10112 if (VarList.empty())
10123 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
10124 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
10125 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10129 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
10131 DepKind == OMPC_DEPEND_sink)) {
10132 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
10133 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
10141 llvm::APSInt DepCounter(32);
10142 llvm::APSInt TotalDepCount(32);
10143 if (DepKind == OMPC_DEPEND_sink) {
10144 if (
auto *OrderedCountExpr =
DSAStack->getParentOrderedRegionParam()) {
10145 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(
Context);
10146 TotalDepCount.setIsUnsigned(
true);
10149 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
10150 DSAStack->getParentOrderedRegionParam()) {
10151 for (
auto &RefExpr : VarList) {
10152 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
10153 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10155 Vars.push_back(RefExpr);
10160 auto *SimpleExpr = RefExpr->IgnoreParenCasts();
10161 if (DepKind == OMPC_DEPEND_sink) {
10162 if (DepCounter >= TotalDepCount) {
10163 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
10177 Vars.push_back(RefExpr);
10180 SimpleExpr = SimpleExpr->IgnoreImplicit();
10183 Expr *LHS = SimpleExpr;
10184 Expr *RHS =
nullptr;
10185 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
10187 OOLoc = BO->getOperatorLoc();
10190 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
10191 OOK = OCE->getOperator();
10192 OOLoc = OCE->getOperatorLoc();
10195 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
10196 OOK = MCE->getMethodDecl()
10199 .getCXXOverloadedOperator();
10200 OOLoc = MCE->getCallee()->getExprLoc();
10210 Vars.push_back(RefExpr);
10216 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
10217 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
10221 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
10222 RHS, OMPC_depend,
false);
10227 DSAStack->getParentOrderedRegionParam() &&
10228 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
10229 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
10230 <<
DSAStack->getParentLoopControlVariable(
10231 DepCounter.getZExtValue());
10234 OpsOffs.push_back({RHS, OOK});
10243 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
10244 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) ||
10248 .getNonReferenceType()
10249 ->isPointerType() &&
10250 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
10251 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item)
10252 << 0 << RefExpr->getSourceRange();
10256 Vars.push_back(RefExpr->IgnoreParenImpCasts());
10260 TotalDepCount > VarList.size() &&
10261 DSAStack->getParentOrderedRegionParam()) {
10262 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
10263 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
10265 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
10270 DepKind, DepLoc, ColonLoc, Vars);
10271 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
10272 DSAStack->addDoacrossDependClause(C, OpsOffs);
10279 Expr *ValExpr = Device;
10297 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10298 SemaRef.
Diag(RD->
getLocation(), diag::note_omp_polymorphic_in_target);
10302 bool IsCorrect =
true;
10303 for (
auto *I : DC->decls()) {
10305 if (
auto *MD = dyn_cast<CXXMethodDecl>(I)) {
10306 if (MD->isStatic()) {
10307 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10308 SemaRef.
Diag(MD->getLocation(),
10309 diag::note_omp_static_member_in_target);
10312 }
else if (
auto *VD = dyn_cast<VarDecl>(I)) {
10313 if (VD->isStaticDataMember()) {
10314 SemaRef.
Diag(Loc, diag::err_omp_not_mappable_type) << QTy;
10316 diag::note_omp_static_member_in_target);
10323 for (
auto &I : RD->
bases()) {
10325 I.getType()->getAsCXXRecordDecl()))
10335 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
10337 }
else if (
CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) {
10355 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
10356 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
10357 return ATy->getSize().getSExtValue() != 1;
10362 assert(OASE &&
"Expecting array section if not an array subscript.");
10363 auto *LowerBound = OASE->getLowerBound();
10364 auto *
Length = OASE->getLength();
10369 llvm::APSInt ConstLowerBound;
10370 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.
getASTContext()))
10372 if (ConstLowerBound.getSExtValue())
10391 llvm::APSInt ConstLength;
10395 return CATy->
getSize().getSExtValue() != ConstLength.getSExtValue();
10408 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
10411 assert(OASE &&
"Expecting array section if not an array subscript.");
10412 auto *
Length = OASE->getLength();
10418 if (
auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
10419 return ATy->getSize().getSExtValue() != 1;
10425 llvm::APSInt ConstLength;
10429 return ConstLength.getSExtValue() != 1;
10462 Expr *RelevantExpr =
nullptr;
10481 bool AllowUnitySizeArraySection =
true;
10482 bool AllowWholeSizeArraySection =
true;
10484 while (!RelevantExpr) {
10487 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
10488 if (!isa<VarDecl>(CurE->getDecl()))
10491 RelevantExpr = CurE;
10495 AllowUnitySizeArraySection =
false;
10496 AllowWholeSizeArraySection =
false;
10500 CurE, CurE->getDecl()));
10504 if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
10505 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
10507 if (isa<CXXThisExpr>(BaseE))
10509 RelevantExpr = CurE;
10513 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
10514 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
10515 << CurE->getSourceRange();
10519 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
10524 if (FD->isBitField()) {
10525 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
10533 QualType CurType = BaseE->getType().getNonReferenceType();
10540 if (RT->isUnionType()) {
10541 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
10542 << CurE->getSourceRange();
10553 AllowUnitySizeArraySection =
false;
10554 AllowWholeSizeArraySection =
false;
10557 CurComponents.push_back(
10562 if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
10566 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
10567 << 0 << CurE->getSourceRange();
10576 AllowWholeSizeArraySection =
false;
10579 CurComponents.push_back(
10584 if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
10593 if (CurType->isReferenceType())
10598 if (!IsPointer && !CurType->isArrayType()) {
10599 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
10600 << 0 << CurE->getSourceRange();
10609 if (AllowWholeSizeArraySection) {
10616 if (NotWhole || IsPointer)
10617 AllowWholeSizeArraySection =
false;
10618 }
else if (AllowUnitySizeArraySection && NotUnity) {
10622 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
10623 << CurE->getSourceRange();
10628 CurComponents.push_back(
10635 diag::err_omp_expected_named_var_member_or_array_expression)
10640 return RelevantExpr;
10647 bool CurrentRegionOnly,
10658 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
10659 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
10660 "Map clause expression with unexpected base!");
10663 bool IsEnclosedByDataEnvironmentExpr =
false;
10664 const Expr *EnclosingExpr =
nullptr;
10666 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
10667 VD, CurrentRegionOnly,
10672 assert(!StackComponents.empty() &&
10673 "Map clause expression with no components!");
10674 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
10675 "Map clause expression with unexpected base!");
10678 auto *RE = StackComponents.front().getAssociatedExpression();
10684 auto CI = CurComponents.rbegin();
10685 auto CE = CurComponents.rend();
10686 auto SI = StackComponents.rbegin();
10687 auto SE = StackComponents.rend();
10688 for (; CI != CE && SI != SE; ++CI, ++SI) {
10693 if (CurrentRegionOnly &&
10694 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
10695 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
10696 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
10697 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
10698 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
10699 diag::err_omp_multiple_array_items_in_map_clause)
10700 << CI->getAssociatedExpression()->getSourceRange();
10701 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
10702 diag::note_used_here)
10703 << SI->getAssociatedExpression()->getSourceRange();
10708 if (CI->getAssociatedExpression()->getStmtClass() !=
10709 SI->getAssociatedExpression()->getStmtClass())
10713 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
10719 for (; SI != SE; ++SI) {
10722 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
10723 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
10724 }
else if (
auto *OASE = dyn_cast<OMPArraySectionExpr>(
10725 SI->getAssociatedExpression())) {
10732 SemaRef, SI->getAssociatedExpression(), Type))
10742 if (CI == CE && SI == SE) {
10743 if (CurrentRegionOnly) {
10744 if (CKind == OMPC_map)
10745 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10747 assert(CKind == OMPC_to || CKind == OMPC_from);
10748 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10751 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10752 << RE->getSourceRange();
10757 IsEnclosedByDataEnvironmentExpr =
true;
10763 std::prev(CI)->getAssociatedDeclaration()->getType();
10765 std::prev(CI)->getAssociatedExpression()->getExprLoc();
10784 if (CI == CE || SI == SE) {
10787 diag::err_omp_pointer_mapped_along_with_derived_section)
10790 assert(CI != CE && SI != SE);
10791 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
10794 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10795 << RE->getSourceRange();
10804 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
10805 if (CKind == OMPC_map)
10806 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
10808 assert(CKind == OMPC_to || CKind == OMPC_from);
10809 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
10812 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
10813 << RE->getSourceRange();
10819 if (!CurrentRegionOnly && SI != SE)
10820 EnclosingExpr = RE;
10824 IsEnclosedByDataEnvironmentExpr |=
10825 (!CurrentRegionOnly && CI != CE && SI == SE);
10830 if (CurrentRegionOnly)
10844 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
10846 diag::err_omp_original_storage_is_shared_and_does_not_contain)
10859 struct MappableVarListInfo final {
10872 VarComponents.reserve(VarList.size());
10873 VarBaseDeclarations.reserve(VarList.size());
10888 bool IsMapTypeImplicit =
false) {
10890 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
10891 "Unexpected clause kind with mappable expressions!");
10899 for (
auto &RE : MVLI.VarList) {
10900 assert(RE &&
"Null expr in omp to/from/map clause");
10903 auto *VE = RE->IgnoreParenLValueCasts();
10905 if (VE->isValueDependent() || VE->isTypeDependent() ||
10906 VE->isInstantiationDependent() ||
10907 VE->containsUnexpandedParameterPack()) {
10910 MVLI.ProcessedVarList.push_back(RE);
10914 auto *SimpleExpr = RE->IgnoreParenCasts();
10916 if (!RE->IgnoreParenImpCasts()->isLValue()) {
10918 diag::err_omp_expected_named_var_member_or_array_expression)
10919 << RE->getSourceRange();
10933 assert(!CurComponents.empty() &&
10934 "Invalid mappable expression information.");
10939 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
10940 assert(CurDeclaration &&
"Null decl on map clause.");
10942 CurDeclaration->isCanonicalDecl() &&
10943 "Expecting components to have associated only canonical declarations.");
10945 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
10946 auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
10948 assert((VD || FD) &&
"Only variables or fields are expected here!");
10955 if (VD && DSAS->isThreadPrivate(VD)) {
10956 auto DVar = DSAS->getTopDSA(VD,
false);
10957 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
10972 true, CurComponents, CKind))
10974 if (CKind == OMPC_map &&
10976 false, CurComponents, CKind))
10983 QualType Type = CurDeclaration->getType().getNonReferenceType();
10993 if (CKind == OMPC_map) {
10999 if (DKind == OMPD_target_enter_data &&
11000 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
11001 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
11002 << (IsMapTypeImplicit ? 1 : 0)
11012 if (DKind == OMPD_target_exit_data &&
11013 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
11014 MapType == OMPC_MAP_delete)) {
11015 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
11016 << (IsMapTypeImplicit ? 1 : 0)
11025 if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
11026 DKind == OMPD_target_teams_distribute ||
11027 DKind == OMPD_target_teams_distribute_parallel_for ||
11028 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
11029 DKind == OMPD_target_teams_distribute_simd) && VD) {
11030 auto DVar = DSAS->getTopDSA(VD,
false);
11032 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
11043 MVLI.ProcessedVarList.push_back(RE);
11047 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
11053 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
11054 MVLI.VarComponents.back().append(CurComponents.begin(),
11055 CurComponents.end());
11056 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr
11067 MappableVarListInfo MVLI(VarList);
11069 MapType, IsMapTypeImplicit);
11074 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11075 MVLI.VarComponents, MapTypeModifier, MapType,
11076 IsMapTypeImplicit, MapLoc);
11084 if (ReductionType.isNull())
11091 if (ReductionType.hasQualifiers()) {
11092 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
11096 if (ReductionType->isFunctionType()) {
11097 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
11100 if (ReductionType->isReferenceType()) {
11101 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
11104 if (ReductionType->isArrayType()) {
11105 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
11108 return ReductionType;
11113 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
11116 Decls.reserve(ReductionTypes.size());
11124 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
11126 bool InCompoundScope =
true;
11127 if (S !=
nullptr) {
11136 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
11138 while (Filter.hasNext()) {
11139 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
11140 if (InCompoundScope) {
11141 auto I = UsedAsPrevious.find(PrevDecl);
11142 if (I == UsedAsPrevious.end())
11143 UsedAsPrevious[PrevDecl] =
false;
11144 if (
auto *D = PrevDecl->getPrevDeclInScope())
11145 UsedAsPrevious[D] =
true;
11147 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
11148 PrevDecl->getLocation();
11151 if (InCompoundScope) {
11152 for (
auto &PrevData : UsedAsPrevious) {
11153 if (!PrevData.second) {
11154 PrevDRD = PrevData.first;
11159 }
else if (PrevDeclInScope !=
nullptr) {
11160 auto *PrevDRDInScope = PrevDRD =
11161 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
11163 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
11165 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
11166 }
while (PrevDRDInScope !=
nullptr);
11168 for (
auto &TyData : ReductionTypes) {
11169 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
11170 bool Invalid =
false;
11171 if (I != PreviousRedeclTypes.end()) {
11172 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
11174 Diag(I->second, diag::note_previous_definition);
11177 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
11179 Name, TyData.first, PrevDRD);
11181 DRD->setAccess(AS);
11182 Decls.push_back(DRD);
11184 DRD->setInvalidDecl();
11194 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11209 QualType ReductionType = DRD->getType();
11226 if (S !=
nullptr) {
11230 DRD->addDecl(OmpInParm);
11231 DRD->addDecl(OmpOutParm);
11236 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11243 if (Combiner !=
nullptr)
11244 DRD->setCombiner(Combiner);
11246 DRD->setInvalidDecl();
11250 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11264 QualType ReductionType = DRD->getType();
11271 auto *OmpPrivParm =
11279 auto *OmpOrigParm =
11281 if (S !=
nullptr) {
11285 DRD->addDecl(OmpPrivParm);
11286 DRD->addDecl(OmpOrigParm);
11291 Expr *Initializer) {
11292 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11299 if (Initializer !=
nullptr)
11300 DRD->setInitializer(Initializer);
11302 DRD->setInvalidDecl();
11307 for (
auto *D : DeclReductions.
get()) {
11309 auto *DRD = cast<OMPDeclareReductionDecl>(D);
11315 return DeclReductions;
11322 Expr *ValExpr = NumTeams;
11323 Stmt *HelperValStmt =
nullptr;
11335 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11336 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11341 StartLoc, LParenLoc, EndLoc);
11348 Expr *ValExpr = ThreadLimit;
11349 Stmt *HelperValStmt =
nullptr;
11361 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11362 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11367 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
11374 Expr *ValExpr = Priority;
11389 Expr *ValExpr = Grainsize;
11405 Expr *ValExpr = NumTasks;
11423 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
11435 std::string Values;
11439 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
11443 Expr *ValExpr = ChunkSize;
11444 Stmt *HelperValStmt =
nullptr;
11455 ValExpr = Val.
get();
11462 if (Result.isSigned() && !Result.isStrictlyPositive()) {
11463 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
11467 }
else if (isParallelOrTaskRegion(
DSAStack->getCurrentDirective()) &&
11469 llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11470 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11478 Kind, ValExpr, HelperValStmt);
11486 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
11490 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
11492 OMPC_DEFAULTMAP_MODIFIER_tofrom);
11496 OMPC_DEFAULTMAP_scalar);
11500 Diag(Loc, diag::err_omp_unexpected_clause_value)
11514 Diag(Loc, diag::err_omp_region_not_file_context);
11517 if (IsInOpenMPDeclareTargetContext) {
11518 Diag(Loc, diag::err_omp_enclosed_declare_target);
11522 IsInOpenMPDeclareTargetContext =
true;
11527 assert(IsInOpenMPDeclareTargetContext &&
11528 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
11530 IsInOpenMPDeclareTargetContext =
false;
11536 OMPDeclareTargetDeclAttr::MapTypeTy MT,
11548 llvm::make_unique<VarOrFuncDeclFilterCCC>(*
this),
11561 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
11565 if (!ND->
hasAttr<OMPDeclareTargetDeclAttr>()) {
11566 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
Context, MT);
11569 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
11571 }
else if (ND->
getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
11572 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
11583 Decl *LD =
nullptr;
11584 if (isa<TagDecl>(D)) {
11586 }
else if (isa<VarDecl>(D)) {
11591 if (cast<VarDecl>(D)->isImplicit()) {
11592 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11593 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11596 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11600 }
else if (isa<FunctionDecl>(D)) {
11602 if (cast<FunctionDecl>(D)->hasBody(FD))
11609 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11610 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11613 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11619 if (LD && !LD->
hasAttr<OMPDeclareTargetDeclAttr>() &&
11620 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
11623 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
11624 SemaRef.
Diag(SL, diag::note_used_here) << SR;
11628 if (isa<FunctionDecl>(DC) &&
11629 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
11637 SemaRef.
Diag(LD->
getLocation(), diag::warn_omp_not_in_target_context);
11638 SemaRef.
Diag(SL, diag::note_used_here) << SR;
11641 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11642 SemaRef.
Context, OMPDeclareTargetDeclAttr::MT_To);
11645 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11652 if (VD->
hasAttr<OMPDeclareTargetDeclAttr>())
11665 if (
VarDecl *VD = dyn_cast<VarDecl>(D)) {
11666 if (
DSAStack->isThreadPrivate(VD)) {
11667 Diag(SL, diag::err_omp_threadprivate_in_target);
11672 if (
ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
11678 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
11679 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11680 Context, OMPDeclareTargetDeclAttr::MT_To);
11683 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
11690 if (!D->
hasAttr<OMPDeclareTargetDeclAttr>() &&
11691 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
11692 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
11693 Context, OMPDeclareTargetDeclAttr::MT_To);
11696 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
11707 MappableVarListInfo MVLI(VarList);
11709 if (MVLI.ProcessedVarList.empty())
11713 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11714 MVLI.VarComponents);
11721 MappableVarListInfo MVLI(VarList);
11723 if (MVLI.ProcessedVarList.empty())
11727 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
11728 MVLI.VarComponents);
11735 MappableVarListInfo MVLI(VarList);
11739 for (
auto &RefExpr : VarList) {
11740 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
11743 Expr *SimpleRefExpr = RefExpr;
11747 MVLI.ProcessedVarList.push_back(RefExpr);
11748 PrivateCopies.push_back(
nullptr);
11749 Inits.push_back(
nullptr);
11758 auto *VD = dyn_cast<
VarDecl>(D);
11762 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
11763 << 0 << RefExpr->getSourceRange();
11770 if (VDPrivate->isInvalidDecl())
11775 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
11779 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
11781 RefExpr->getExprLoc());
11791 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
11792 PrivateCopies.push_back(VDPrivateRefExpr);
11793 Inits.push_back(VDInitRefExpr);
11798 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
11802 MVLI.VarBaseDeclarations.push_back(D);
11803 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
11804 MVLI.VarComponents.back().push_back(
11808 if (MVLI.ProcessedVarList.empty())
11812 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
11813 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
11820 MappableVarListInfo MVLI(VarList);
11821 for (
auto &RefExpr : VarList) {
11822 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
11825 Expr *SimpleRefExpr = RefExpr;
11829 MVLI.ProcessedVarList.push_back(RefExpr);
11839 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
11840 << 0 << RefExpr->getSourceRange();
11846 auto DVar =
DSAStack->getTopDSA(D,
false);
11848 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
11856 Expr *ConflictExpr;
11857 if (
DSAStack->checkMappableExprComponentListsForDecl(
11862 ConflictExpr = R.front().getAssociatedExpression();
11865 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
11866 Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
11867 << ConflictExpr->getSourceRange();
11874 DSAStack->addMappableExpressionComponents(
11875 D, MC, OMPC_is_device_ptr);
11878 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
11883 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
11884 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
11885 "Unexpected device pointer expression!");
11886 MVLI.VarBaseDeclarations.push_back(
11887 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
11888 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
11889 MVLI.VarComponents.back().push_back(MC);
11892 if (MVLI.ProcessedVarList.empty())
11896 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
11897 MVLI.VarBaseDeclarations, MVLI.VarComponents);
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
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.
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
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.
Expr * NLB
Update of LowerBound for statically sheduled 'omp for' loops.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Defines the clang::ASTContext interface.
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Expr * NUB
Update of UpperBound for statically sheduled omp loops for outer loop in combined constructs (e...
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
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.
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.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
void setImplicit(bool I=true)
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
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 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.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
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.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
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.
ArrayRef< OMPClause * > clauses()
static Opcode getOpForCompoundAssignment(Opcode Opc)
DeclContext * getCurLexicalContext() const
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'use_device_ptr' clause.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
static bool hasClauses(ArrayRef< OMPClause * > Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
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.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
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.
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc...
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Expr * getSimdlen() const
Return safe iteration space distance.
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
const LangOptions & getLangOpts() const
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false)
Perform unqualified name lookup starting from a given scope.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
DeclClass * getAsSingle() const
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 OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Filter makeFilter()
Create a filter for this result set.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
FullExprArg MakeFullExpr(Expr *Arg)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ActionResult< Expr * > ExprResult
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.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
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...
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
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.
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
This represents 'if' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is captured by 'target' directive.
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
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...
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
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.
bool isEnumeralType() const
bool hasDefinition() const
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
This represents 'priority' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
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...
The base class of the type hierarchy.
bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
QualType getRecordType(const RecordDecl *Decl) const
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
const Expr * getInit() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
SourceLocation getOperatorLoc() const
static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
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.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
static bool ActOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions, ReductionData &RD)
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target update'.
Represents a C++ constructor within a class.
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
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.
const llvm::APInt & getSize() const
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
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.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
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.
DiagnosticsEngine & Diags
This represents 'num_threads' clause in the '#pragma omp ...' directive.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
Extra information about a function prototype.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
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.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
void setBegin(SourceLocation b)
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.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static OMPDistributeParallelForDirective * 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 containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Expr * getNumForLoops() const
Return the number of associated for-loops.
static const NamedDecl * getDefinition(const Decl *D)
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
void setHasBranchProtectedScope()
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
QualType withConst() const
Retrieves a version of this type with const applied.
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...
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
void ActOnUninitializedDecl(Decl *dcl)
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement...
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
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.
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
DeclarationName getName() const
getName - Returns the embedded declaration name.
One of these records is kept for each identifier that is lexed.
bool isScalarType() const
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
void setHasOMPDeclareReductionCombiner()
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
This represents 'simd' clause in the '#pragma omp ...' directive.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isReferenceType() const
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
The current expression is potentially evaluated at run time, which means that code may be generated t...
bool isAnyPointerType() const
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
SourceLocation getLocStart() const
Returns the starting location of the clause.
void Deallocate(void *Ptr) const
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 isTranslationUnit() const
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.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
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)
Defines some OpenMP-specific enums and functions.
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
void PopExpressionEvaluationContext()
This represents '#pragma omp critical' directive.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
void EndOpenMPClause()
End analysis of clauses.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
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.
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'is_device_ptr' clause.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
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.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
Represents the results of name lookup.
bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level)
Return true if the provided declaration VD should be captured by reference.
const TargetInfo & getTargetInfo() const
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer)
Finish current declare reduction construct initializer.
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...
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive.
void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct...
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
static ValueDecl * getCanonicalDecl(ValueDecl *D)
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'from' clause.
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
Concrete class used by the front-end to report problems and issues.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Look up the name of an OpenMP user-defined reduction operation.
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
This represents 'default' clause in the '#pragma omp ...' directive.
Scope - A scope is a transient data structure that is used while parsing the program.
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'map' clause.
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.
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
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...
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
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'.
An ordinary object is located at an address in memory.
detail::InMemoryDirectory::const_iterator I
static T filterLookupForUDR(SmallVectorImpl< UnresolvedSet< 8 >> &Lookups, const llvm::function_ref< T(ValueDecl *)> &Gen)
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.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2, C99 6.9p3).
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
const LangOptions & LangOpts
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Expr * NUB
Update of UpperBound for statically sheduled 'omp for' loops.
The lookup results will be used for redeclaration of a name, if an entity by that name already exists...
Expr * Cond
Loop condition.
static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, DSAStackTy *Stack, CXXRecordDecl *RD)
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Expr * PreCond
Loop pre-condition.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
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.
OpenMP 4.0 [2.4, Array Sections].
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
SourceLocation getLocEnd() const
Returns the ending location of the clause.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
ConditionalOperator - The ?: ternary operator.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
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...
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' 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.
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr * > VL)
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.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
std::vector< bool > & Stack
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Expr * IterationVarRef
Loop iteration variable.
sema::FunctionScopeInfo * getEnclosingFunction() const
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
Allows QualTypes to be sorted and hence used in maps and sets.
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
const Type * getTypePtrOrNull() const
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Expr - This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
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 isAnyComplexType() const
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
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.
bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is used in 'private' clause.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
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.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Defines the clang::Preprocessor interface.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, bool AllowFold=true)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
OpenMPClauseKind
OpenMP clauses.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
DeclContext * getDeclContext()
void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, const BlockExpr *blkExpr=nullptr)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
static 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.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
void DiscardCleanupsInEvaluationContext()
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.
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.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause * > Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
DiagnosticsEngine & getDiagnostics() const
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.
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr * > PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Represents a C++ conversion function within a class.
Expr * NLB
Update of LowerBound for statically sheduled omp loops for outer loop in combined constructs (e...
The result type of a method or function.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VL)
Creates clause with a list of variables VL.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
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.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
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...
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
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)
Expr * ST
Stride - local variable passed to runtime.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D)
Check declaration inside target region.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause * > Clauses)
static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause * > Clauses)
This captures a statement into a function.
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.
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< Expr *, DeclRefExpr * > *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
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.
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.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
This represents '#pragma omp declare reduction ...' directive.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool isConstant(const ASTContext &Ctx) const
Pseudo declaration for capturing expressions.
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
This is a basic class for representing single OpenMP executable directive.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
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.
bool isValid() const
Return true if this is a valid SourceLocation object.
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
This represents 'schedule' clause in the '#pragma omp ...' directive.
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.
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.
ASTContext & getASTContext() const
bool getSuppressAllDiagnostics() const
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'to' clause.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
IdentifierTable & getIdentifierTable()
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
QualType withConst() const
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
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.
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.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
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...
This is a basic class for representing single OpenMP clause.
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' 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.
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)
Describes the kind of initialization being performed, along with location information for tokens rela...
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
This declaration is only a declaration.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
SourceLocation getBegin() const
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.
const T * castAs() const
Member-template castAs<specific type>.
SourceLocation getBeginLoc() const
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.
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 isFileContext() const
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.
sema::FunctionScopeInfo * getCurFunction() const
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
SourceLocation getLocStart() const LLVM_READONLY
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement...
bool isDynamicClass() const
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.
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause * > Clauses)
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
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.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< Expr *, DeclRefExpr * > &Captures)
Build 'VarRef = Start.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
static Stmt * buildPreInits(ASTContext &Context, SmallVectorImpl< Decl * > &PreInits)
Build preinits statement for the given declarations.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
This represents 'device' clause in the '#pragma omp ...' directive.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
bool isInvalidDecl() const
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, OpenMPDirectiveKind NameModifier=OMPD_unknown)
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
This represents clause 'linear' in the '#pragma omp ...' directives.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause * > Clauses)
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
detail::InMemoryDirectory::const_iterator E
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
static Expr * CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind)
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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 bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
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.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
bool empty() const
Return true if no decls were found.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
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...
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
Not an overloaded operator.
Expr * getSafelen() const
Return safe iteration space distance.
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 isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
const T * getAs() const
Member-template getAs<specific type>'.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
QualType getCanonicalType() const
This file defines OpenMP AST classes for executable directives and clauses.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, bool IsDecltype=false)
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.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
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'...
Expr * Inc
Loop increment.
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
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.
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.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause * > Clauses)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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)
QualType withRestrict() const
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.
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
void addDecl(Decl *D)
Add the declaration D into this context.
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
SourceLocation getExprLoc() const LLVM_READONLY
bool isStaticDataMember() const
Determines whether this is a static data member.
This represents 'write' clause in the '#pragma omp atomic' directive.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr * > VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
QualType getPointeeType() const
bool isTLSSupported() const
Whether the target supports thread-local storage.
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 ...
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
static OMPTargetTeamsDistributeParallelForDirective * 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.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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)
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType 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...
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'.
Represents a C++ struct/union/class.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
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.
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.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
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.
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr * > Vars, ArrayRef< ValueDecl * > Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Defines the clang::TargetInfo interface.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
static OpaquePtr make(PtrTy P)
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
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 isValid() const
A scope specifier is present, and it refers to a real scope.
A reference to a declared variable, function, enum, etc.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isSet() const
Deprecated.
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 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 OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static OMPTeamsDistributeParallelForDirective * 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.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
An l-value expression is a reference to an object with independent storage.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, std::unique_ptr< CorrectionCandidateCallback > CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
NamedDecl - This represents a decl with a name.
static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses)
Creates directive with a list of Clauses.
void setAccess(AccessSpecifier AS)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
static OMPClauseWithPostUpdate * get(OMPClause *C)
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.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Describes an entity that is being initialized.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation getLocStart() const LLVM_READONLY
SourceLocation ColonLoc
Location of ':'.
This represents '#pragma omp threadprivate ...' directive.
Represents the canonical version of C arrays with a specified constant size.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
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.
void clear()
Clears out any current state.
void PushFunctionScope()
Enter a new function scope.
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Attr - This represents one attribute.
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause * > Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
static 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.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
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.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr * > &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause * > Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope...
bool isPointerType() const