31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang;
64 const Expr *RefExpr =
nullptr;
67 DSAVarData() =
default;
71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
74 using OperatorOffsetTy =
76 using DoacrossDependMapTy =
77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90 using LoopControlVariablesMapTy =
91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
94 struct MappedExprComponentTy {
98 using MappedExprComponentsTy =
99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100 using CriticalsWithHintsTy =
101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102 struct ReductionData {
103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106 ReductionData() =
default;
113 ReductionOp = RefExpr;
116 using DeclReductionMapTy =
117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
119 struct SharingMapTy {
120 DeclSAMapTy SharingMap;
121 DeclReductionMapTy ReductionMap;
122 AlignedMapTy AlignedMap;
123 MappedExprComponentsTy MappedExprComponents;
124 LoopControlVariablesMapTy LCVMap;
131 Scope *CurScope =
nullptr;
136 DoacrossDependMapTy DoacrossDepends;
141 unsigned AssociatedLoops = 1;
142 bool HasMutipleLoops =
false;
143 const Decl *PossiblyLoopCounter =
nullptr;
144 bool NowaitRegion =
false;
145 bool CancelRegion =
false;
146 bool LoopStart =
false;
147 bool BodyComplete =
false;
150 Expr *TaskgroupReductionRef =
nullptr;
157 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
159 SharingMapTy() =
default;
165 DeclSAMapTy Threadprivates;
172 bool ForceCapturing =
false;
175 bool ForceCaptureByReferenceInTargetExecutable =
false;
176 CriticalsWithHintsTy Criticals;
177 unsigned IgnoredStackElements = 0;
181 using const_iterator = StackTy::const_reverse_iterator;
182 const_iterator begin()
const {
183 return Stack.empty() ? const_iterator()
184 : Stack.back().first.rbegin() + IgnoredStackElements;
186 const_iterator end()
const {
187 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
189 using iterator = StackTy::reverse_iterator;
191 return Stack.empty() ? iterator()
192 : Stack.back().first.rbegin() + IgnoredStackElements;
195 return Stack.empty() ? iterator() : Stack.back().first.rend();
200 bool isStackEmpty()
const {
201 return Stack.empty() ||
202 Stack.back().second != CurrentNonCapturingFunctionScope ||
203 Stack.back().first.size() <= IgnoredStackElements;
205 size_t getStackSize()
const {
206 return isStackEmpty() ? 0
207 : Stack.back().first.size() - IgnoredStackElements;
210 SharingMapTy *getTopOfStackOrNull() {
211 size_t Size = getStackSize();
214 return &Stack.back().first[Size - 1];
216 const SharingMapTy *getTopOfStackOrNull()
const {
217 return const_cast<DSAStackTy&
>(*this).getTopOfStackOrNull();
219 SharingMapTy &getTopOfStack() {
220 assert(!isStackEmpty() &&
"no current directive");
221 return *getTopOfStackOrNull();
223 const SharingMapTy &getTopOfStack()
const {
224 return const_cast<DSAStackTy&
>(*this).getTopOfStack();
227 SharingMapTy *getSecondOnStackOrNull() {
228 size_t Size = getStackSize();
231 return &Stack.back().first[Size - 2];
233 const SharingMapTy *getSecondOnStackOrNull()
const {
234 return const_cast<DSAStackTy&
>(*this).getSecondOnStackOrNull();
243 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
244 assert(Level < getStackSize() &&
"no such stack element");
245 return Stack.back().first[
Level];
247 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
248 return const_cast<DSAStackTy&
>(*this).getStackElemAtLevel(Level);
251 DSAVarData getDSA(const_iterator &Iter,
ValueDecl *D)
const;
254 bool isOpenMPLocal(
VarDecl *D, const_iterator Iter)
const;
261 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
267 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
270 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
272 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
274 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
276 OMPPredefinedAllocators[AllocatorKind] = Allocator;
279 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
280 return OMPPredefinedAllocators[AllocatorKind];
283 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
285 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
286 return ClauseKindMode;
290 bool isBodyComplete()
const {
291 const SharingMapTy *Top = getTopOfStackOrNull();
292 return Top && Top->BodyComplete;
294 void setBodyComplete() {
295 getTopOfStack().BodyComplete =
true;
298 bool isForceVarCapturing()
const {
return ForceCapturing; }
299 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
301 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
302 ForceCaptureByReferenceInTargetExecutable =
V;
304 bool isForceCaptureByReferenceInTargetExecutable()
const {
305 return ForceCaptureByReferenceInTargetExecutable;
310 assert(!IgnoredStackElements &&
311 "cannot change stack while ignoring elements");
313 Stack.back().second != CurrentNonCapturingFunctionScope)
314 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
315 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
316 Stack.back().first.back().DefaultAttrLoc = Loc;
320 assert(!IgnoredStackElements &&
321 "cannot change stack while ignoring elements");
322 assert(!Stack.back().first.empty() &&
323 "Data-sharing attributes stack is empty!");
324 Stack.back().first.pop_back();
329 class ParentDirectiveScope {
333 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
334 : Self(Self), Active(
false) {
338 ~ParentDirectiveScope() { disable(); }
341 --Self.IgnoredStackElements;
347 ++Self.IgnoredStackElements;
356 "Expected loop-based directive.");
357 getTopOfStack().LoopStart =
true;
362 "Expected loop-based directive.");
363 getTopOfStack().LoopStart =
false;
366 bool isLoopStarted()
const {
368 "Expected loop-based directive.");
369 return !getTopOfStack().LoopStart;
372 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
373 getTopOfStack().PossiblyLoopCounter =
377 const Decl *getPossiblyLoopCunter()
const {
378 return getTopOfStack().PossiblyLoopCounter;
381 void pushFunction() {
382 assert(!IgnoredStackElements &&
383 "cannot change stack while ignoring elements");
385 assert(!isa<CapturingScopeInfo>(CurFnScope));
386 CurrentNonCapturingFunctionScope = CurFnScope;
390 assert(!IgnoredStackElements &&
391 "cannot change stack while ignoring elements");
392 if (!Stack.empty() && Stack.back().second == OldFSI) {
393 assert(Stack.back().first.empty());
396 CurrentNonCapturingFunctionScope =
nullptr;
398 if (!isa<CapturingScopeInfo>(FSI)) {
399 CurrentNonCapturingFunctionScope = FSI;
408 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
411 if (I != Criticals.end())
413 return std::make_pair(
nullptr, llvm::APSInt());
426 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
431 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
434 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
447 const Expr *ReductionRef);
453 Expr *&TaskgroupDescriptor)
const;
458 const Expr *&ReductionRef,
459 Expr *&TaskgroupDescriptor)
const;
461 Expr *getTaskgroupReductionRef()
const {
462 assert(getTopOfStack().
Directive == OMPD_taskgroup &&
463 "taskgroup reference expression requested for non taskgroup " 465 return getTopOfStack().TaskgroupReductionRef;
469 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
470 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
471 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
477 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
479 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
486 bool FromParent)
const;
494 bool FromParent)
const;
500 unsigned Level,
bool NotLastprivate =
false)
const;
504 bool hasExplicitDirective(
506 unsigned Level)
const;
510 const llvm::function_ref<
bool(
513 bool FromParent)
const;
517 const SharingMapTy *Top = getTopOfStackOrNull();
522 assert(!isStackEmpty() &&
"No directive at specified level.");
523 return getStackElemAtLevel(Level).Directive;
527 const SharingMapTy *
Parent = getSecondOnStackOrNull();
533 RequiresDecls.push_back(RD);
537 template <
typename ClauseType>
538 bool hasRequiresDeclWithClause() {
541 return isa<ClauseType>(
C);
548 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList)
const {
549 bool IsDuplicate =
false;
552 for (
const OMPClause *CPrev : D->clauselists()) {
553 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
554 SemaRef.
Diag(CNew->getBeginLoc(),
555 diag::err_omp_requires_clause_redeclaration)
557 SemaRef.
Diag(CPrev->getBeginLoc(),
558 diag::note_omp_requires_previous_clause)
570 TargetLocations.push_back(LocStart);
574 ArrayRef<SourceLocation> getEncounteredTargetLocs()
const {
575 return TargetLocations;
580 getTopOfStack().DefaultAttr = DSA_none;
581 getTopOfStack().DefaultAttrLoc = Loc;
585 getTopOfStack().DefaultAttr = DSA_shared;
586 getTopOfStack().DefaultAttrLoc = Loc;
590 getTopOfStack().DefaultMapAttr = DMA_tofrom_scalar;
591 getTopOfStack().DefaultMapAttrLoc = Loc;
595 return isStackEmpty() ? DSA_unspecified
596 : getTopOfStack().DefaultAttr;
600 : getTopOfStack().DefaultAttrLoc;
603 return isStackEmpty() ? DMA_unspecified
604 : getTopOfStack().DefaultMapAttr;
607 return getStackElemAtLevel(Level).DefaultMapAttr;
611 : getTopOfStack().DefaultMapAttrLoc;
615 bool isThreadPrivate(
VarDecl *D) {
616 const DSAVarData DVar = getTopDSA(D,
false);
621 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
624 getTopOfStack().OrderedRegion.emplace(Param, Clause);
626 getTopOfStack().OrderedRegion.reset();
630 bool isOrderedRegion()
const {
631 if (
const SharingMapTy *Top = getTopOfStackOrNull())
632 return Top->OrderedRegion.hasValue();
636 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
637 if (
const SharingMapTy *Top = getTopOfStackOrNull())
638 if (Top->OrderedRegion.hasValue())
639 return Top->OrderedRegion.getValue();
640 return std::make_pair(
nullptr,
nullptr);
644 bool isParentOrderedRegion()
const {
645 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
646 return Parent->OrderedRegion.hasValue();
650 std::pair<const Expr *, OMPOrderedClause *>
651 getParentOrderedRegionParam()
const {
652 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
653 if (
Parent->OrderedRegion.hasValue())
654 return Parent->OrderedRegion.getValue();
655 return std::make_pair(
nullptr,
nullptr);
658 void setNowaitRegion(
bool IsNowait =
true) {
659 getTopOfStack().NowaitRegion = IsNowait;
663 bool isParentNowaitRegion()
const {
664 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
665 return Parent->NowaitRegion;
669 void setParentCancelRegion(
bool Cancel =
true) {
670 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
671 Parent->CancelRegion |= Cancel;
674 bool isCancelRegion()
const {
675 const SharingMapTy *Top = getTopOfStackOrNull();
676 return Top ? Top->CancelRegion :
false;
680 void setAssociatedLoops(
unsigned Val) {
681 getTopOfStack().AssociatedLoops = Val;
683 getTopOfStack().HasMutipleLoops =
true;
686 unsigned getAssociatedLoops()
const {
687 const SharingMapTy *Top = getTopOfStackOrNull();
688 return Top ? Top->AssociatedLoops : 0;
691 bool hasMutipleLoops()
const {
692 const SharingMapTy *Top = getTopOfStackOrNull();
693 return Top ? Top->HasMutipleLoops :
false;
699 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
700 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
703 bool hasInnerTeamsRegion()
const {
704 return getInnerTeamsRegionLoc().
isValid();
708 const SharingMapTy *Top = getTopOfStackOrNull();
712 Scope *getCurScope()
const {
713 const SharingMapTy *Top = getTopOfStackOrNull();
714 return Top ? Top->CurScope :
nullptr;
717 const SharingMapTy *Top = getTopOfStackOrNull();
723 bool checkMappableExprComponentListsForDecl(
724 const ValueDecl *VD,
bool CurrentRegionOnly,
725 const llvm::function_ref<
737 if (CurrentRegionOnly)
742 for (; SI != SE; ++SI) {
743 auto MI = SI->MappedExprComponents.find(VD);
744 if (MI != SI->MappedExprComponents.end())
746 MI->second.Components)
747 if (Check(L, MI->second.Kind))
755 bool checkMappableExprComponentListsForDeclAtLevel(
757 const llvm::function_ref<
761 if (getStackSize() <= Level)
764 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
765 auto MI = StackElem.MappedExprComponents.find(VD);
766 if (MI != StackElem.MappedExprComponents.end())
768 MI->second.Components)
769 if (Check(L, MI->second.Kind))
776 void addMappableExpressionComponents(
780 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
782 MEC.Components.resize(MEC.Components.size() + 1);
783 MEC.Components.back().append(Components.begin(), Components.end());
784 MEC.Kind = WhereFoundClauseKind;
787 unsigned getNestingLevel()
const {
788 assert(!isStackEmpty());
789 return getStackSize() - 1;
792 const OperatorOffsetTy &OpsOffs) {
793 SharingMapTy *
Parent = getSecondOnStackOrNull();
795 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
797 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
798 getDoacrossDependClauses()
const {
799 const SharingMapTy &StackElem = getTopOfStack();
801 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
802 return llvm::make_range(Ref.begin(), Ref.end());
804 return llvm::make_range(StackElem.DoacrossDepends.end(),
805 StackElem.DoacrossDepends.end());
809 void addMappedClassesQualTypes(
QualType QT) {
810 SharingMapTy &StackElem = getTopOfStack();
811 StackElem.MappedClassesQualTypes.insert(QT);
815 bool isClassPreviouslyMapped(
QualType QT)
const {
816 const SharingMapTy &StackElem = getTopOfStack();
817 return StackElem.MappedClassesQualTypes.count(QT) != 0;
821 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
822 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
823 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
824 "Expected declare target link global.");
825 for (
auto &Elem : *
this) {
827 Elem.DeclareTargetLinkVarDecls.push_back(E);
835 ArrayRef<DeclRefExpr *> getLinkGlobals()
const {
837 "Expected target executable directive.");
838 return getTopOfStack().DeclareTargetLinkVarDecls;
854 if (
const auto *FE = dyn_cast<FullExpr>(E))
855 E = FE->getSubExpr();
857 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
858 E = MTE->GetTemporaryExpr();
860 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
861 E = Binder->getSubExpr();
863 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
864 E = ICE->getSubExprAsWritten();
873 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
874 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
875 D = ME->getMemberDecl();
876 const auto *VD = dyn_cast<
VarDecl>(D);
883 FD = FD->getCanonicalDecl();
894 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
897 auto *VD = dyn_cast<
VarDecl>(D);
906 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
907 DVar.CKind = OMPC_shared;
913 if (VD && VD->hasGlobalStorage())
914 DVar.CKind = OMPC_shared;
918 DVar.CKind = OMPC_shared;
927 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
928 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
929 DVar.CKind = OMPC_private;
933 DVar.DKind = Iter->Directive;
936 if (Iter->SharingMap.count(D)) {
937 const DSAInfo &Data = Iter->SharingMap.lookup(D);
938 DVar.RefExpr = Data.RefExpr.getPointer();
939 DVar.PrivateCopy = Data.PrivateCopy;
940 DVar.CKind = Data.Attributes;
941 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
949 switch (Iter->DefaultAttr) {
951 DVar.CKind = OMPC_shared;
952 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
956 case DSA_unspecified:
961 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
964 DVar.CKind = OMPC_shared;
975 const_iterator I = Iter, E = end();
983 DVarTemp = getDSA(I, D);
984 if (DVarTemp.CKind != OMPC_shared) {
985 DVar.RefExpr =
nullptr;
986 DVar.CKind = OMPC_firstprivate;
989 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
991 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1000 return getDSA(++Iter, D);
1003 const Expr *DSAStackTy::addUniqueAligned(
const ValueDecl *D,
1004 const Expr *NewDE) {
1005 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1007 SharingMapTy &StackElem = getTopOfStack();
1008 auto It = StackElem.AlignedMap.find(D);
1009 if (It == StackElem.AlignedMap.end()) {
1010 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1011 StackElem.AlignedMap[D] = NewDE;
1014 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1019 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1021 SharingMapTy &StackElem = getTopOfStack();
1022 StackElem.LCVMap.try_emplace(
1023 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1026 const DSAStackTy::LCDeclInfo
1027 DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1028 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1030 const SharingMapTy &StackElem = getTopOfStack();
1031 auto It = StackElem.LCVMap.find(D);
1032 if (It != StackElem.LCVMap.end())
1034 return {0,
nullptr};
1037 const DSAStackTy::LCDeclInfo
1038 DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1039 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1040 assert(Parent &&
"Data-sharing attributes stack is empty");
1042 auto It = Parent->LCVMap.find(D);
1043 if (It != Parent->LCVMap.end())
1045 return {0,
nullptr};
1048 const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1049 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1050 assert(Parent &&
"Data-sharing attributes stack is empty");
1051 if (Parent->LCVMap.size() < I)
1053 for (
const auto &Pair : Parent->LCVMap)
1054 if (Pair.second.first == I)
1063 DSAInfo &Data = Threadprivates[D];
1064 Data.Attributes = A;
1065 Data.RefExpr.setPointer(E);
1066 Data.PrivateCopy =
nullptr;
1068 DSAInfo &Data = getTopOfStack().SharingMap[D];
1069 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
1070 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1071 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1072 (isLoopControlVariable(D).first && A == OMPC_private));
1073 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1074 Data.RefExpr.setInt(
true);
1077 const bool IsLastprivate =
1078 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1079 Data.Attributes = A;
1080 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1081 Data.PrivateCopy = PrivateCopy;
1083 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1084 Data.Attributes = A;
1085 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1086 Data.PrivateCopy =
nullptr;
1093 StringRef Name,
const AttrVec *Attrs =
nullptr,
1108 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1115 bool RefersToCapture =
false) {
1126 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1128 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1129 "Additional reduction info may be specified only for reduction items.");
1130 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1131 assert(ReductionData.ReductionRange.isInvalid() &&
1132 getTopOfStack().Directive == OMPD_taskgroup &&
1133 "Additional reduction info may be specified only once for reduction " 1135 ReductionData.set(BOK, SR);
1136 Expr *&TaskgroupReductionRef =
1137 getTopOfStack().TaskgroupReductionRef;
1138 if (!TaskgroupReductionRef) {
1140 SemaRef.Context.VoidPtrTy,
".task_red.");
1141 TaskgroupReductionRef =
1147 const Expr *ReductionRef) {
1149 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1151 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1152 "Additional reduction info may be specified only for reduction items.");
1153 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1154 assert(ReductionData.ReductionRange.isInvalid() &&
1155 getTopOfStack().Directive == OMPD_taskgroup &&
1156 "Additional reduction info may be specified only once for reduction " 1158 ReductionData.set(ReductionRef, SR);
1159 Expr *&TaskgroupReductionRef =
1160 getTopOfStack().TaskgroupReductionRef;
1161 if (!TaskgroupReductionRef) {
1163 SemaRef.Context.VoidPtrTy,
".task_red.");
1164 TaskgroupReductionRef =
1169 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1171 Expr *&TaskgroupDescriptor)
const {
1173 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1174 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1175 const DSAInfo &Data = I->SharingMap.lookup(D);
1176 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1178 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1179 if (!ReductionData.ReductionOp ||
1180 ReductionData.ReductionOp.is<
const Expr *>())
1181 return DSAVarData();
1182 SR = ReductionData.ReductionRange;
1183 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1184 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1185 "expression for the descriptor is not " 1187 TaskgroupDescriptor = I->TaskgroupReductionRef;
1188 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1189 Data.PrivateCopy, I->DefaultAttrLoc);
1191 return DSAVarData();
1194 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1196 Expr *&TaskgroupDescriptor)
const {
1198 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1199 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1200 const DSAInfo &Data = I->SharingMap.lookup(D);
1201 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1203 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1204 if (!ReductionData.ReductionOp ||
1205 !ReductionData.ReductionOp.is<
const Expr *>())
1206 return DSAVarData();
1207 SR = ReductionData.ReductionRange;
1208 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1209 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1210 "expression for the descriptor is not " 1212 TaskgroupDescriptor = I->TaskgroupReductionRef;
1213 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1214 Data.PrivateCopy, I->DefaultAttrLoc);
1216 return DSAVarData();
1219 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1221 for (const_iterator E = end(); I != E; ++I) {
1222 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1224 Scope *TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
1225 Scope *CurScope = getCurScope();
1226 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1228 return CurScope != TopScope;
1235 bool AcceptIfMutable =
true,
1236 bool *IsClassType =
nullptr) {
1244 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1246 RD = CTD->getTemplatedDecl();
1249 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1256 bool AcceptIfMutable =
true,
1257 bool ListItemNotVar =
false) {
1261 unsigned Diag = ListItemNotVar
1262 ? diag::err_omp_const_list_item
1263 : IsClassType ? diag::err_omp_const_not_mutable_variable
1264 : diag::err_omp_const_variable;
1266 if (!ListItemNotVar && D) {
1271 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1279 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1284 auto *VD = dyn_cast<
VarDecl>(D);
1285 auto TI = Threadprivates.find(D);
1286 if (TI != Threadprivates.end()) {
1287 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1291 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1294 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1303 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1304 SemaRef.getLangOpts().OpenMPUseTLS &&
1305 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1307 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1314 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1315 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1316 !isLoopControlVariable(D).first) {
1317 const_iterator IterTarget =
1318 std::find_if(begin(), end(), [](
const SharingMapTy &Data) {
1321 if (IterTarget != end()) {
1322 const_iterator ParentIterTarget = IterTarget + 1;
1323 for (const_iterator Iter = begin();
1324 Iter != ParentIterTarget; ++Iter) {
1325 if (isOpenMPLocal(VD, Iter)) {
1333 if (!isClauseParsingMode() || IterTarget != begin()) {
1334 auto DSAIter = IterTarget->SharingMap.find(D);
1335 if (DSAIter != IterTarget->SharingMap.end() &&
1337 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1341 const_iterator
End = end();
1342 if (!SemaRef.isOpenMPCapturedByRef(
1346 IterTarget->ConstructLoc);
1365 if (VD && VD->isStaticDataMember()) {
1367 const_iterator I = begin();
1368 const_iterator EndI = end();
1369 if (FromParent && I != EndI)
1371 auto It = I->SharingMap.find(D);
1372 if (It != I->SharingMap.end()) {
1373 const DSAInfo &Data = It->getSecond();
1374 DVar.RefExpr = Data.RefExpr.getPointer();
1375 DVar.PrivateCopy = Data.PrivateCopy;
1376 DVar.CKind = Data.Attributes;
1377 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1378 DVar.DKind = I->Directive;
1382 DVar.CKind = OMPC_shared;
1389 if (SemaRef.LangOpts.OpenMP <= 31) {
1397 DSAVarData DVarTemp = hasInnermostDSA(
1400 return C == OMPC_firstprivate || C == OMPC_shared;
1402 MatchesAlways, FromParent);
1403 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1406 DVar.CKind = OMPC_shared;
1413 const_iterator I = begin();
1414 const_iterator EndI = end();
1415 if (FromParent && I != EndI)
1417 auto It = I->SharingMap.find(D);
1418 if (It != I->SharingMap.end()) {
1419 const DSAInfo &Data = It->getSecond();
1420 DVar.RefExpr = Data.RefExpr.getPointer();
1421 DVar.PrivateCopy = Data.PrivateCopy;
1422 DVar.CKind = Data.Attributes;
1423 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1424 DVar.DKind = I->Directive;
1430 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1431 bool FromParent)
const {
1432 if (isStackEmpty()) {
1434 return getDSA(I, D);
1437 const_iterator StartI = begin();
1438 const_iterator EndI = end();
1439 if (FromParent && StartI != EndI)
1441 return getDSA(StartI, D);
1444 const DSAStackTy::DSAVarData
1448 bool FromParent)
const {
1452 const_iterator I = begin();
1453 const_iterator EndI = end();
1454 if (FromParent && I != EndI)
1456 for (; I != EndI; ++I) {
1457 if (!DPred(I->Directive) &&
1458 !isImplicitOrExplicitTaskingRegion(I->Directive))
1460 const_iterator NewI = I;
1461 DSAVarData DVar = getDSA(NewI, D);
1462 if (I == NewI && CPred(DVar.CKind))
1468 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1471 bool FromParent)
const {
1475 const_iterator StartI = begin();
1476 const_iterator EndI = end();
1477 if (FromParent && StartI != EndI)
1479 if (StartI == EndI || !DPred(StartI->Directive))
1481 const_iterator NewI = StartI;
1482 DSAVarData DVar = getDSA(NewI, D);
1483 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1486 bool DSAStackTy::hasExplicitDSA(
1488 unsigned Level,
bool NotLastprivate)
const {
1489 if (getStackSize() <=
Level)
1492 const SharingMapTy &StackElem = getStackElemAtLevel(
Level);
1493 auto I = StackElem.SharingMap.find(D);
1494 if (I != StackElem.SharingMap.end() &&
1495 I->getSecond().RefExpr.getPointer() &&
1496 CPred(I->getSecond().Attributes) &&
1497 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1500 auto LI = StackElem.LCVMap.find(D);
1501 if (LI != StackElem.LCVMap.end())
1502 return CPred(OMPC_private);
1506 bool DSAStackTy::hasExplicitDirective(
1508 unsigned Level)
const {
1509 if (getStackSize() <= Level)
1511 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1512 return DPred(StackElem.Directive);
1515 bool DSAStackTy::hasDirective(
1519 bool FromParent)
const {
1521 size_t Skip = FromParent ? 2 : 1;
1522 for (const_iterator I = begin() +
std::min(Skip, getStackSize()), E = end();
1524 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1530 void Sema::InitDataSharingAttributesStack() {
1531 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1534 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1536 void Sema::pushOpenMPFunctionRegion() {
1546 "Expected OpenMP device compilation.");
1554 "Expected OpenMP device compilation.");
1559 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1570 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1571 "Expected OpenMP device compilation.");
1574 ? DeviceDiagBuilder::K_Deferred
1575 : DeviceDiagBuilder::K_Immediate,
1576 Loc, DiagID, getCurFunctionDecl(), *
this);
1580 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1581 "Expected OpenMP device compilation.");
1582 assert(Callee &&
"Callee may not be null.");
1591 DeviceCallGraph[Caller].insert({Callee, Loc});
1594 void Sema::checkOpenMPDeviceExpr(
const Expr *E) {
1595 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1596 "OpenMP device compilation mode is expected.");
1604 targetDiag(E->
getExprLoc(), diag::err_omp_unsupported_type)
1605 << static_cast<unsigned>(Context.
getTypeSize(Ty)) << Ty
1610 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1613 bool IsByRef =
true;
1674 if (Ty->isReferenceType())
1680 bool IsVariableUsedInMapClause =
false;
1681 bool IsVariableAssociatedWithSection =
false;
1683 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1685 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1692 if (WhereFoundClauseKind != OMPC_map)
1695 auto EI = MapExprComponents.rbegin();
1696 auto EE = MapExprComponents.rend();
1698 assert(EI != EE &&
"Invalid map expression!");
1700 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1701 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1707 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1708 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1709 isa<MemberExpr>(EI->getAssociatedExpression())) {
1710 IsVariableAssociatedWithSection =
true;
1719 if (IsVariableUsedInMapClause) {
1722 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1727 (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1728 !Ty->isAnyPointerType()) ||
1729 !Ty->isScalarType() ||
1730 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1736 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1744 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
1745 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1762 unsigned Sema::getOpenMPNestingLevel()
const {
1763 assert(getLangOpts().OpenMP);
1764 return DSAStack->getNestingLevel();
1769 !
DSAStack->isClauseParsingMode()) ||
1773 return isOpenMPTargetExecutionDirective(K);
1780 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1787 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1793 auto *VD = dyn_cast<
VarDecl>(D);
1794 if (VD && !VD->hasLocalStorage() &&
1795 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1796 if (isInOpenMPDeclareTargetContext()) {
1799 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1800 checkDeclIsAllowedInOpenMPTarget(
nullptr, VD);
1802 }
else if (isInOpenMPTargetExecutionDirective()) {
1806 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1812 if (CheckScopeInfo) {
1813 bool OpenMPFound =
false;
1814 for (
unsigned I = StopAt + 1; I > 0; --I) {
1816 if(!isa<CapturingScopeInfo>(FSI))
1818 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
1829 (!
DSAStack->isClauseParsingMode() ||
1831 auto &&Info =
DSAStack->isLoopControlVariable(D);
1833 (VD && VD->hasLocalStorage() &&
1834 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
1835 (VD &&
DSAStack->isForceVarCapturing()))
1836 return VD ? VD : Info.second;
1837 DSAStackTy::DSAVarData DVarPrivate =
1840 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1850 (VD &&
DSAStack->getDefaultDSA() == DSA_none))
1851 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1856 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
1857 unsigned Level)
const {
1860 FunctionScopesIndex -= Regions.size();
1864 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
1870 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1872 if (
DSAStack->getAssociatedLoops() > 0 &&
1874 DSAStack->resetPossibleLoopCounter(D);
1879 DSAStack->isLoopControlVariable(D).first) &&
1885 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
1886 if (
DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
1894 (
DSAStack->isClauseParsingMode() &&
1895 DSAStack->getClauseParsingMode() == OMPC_private) ||
1901 DSAStack->isTaskgroupReductionRef(D, Level));
1906 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1909 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
1910 const unsigned NewLevel = I - 1;
1913 if (isOpenMPPrivate(K)) {
1921 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1932 DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1933 DefaultMapAttributes::DMA_tofrom_scalar)
1934 OMPC = OMPC_firstprivate;
1939 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1943 unsigned Level)
const {
1944 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1947 const auto *VD = dyn_cast<
VarDecl>(D);
1953 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
1958 DSAStack->push(DKind, DirName, CurScope, Loc);
1959 PushExpressionEvaluationContext(
1960 ExpressionEvaluationContext::PotentiallyEvaluated);
1980 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1982 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
1984 for (
Expr *DE : Clause->varlists()) {
1985 if (DE->isValueDependent() || DE->isTypeDependent()) {
1986 PrivateCopies.push_back(
nullptr);
1989 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1990 auto *VD = cast<VarDecl>(DRE->getDecl());
1992 const DSAStackTy::DSAVarData DVar =
1994 if (DVar.CKind == OMPC_lastprivate) {
2001 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
2002 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr, DRE);
2003 ActOnUninitializedDecl(VDPrivate);
2005 PrivateCopies.push_back(
nullptr);
2009 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2013 PrivateCopies.push_back(
nullptr);
2016 Clause->setPrivateCopies(PrivateCopies);
2020 if (!CurContext->isDependentContext())
2025 DiscardCleanupsInEvaluationContext();
2026 PopExpressionEvaluationContext();
2030 Expr *NumIterations,
Sema &SemaRef,
2031 Scope *S, DSAStackTy *Stack);
2040 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2041 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2043 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2044 return VD->hasGlobalStorage() &&
2051 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2052 return llvm::make_unique<VarDeclFilterCCC>(*this);
2062 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2063 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2065 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
2066 isa<FunctionDecl>(ND))) {
2073 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2074 return llvm::make_unique<VarOrFuncDeclFilterCCC>(*this);
2085 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
2092 VarDeclFilterCCC CCC(*
this);
2094 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr, CCC,
2095 CTK_ErrorRecovery)) {
2096 diagnoseTypo(Corrected,
2097 PDiag(Lookup.
empty()
2098 ? diag::err_undeclared_var_use_suggest
2099 : diag::err_omp_expected_var_arg_suggest)
2101 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
2104 : diag::err_omp_expected_var_arg)
2118 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
2123 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2134 !getCurLexicalContext()->isTranslationUnit()) {
2140 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2155 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2164 (!getCurLexicalContext()->isFileContext() ||
2165 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
2171 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2179 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2185 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2193 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
2211 CurContext->addDecl(D);
2218 class LocalVarRefChecker final
2224 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2225 if (VD->hasLocalStorage()) {
2227 diag::err_omp_local_var_in_threadprivate_init)
2229 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2230 << VD << VD->getSourceRange();
2236 bool VisitStmt(
const Stmt *S) {
2238 if (Child && Visit(Child))
2243 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
2250 for (
Expr *RefExpr : VarList) {
2251 auto *DE = cast<DeclRefExpr>(RefExpr);
2252 auto *VD = cast<VarDecl>(DE->getDecl());
2256 VD->setReferenced();
2257 VD->markUsed(Context);
2268 if (RequireCompleteType(ILoc, VD->getType(),
2269 diag::err_omp_threadprivate_incomplete_type)) {
2275 if (VD->getType()->isReferenceType()) {
2276 Diag(ILoc, diag::err_omp_ref_type_arg)
2280 Diag(VD->getLocation(),
2281 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2289 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2290 getLangOpts().OpenMPUseTLS &&
2291 getASTContext().getTargetInfo().isTLSSupported())) ||
2292 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2293 !VD->isLocalVarDecl())) {
2294 Diag(ILoc, diag::err_omp_var_thread_local)
2298 Diag(VD->getLocation(),
2299 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2306 if (
const Expr *Init = VD->getAnyInitializer()) {
2307 LocalVarRefChecker Checker(*
this);
2308 if (Checker.Visit(Init))
2312 Vars.push_back(RefExpr);
2314 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2317 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2320 if (!Vars.empty()) {
2328 static OMPAllocateDeclAttr::AllocatorTypeTy
2331 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2335 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2336 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2338 for (
int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2339 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2340 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
2341 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2342 llvm::FoldingSetNodeID AEId, DAEId;
2345 if (AEId == DAEId) {
2346 AllocatorKindRes = AllocatorKind;
2350 return AllocatorKindRes;
2355 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
2356 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
2358 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
2359 Expr *PrevAllocator = A->getAllocator();
2360 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2362 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2363 if (AllocatorsMatch &&
2364 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2365 Allocator && PrevAllocator) {
2368 llvm::FoldingSetNodeID AEId, PAEId;
2371 AllocatorsMatch = AEId == PAEId;
2373 if (!AllocatorsMatch) {
2375 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2379 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2381 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
2389 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2391 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2392 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2393 << (Allocator ? 1 : 0) << AllocatorStream.str()
2394 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2396 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2397 << PrevAllocatorRange;
2405 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2407 if (VD->
hasAttr<OMPAllocateDeclAttr>())
2414 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
2418 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2424 assert(Clauses.size() <= 1 &&
"Expected at most one clause.");
2425 Expr *Allocator =
nullptr;
2426 if (Clauses.empty()) {
2431 if (LangOpts.OpenMPIsDevice &&
2433 targetDiag(Loc, diag::err_expected_allocator_clause);
2435 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2437 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2440 for (
Expr *RefExpr : VarList) {
2441 auto *DE = cast<DeclRefExpr>(RefExpr);
2442 auto *VD = cast<VarDecl>(DE->getDecl());
2446 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2447 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2448 !VD->isLocalVarDecl()))
2454 AllocatorKind, Allocator))
2461 if (Allocator && VD->hasGlobalStorage()) {
2462 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2463 Diag(Allocator->getExprLoc(),
2464 diag::err_omp_expected_predefined_allocator)
2465 << Allocator->getSourceRange();
2466 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2468 Diag(VD->getLocation(),
2469 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2475 Vars.push_back(RefExpr);
2477 DE->getSourceRange());
2482 Owner = getCurLexicalContext();
2493 if (!CurContext->isFileContext()) {
2494 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
2496 D = CheckOMPRequiresDecl(Loc, ClauseList);
2498 CurContext->addDecl(D);
2511 DSAStack->getEncounteredTargetLocs();
2512 if (!TargetLocations.empty()) {
2513 for (
const OMPClause *CNew : ClauseList) {
2515 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2516 isa<OMPUnifiedAddressClause>(CNew) ||
2517 isa<OMPReverseOffloadClause>(CNew) ||
2518 isa<OMPDynamicAllocatorsClause>(CNew)) {
2519 Diag(Loc, diag::err_omp_target_before_requires)
2522 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2528 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
2536 const DSAStackTy::DSAVarData &DVar,
2537 bool IsLoopIterVar =
false) {
2539 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2544 PDSA_StaticMemberShared,
2545 PDSA_StaticLocalVarShared,
2546 PDSA_LoopIterVarPrivate,
2547 PDSA_LoopIterVarLinear,
2548 PDSA_LoopIterVarLastprivate,
2549 PDSA_ConstVarShared,
2550 PDSA_GlobalVarShared,
2551 PDSA_TaskVarFirstprivate,
2552 PDSA_LocalVarPrivate,
2554 } Reason = PDSA_Implicit;
2555 bool ReportHint =
false;
2557 auto *VD = dyn_cast<
VarDecl>(D);
2558 if (IsLoopIterVar) {
2559 if (DVar.CKind == OMPC_private)
2560 Reason = PDSA_LoopIterVarPrivate;
2561 else if (DVar.CKind == OMPC_lastprivate)
2562 Reason = PDSA_LoopIterVarLastprivate;
2564 Reason = PDSA_LoopIterVarLinear;
2566 DVar.CKind == OMPC_firstprivate) {
2567 Reason = PDSA_TaskVarFirstprivate;
2568 ReportLoc = DVar.ImplicitDSALoc;
2569 }
else if (VD && VD->isStaticLocal())
2570 Reason = PDSA_StaticLocalVarShared;
2571 else if (VD && VD->isStaticDataMember())
2572 Reason = PDSA_StaticMemberShared;
2573 else if (VD && VD->isFileVarDecl())
2574 Reason = PDSA_GlobalVarShared;
2576 Reason = PDSA_ConstVarShared;
2577 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2579 Reason = PDSA_LocalVarPrivate;
2581 if (Reason != PDSA_Implicit) {
2582 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2583 << Reason << ReportHint
2585 }
else if (DVar.ImplicitDSALoc.isValid()) {
2586 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2592 class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
2595 bool ErrorFound =
false;
2600 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2614 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2617 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2618 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2619 Visit(CED->getInit());
2622 }
else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2626 VD = VD->getCanonicalDecl();
2631 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
2633 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2638 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2641 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2650 if (DVar.CKind ==
OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2651 isImplicitOrExplicitTaskingRegion(DKind) &&
2652 VarsWithInheritedDSA.count(VD) == 0) {
2653 VarsWithInheritedDSA[VD] = E;
2658 !Stack->isLoopControlVariable(VD).first) {
2659 if (!Stack->checkMappableExprComponentListsForDecl(
2666 return StackComponents.size() == 1 ||
2668 std::next(StackComponents.rbegin()),
2669 StackComponents.rend(),
2670 [](const OMPClauseMappableExprCommon::
2671 MappableComponent &MC) {
2672 return MC.getAssociatedDeclaration() ==
2674 (isa<OMPArraySectionExpr>(
2675 MC.getAssociatedExpression()) ||
2676 isa<ArraySubscriptExpr>(
2677 MC.getAssociatedExpression()));
2680 bool IsFirstprivate =
false;
2682 if (
const auto *RD =
2683 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2684 IsFirstprivate = RD->isLambda();
2687 (VD->getType().getNonReferenceType()->isScalarType() &&
2688 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2690 ImplicitFirstprivate.emplace_back(E);
2692 ImplicitMap.emplace_back(E);
2701 DVar = Stack->hasInnermostDSA(
2710 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2716 DVar = Stack->getImplicitDSA(VD,
false);
2718 !Stack->isLoopControlVariable(VD).first) {
2719 ImplicitFirstprivate.push_back(E);
2726 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2727 Stack->addToParentTargetRegionLinkGlobals(E);
2741 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
2744 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2748 !Stack->isLoopControlVariable(FD).first &&
2749 !Stack->checkMappableExprComponentListsForDecl(
2754 return isa<CXXThisExpr>(
2756 StackComponents.back().getAssociatedExpression())
2763 if (FD->isBitField())
2768 if (Stack->isClassPreviouslyMapped(TE->getType()))
2771 ImplicitMap.emplace_back(E);
2780 DVar = Stack->hasInnermostDSA(
2789 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
2795 DVar = Stack->getImplicitDSA(FD,
false);
2797 !Stack->isLoopControlVariable(FD).first) {
2803 ImplicitFirstprivate.push_back(E);
2812 const auto *VD = cast<ValueDecl>(
2813 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2814 if (!Stack->checkMappableExprComponentListsForDecl(
2820 auto CCI = CurComponents.rbegin();
2821 auto CCE = CurComponents.rend();
2822 for (const auto &SC : llvm::reverse(StackComponents)) {
2824 if (CCI->getAssociatedExpression()->getStmtClass() !=
2825 SC.getAssociatedExpression()->getStmtClass())
2826 if (!(isa<OMPArraySectionExpr>(
2827 SC.getAssociatedExpression()) &&
2828 isa<ArraySubscriptExpr>(
2829 CCI->getAssociatedExpression())))
2832 const Decl *CCD = CCI->getAssociatedDeclaration();
2833 const Decl *SCD = SC.getAssociatedDeclaration();
2834 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2835 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2838 std::advance(CCI, 1);
2856 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
2858 for (
Stmt *CC :
C->children()) {
2865 VisitSubCaptures(S);
2867 void VisitStmt(
Stmt *S) {
2879 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
2881 VarDecl *VD = Cap.getCapturedVar();
2885 Stack->checkMappableExprComponentListsForDecl(
2892 Cap.getLocation(),
true);
2896 bool isErrorFound()
const {
return ErrorFound; }
2897 ArrayRef<Expr *> getImplicitFirstprivate()
const {
2898 return ImplicitFirstprivate;
2900 ArrayRef<Expr *> getImplicitMap()
const {
return ImplicitMap; }
2902 return VarsWithInheritedDSA;
2906 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
2919 case OMPD_parallel_for:
2920 case OMPD_parallel_for_simd:
2921 case OMPD_parallel_sections:
2923 case OMPD_teams_distribute:
2924 case OMPD_teams_distribute_simd: {
2929 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2930 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2931 std::make_pair(StringRef(),
QualType())
2937 case OMPD_target_teams:
2938 case OMPD_target_parallel:
2939 case OMPD_target_parallel_for:
2940 case OMPD_target_parallel_for_simd:
2941 case OMPD_target_teams_distribute:
2942 case OMPD_target_teams_distribute_simd: {
2952 std::make_pair(
".global_tid.", KmpInt32Ty),
2953 std::make_pair(
".part_id.", KmpInt32PtrTy),
2954 std::make_pair(
".privates.", VoidPtrTy),
2959 std::make_pair(StringRef(),
QualType())
2965 getCurCapturedRegion()->TheCapturedDecl->addAttr(
2966 AlwaysInlineAttr::CreateImplicit(
2967 Context, AlwaysInlineAttr::Keyword_forceinline));
2969 std::make_pair(StringRef(),
QualType())
2975 std::make_pair(
".global_tid.", KmpInt32PtrTy),
2976 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
2977 std::make_pair(StringRef(),
QualType())
2982 ParamsTeamsOrParallel);
2986 case OMPD_target_simd: {
2996 std::make_pair(
".global_tid.", KmpInt32Ty),
2997 std::make_pair(
".part_id.", KmpInt32PtrTy),
2998 std::make_pair(
".privates.", VoidPtrTy),
3003 std::make_pair(StringRef(),
QualType())
3009 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3010 AlwaysInlineAttr::CreateImplicit(
3011 Context, AlwaysInlineAttr::Keyword_forceinline));
3013 std::make_pair(StringRef(),
QualType()));
3024 case OMPD_taskgroup:
3025 case OMPD_distribute:
3026 case OMPD_distribute_simd:
3029 case OMPD_target_data: {
3031 std::make_pair(StringRef(),
QualType())
3047 std::make_pair(
".global_tid.", KmpInt32Ty),
3048 std::make_pair(
".part_id.", KmpInt32PtrTy),
3049 std::make_pair(
".privates.", VoidPtrTy),
3054 std::make_pair(StringRef(),
QualType())
3060 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3061 AlwaysInlineAttr::CreateImplicit(
3062 Context, AlwaysInlineAttr::Keyword_forceinline));
3066 case OMPD_taskloop_simd: {
3084 std::make_pair(
".global_tid.", KmpInt32Ty),
3085 std::make_pair(
".part_id.", KmpInt32PtrTy),
3086 std::make_pair(
".privates.", VoidPtrTy),
3091 std::make_pair(
".lb.", KmpUInt64Ty),
3092 std::make_pair(
".ub.", KmpUInt64Ty),
3093 std::make_pair(
".st.", KmpInt64Ty),
3094 std::make_pair(
".liter.", KmpInt32Ty),
3095 std::make_pair(
".reductions.", VoidPtrTy),
3096 std::make_pair(StringRef(),
QualType())
3102 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3103 AlwaysInlineAttr::CreateImplicit(
3104 Context, AlwaysInlineAttr::Keyword_forceinline));
3107 case OMPD_distribute_parallel_for_simd:
3108 case OMPD_distribute_parallel_for: {
3113 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3114 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3117 std::make_pair(StringRef(),
QualType())
3123 case OMPD_target_teams_distribute_parallel_for:
3124 case OMPD_target_teams_distribute_parallel_for_simd: {
3135 std::make_pair(
".global_tid.", KmpInt32Ty),
3136 std::make_pair(
".part_id.", KmpInt32PtrTy),
3137 std::make_pair(
".privates.", VoidPtrTy),
3142 std::make_pair(StringRef(),
QualType())
3148 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3149 AlwaysInlineAttr::CreateImplicit(
3150 Context, AlwaysInlineAttr::Keyword_forceinline));
3152 std::make_pair(StringRef(),
QualType())
3159 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3160 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3161 std::make_pair(StringRef(),
QualType())
3168 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3169 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3172 std::make_pair(StringRef(),
QualType())
3181 case OMPD_teams_distribute_parallel_for:
3182 case OMPD_teams_distribute_parallel_for_simd: {
3188 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3189 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3190 std::make_pair(StringRef(),
QualType())
3197 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3198 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3201 std::make_pair(StringRef(),
QualType())
3209 case OMPD_target_update:
3210 case OMPD_target_enter_data:
3211 case OMPD_target_exit_data: {
3221 std::make_pair(
".global_tid.", KmpInt32Ty),
3222 std::make_pair(
".part_id.", KmpInt32PtrTy),
3223 std::make_pair(
".privates.", VoidPtrTy),
3228 std::make_pair(StringRef(),
QualType())
3234 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3235 AlwaysInlineAttr::CreateImplicit(
3236 Context, AlwaysInlineAttr::Keyword_forceinline));
3239 case OMPD_threadprivate:
3241 case OMPD_taskyield:
3244 case OMPD_cancellation_point:
3247 case OMPD_declare_reduction:
3248 case OMPD_declare_mapper:
3249 case OMPD_declare_simd:
3250 case OMPD_declare_target:
3251 case OMPD_end_declare_target:
3253 llvm_unreachable(
"OpenMP Directive is not allowed");
3255 llvm_unreachable(
"Unknown OpenMP directive");
3262 return CaptureRegions.size();
3266 Expr *CaptureExpr,
bool WithInit,
3267 bool AsExpression) {
3268 assert(CaptureExpr);
3288 CED->
addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3298 CD = cast<OMPCapturedExprDecl>(VD);
3320 if (!Res.isUsable())
3335 class CaptureRegionUnwinderRAII {
3342 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
3344 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3345 ~CaptureRegionUnwinderRAII() {
3348 while (--ThisCaptureLevel >= 0)
3358 if (!CurContext->isDependentContext() &&
3361 DSAStack->getCurrentDirective()))) {
3366 bool SavedForceCaptureByReferenceInTargetExecutable =
3367 DSAStack->isForceCaptureByReferenceInTargetExecutable();
3368 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3370 if (RD->isLambda()) {
3371 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3373 RD->getCaptureFields(Captures, ThisCapture);
3376 VarDecl *VD = LC.getCapturedVar();
3380 MarkVariableReferenced(LC.getLocation(), VD);
3381 }
else if (LC.getCaptureKind() ==
LCK_This) {
3382 QualType ThisTy = getCurrentThisType();
3385 CheckCXXThisCapture(LC.getLocation());
3389 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3390 SavedForceCaptureByReferenceInTargetExecutable);
3397 bool ErrorFound =
false;
3398 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3399 *
this, ErrorFound,
DSAStack->getCurrentDirective());
3417 auto *IRC = cast<OMPInReductionClause>(Clause);
3418 for (
Expr *E : IRC->taskgroup_descriptors())
3420 MarkDeclarationsReferencedInExpr(E);
3424 (getLangOpts().OpenMPUseTLS &&
3425 getASTContext().getTargetInfo().isTLSSupported() &&
3430 if (
auto *E = cast_or_null<Expr>(VarRef)) {
3431 MarkDeclarationsReferencedInExpr(E);
3434 DSAStack->setForceVarCapturing(
false);
3435 }
else if (CaptureRegions.size() > 1 ||
3440 if (
Expr *E =
C->getPostUpdateExpr())
3441 MarkDeclarationsReferencedInExpr(E);
3445 SC = cast<OMPScheduleClause>(Clause);
3447 OC = cast<OMPOrderedClause>(Clause);
3449 LCs.push_back(cast<OMPLinearClause>(Clause));
3457 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3462 diag::err_omp_schedule_nonmonotonic_ordered)
3463 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3466 if (!LCs.empty() && OC && OC->getNumForLoops()) {
3468 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
3469 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3475 OC->getNumForLoops()) {
3476 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3484 unsigned CompletedRegions = 0;
3497 if (CaptureRegion == ThisCaptureRegion ||
3499 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
3500 for (
Decl *D : DS->decls())
3501 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
3506 if (++CompletedRegions == CaptureRegions.size())
3508 SR = ActOnCapturedRegionEnd(SR.
get());
3517 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3520 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3521 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3524 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3534 if (Stack->getCurScope()) {
3537 bool NestingProhibited =
false;
3538 bool CloseNesting =
true;
3539 bool OrphanSeen =
false;
3542 ShouldBeInParallelRegion,
3543 ShouldBeInOrderedRegion,
3544 ShouldBeInTargetRegion,
3545 ShouldBeInTeamsRegion
3546 } Recommend = NoRecommend;
3556 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
3557 ? diag::err_omp_prohibited_region_simd
3558 : diag::warn_omp_nesting_simd);
3559 return CurrentRegion != OMPD_simd;
3561 if (ParentRegion == OMPD_atomic) {
3564 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3567 if (CurrentRegion == OMPD_section) {
3572 if (ParentRegion != OMPD_sections &&
3573 ParentRegion != OMPD_parallel_sections) {
3574 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3586 CurrentRegion != OMPD_cancellation_point &&
3587 CurrentRegion != OMPD_cancel)
3589 if (CurrentRegion == OMPD_cancellation_point ||
3590 CurrentRegion == OMPD_cancel) {
3603 !((CancelRegion == OMPD_parallel &&
3604 (ParentRegion == OMPD_parallel ||
3605 ParentRegion == OMPD_target_parallel)) ||
3606 (CancelRegion == OMPD_for &&
3607 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3608 ParentRegion == OMPD_target_parallel_for ||
3609 ParentRegion == OMPD_distribute_parallel_for ||
3610 ParentRegion == OMPD_teams_distribute_parallel_for ||
3611 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3612 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3613 (CancelRegion == OMPD_sections &&
3614 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3615 ParentRegion == OMPD_parallel_sections)));
3617 }
else if (CurrentRegion == OMPD_master) {
3623 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
3629 bool DeadLock = Stack->hasDirective(
3633 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
3634 PreviousCriticalLoc = Loc;
3641 SemaRef.
Diag(StartLoc,
3642 diag::err_omp_prohibited_region_critical_same_name)
3644 if (PreviousCriticalLoc.
isValid())
3645 SemaRef.
Diag(PreviousCriticalLoc,
3646 diag::note_omp_previous_critical_region);
3649 }
else if (CurrentRegion == OMPD_barrier) {
3655 ParentRegion == OMPD_master ||
3656 ParentRegion == OMPD_critical ||
3657 ParentRegion == OMPD_ordered;
3666 ParentRegion == OMPD_master ||
3667 ParentRegion == OMPD_critical ||
3668 ParentRegion == OMPD_ordered;
3669 Recommend = ShouldBeInParallelRegion;
3670 }
else if (CurrentRegion == OMPD_ordered) {
3679 NestingProhibited = ParentRegion == OMPD_critical ||
3682 Stack->isParentOrderedRegion());
3683 Recommend = ShouldBeInOrderedRegion;
3688 NestingProhibited = ParentRegion != OMPD_target;
3690 Recommend = ShouldBeInTargetRegion;
3692 if (!NestingProhibited &&
3695 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3702 Recommend = ShouldBeInParallelRegion;
3704 if (!NestingProhibited &&
3710 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3711 Recommend = ShouldBeInTeamsRegion;
3713 if (!NestingProhibited &&
3720 NestingProhibited = Stack->hasDirective(
3724 OffendingRegion = K;
3730 CloseNesting =
false;
3732 if (NestingProhibited) {
3734 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3737 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
3748 ArrayRef<OMPClause *> Clauses,
3749 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3750 bool ErrorFound =
false;
3751 unsigned NamedModifiersNumber = 0;
3756 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
3760 if (FoundNameModifiers[CurNM]) {
3761 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
3766 NameModifierLoc.push_back(IC->getNameModifierLoc());
3767 ++NamedModifiersNumber;
3769 FoundNameModifiers[CurNM] = IC;
3776 bool MatchFound =
false;
3777 for (
auto NM : AllowedNameModifiers) {
3784 S.
Diag(IC->getNameModifierLoc(),
3785 diag::err_omp_wrong_if_directive_name_modifier)
3793 if (FoundNameModifiers[
OMPD_unknown] && NamedModifiersNumber > 0) {
3794 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3796 diag::err_omp_no_more_if_clause);
3799 std::string Sep(
", ");
3800 unsigned AllowedCnt = 0;
3801 unsigned TotalAllowedNum =
3802 AllowedNameModifiers.size() - NamedModifiersNumber;
3803 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
3806 if (!FoundNameModifiers[NM]) {
3810 if (AllowedCnt + 2 == TotalAllowedNum)
3812 else if (AllowedCnt + 1 != TotalAllowedNum)
3818 diag::err_omp_unnamed_if_clause)
3819 << (TotalAllowedNum > 1) << Values;
3822 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
3829 static std::pair<ValueDecl *, bool>
3831 SourceRange &ERange,
bool AllowArraySection =
false) {
3834 return std::make_pair(
nullptr,
true);
3846 } IsArrayExpr = NoArrayExpr;
3847 if (AllowArraySection) {
3848 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
3849 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
3850 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
3853 IsArrayExpr = ArraySubscript;
3854 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
3855 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
3856 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
3858 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
3861 IsArrayExpr = OMPArraySection;
3867 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
3868 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
3869 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
3871 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
3872 !isa<FieldDecl>(ME->getMemberDecl()))) {
3873 if (IsArrayExpr != NoArrayExpr) {
3874 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
3879 ? diag::err_omp_expected_var_name_member_expr_or_array_item
3880 : diag::err_omp_expected_var_name_member_expr)
3883 return std::make_pair(
nullptr,
false);
3885 return std::make_pair(
3890 ArrayRef<OMPClause *> Clauses) {
3892 "Expected non-dependent context.");
3893 auto AllocateRange =
3897 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
3901 MutableArrayRef<Expr *>::iterator I, It, Et;
3902 if (
Cl->getClauseKind() == OMPC_private) {
3903 auto *PC = cast<OMPPrivateClause>(
Cl);
3904 I = PC->private_copies().begin();
3905 It = PC->varlist_begin();
3906 Et = PC->varlist_end();
3907 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
3908 auto *PC = cast<OMPFirstprivateClause>(
Cl);
3909 I = PC->private_copies().begin();
3910 It = PC->varlist_begin();
3911 Et = PC->varlist_end();
3912 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
3913 auto *PC = cast<OMPLastprivateClause>(
Cl);
3914 I = PC->private_copies().begin();
3915 It = PC->varlist_begin();
3916 Et = PC->varlist_end();
3917 }
else if (
Cl->getClauseKind() == OMPC_linear) {
3918 auto *PC = cast<OMPLinearClause>(
Cl);
3919 I = PC->privates().begin();
3920 It = PC->varlist_begin();
3921 Et = PC->varlist_end();
3922 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
3923 auto *PC = cast<OMPReductionClause>(
Cl);
3924 I = PC->privates().begin();
3925 It = PC->varlist_begin();
3926 Et = PC->varlist_end();
3927 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
3928 auto *PC = cast<OMPTaskReductionClause>(
Cl);
3929 I = PC->privates().begin();
3930 It = PC->varlist_begin();
3931 Et = PC->varlist_end();
3932 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
3933 auto *PC = cast<OMPInReductionClause>(
Cl);
3934 I = PC->privates().begin();
3935 It = PC->varlist_begin();
3936 Et = PC->varlist_end();
3938 llvm_unreachable(
"Expected private clause.");
3940 for (
Expr *E : llvm::make_range(It, Et)) {
3947 Expr *SimpleRefExpr = E;
3950 DeclToCopy.try_emplace(Res.first,
3951 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
3956 auto *AC = cast<OMPAllocateClause>(
C);
3957 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3963 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
3966 S.
Diag(AC->getAllocator()->getExprLoc(),
3967 diag::warn_omp_allocate_thread_on_task_target_directive)
3970 for (
Expr *E : AC->varlists()) {
3973 Expr *SimpleRefExpr = E;
3976 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD,
false);
3979 diag::err_omp_expected_private_copy_for_allocate);
3982 VarDecl *PrivateVD = DeclToCopy[VD];
3984 AllocatorKind, AC->getAllocator()))
4005 bool ErrorFound =
false;
4006 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4007 if (AStmt && !CurContext->isDependentContext()) {
4008 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4011 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
4012 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4014 while (--ThisCaptureLevel >= 0)
4015 S = cast<CapturedStmt>(S)->getCapturedStmt();
4016 DSAChecker.Visit(S);
4020 auto *CS = cast<CapturedStmt>(AStmt);
4024 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4026 DSAChecker.visitSubCaptures(CS);
4028 if (DSAChecker.isErrorFound())
4031 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4034 DSAChecker.getImplicitFirstprivate().begin(),
4035 DSAChecker.getImplicitFirstprivate().end());
4037 DSAChecker.getImplicitMap().end());
4040 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
4041 for (
Expr *E : IRC->taskgroup_descriptors())
4043 ImplicitFirstprivates.emplace_back(E);
4046 if (!ImplicitFirstprivates.empty()) {
4047 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4050 ClausesWithImplicit.push_back(Implicit);
4051 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4052 ImplicitFirstprivates.size();
4057 if (!ImplicitMaps.empty()) {
4060 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
4064 ClausesWithImplicit.emplace_back(Implicit);
4066 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
4076 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4078 AllowedNameModifiers.push_back(OMPD_parallel);
4081 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4082 VarsWithInheritedDSA);
4085 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4086 VarsWithInheritedDSA);
4089 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4090 EndLoc, VarsWithInheritedDSA);
4093 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4097 assert(ClausesWithImplicit.empty() &&
4098 "No clauses are allowed for 'omp section' directive");
4099 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4102 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4106 assert(ClausesWithImplicit.empty() &&
4107 "No clauses are allowed for 'omp master' directive");
4108 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4111 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4114 case OMPD_parallel_for:
4115 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4116 EndLoc, VarsWithInheritedDSA);
4117 AllowedNameModifiers.push_back(OMPD_parallel);
4119 case OMPD_parallel_for_simd:
4120 Res = ActOnOpenMPParallelForSimdDirective(
4121 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4122 AllowedNameModifiers.push_back(OMPD_parallel);
4124 case OMPD_parallel_sections:
4125 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4127 AllowedNameModifiers.push_back(OMPD_parallel);
4131 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4132 AllowedNameModifiers.push_back(OMPD_task);
4134 case OMPD_taskyield:
4135 assert(ClausesWithImplicit.empty() &&
4136 "No clauses are allowed for 'omp taskyield' directive");
4137 assert(AStmt ==
nullptr &&
4138 "No associated statement allowed for 'omp taskyield' directive");
4139 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4142 assert(ClausesWithImplicit.empty() &&
4143 "No clauses are allowed for 'omp barrier' directive");
4144 assert(AStmt ==
nullptr &&
4145 "No associated statement allowed for 'omp barrier' directive");
4146 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4149 assert(ClausesWithImplicit.empty() &&
4150 "No clauses are allowed for 'omp taskwait' directive");
4151 assert(AStmt ==
nullptr &&
4152 "No associated statement allowed for 'omp taskwait' directive");
4153 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4155 case OMPD_taskgroup:
4156 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4160 assert(AStmt ==
nullptr &&
4161 "No associated statement allowed for 'omp flush' directive");
4162 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4165 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4169 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4174 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4177 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4179 AllowedNameModifiers.push_back(OMPD_target);
4181 case OMPD_target_parallel:
4182 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4184 AllowedNameModifiers.push_back(OMPD_target);
4185 AllowedNameModifiers.push_back(OMPD_parallel);
4187 case OMPD_target_parallel_for:
4188 Res = ActOnOpenMPTargetParallelForDirective(
4189 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4190 AllowedNameModifiers.push_back(OMPD_target);
4191 AllowedNameModifiers.push_back(OMPD_parallel);
4193 case OMPD_cancellation_point:
4194 assert(ClausesWithImplicit.empty() &&
4195 "No clauses are allowed for 'omp cancellation point' directive");
4196 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp " 4197 "cancellation point' directive");
4198 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4201 assert(AStmt ==
nullptr &&
4202 "No associated statement allowed for 'omp cancel' directive");
4203 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4205 AllowedNameModifiers.push_back(OMPD_cancel);
4207 case OMPD_target_data:
4208 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4210 AllowedNameModifiers.push_back(OMPD_target_data);
4212 case OMPD_target_enter_data:
4213 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4215 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4217 case OMPD_target_exit_data:
4218 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4220 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4223 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4224 EndLoc, VarsWithInheritedDSA);
4225 AllowedNameModifiers.push_back(OMPD_taskloop);
4227 case OMPD_taskloop_simd:
4228 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4229 EndLoc, VarsWithInheritedDSA);
4230 AllowedNameModifiers.push_back(OMPD_taskloop);
4232 case OMPD_distribute:
4233 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4234 EndLoc, VarsWithInheritedDSA);
4236 case OMPD_target_update:
4237 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4239 AllowedNameModifiers.push_back(OMPD_target_update);
4241 case OMPD_distribute_parallel_for:
4242 Res = ActOnOpenMPDistributeParallelForDirective(
4243 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4244 AllowedNameModifiers.push_back(OMPD_parallel);
4246 case OMPD_distribute_parallel_for_simd:
4247 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4248 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4249 AllowedNameModifiers.push_back(OMPD_parallel);
4251 case OMPD_distribute_simd:
4252 Res = ActOnOpenMPDistributeSimdDirective(
4253 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4255 case OMPD_target_parallel_for_simd:
4256 Res = ActOnOpenMPTargetParallelForSimdDirective(
4257 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4258 AllowedNameModifiers.push_back(OMPD_target);
4259 AllowedNameModifiers.push_back(OMPD_parallel);
4261 case OMPD_target_simd:
4262 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4263 EndLoc, VarsWithInheritedDSA);
4264 AllowedNameModifiers.push_back(OMPD_target);
4266 case OMPD_teams_distribute:
4267 Res = ActOnOpenMPTeamsDistributeDirective(
4268 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4270 case OMPD_teams_distribute_simd:
4271 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4274 case OMPD_teams_distribute_parallel_for_simd:
4275 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4276 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4277 AllowedNameModifiers.push_back(OMPD_parallel);
4279 case OMPD_teams_distribute_parallel_for:
4280 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4281 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4282 AllowedNameModifiers.push_back(OMPD_parallel);
4284 case OMPD_target_teams:
4285 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4287 AllowedNameModifiers.push_back(OMPD_target);
4289 case OMPD_target_teams_distribute:
4290 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4291 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4292 AllowedNameModifiers.push_back(OMPD_target);
4294 case OMPD_target_teams_distribute_parallel_for:
4295 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4296 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4297 AllowedNameModifiers.push_back(OMPD_target);
4298 AllowedNameModifiers.push_back(OMPD_parallel);
4300 case OMPD_target_teams_distribute_parallel_for_simd:
4301 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4302 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4303 AllowedNameModifiers.push_back(OMPD_target);
4304 AllowedNameModifiers.push_back(OMPD_parallel);
4306 case OMPD_target_teams_distribute_simd:
4307 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4308 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4309 AllowedNameModifiers.push_back(OMPD_target);
4311 case OMPD_declare_target:
4312 case OMPD_end_declare_target:
4313 case OMPD_threadprivate:
4315 case OMPD_declare_reduction:
4316 case OMPD_declare_mapper:
4317 case OMPD_declare_simd:
4319 llvm_unreachable(
"OpenMP Directive is not allowed");
4321 llvm_unreachable(
"Unknown OpenMP directive");
4324 ErrorFound = Res.
isInvalid() || ErrorFound;
4327 if (
DSAStack->getDefaultDSA() == DSA_none) {
4328 DSAAttrChecker DSAChecker(
DSAStack, *
this,
nullptr);
4330 switch (
C->getClauseKind()) {
4331 case OMPC_num_threads:
4332 case OMPC_dist_schedule:
4339 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
4346 case OMPC_num_teams:
4347 case OMPC_thread_limit:
4349 case OMPC_grainsize:
4350 case OMPC_num_tasks:
4357 case OMPC_proc_bind:
4359 case OMPC_firstprivate:
4360 case OMPC_lastprivate:
4362 case OMPC_reduction:
4363 case OMPC_task_reduction:
4364 case OMPC_in_reduction:
4368 case OMPC_copyprivate:
4371 case OMPC_mergeable:
4383 case OMPC_defaultmap:
4386 case OMPC_use_device_ptr:
4387 case OMPC_is_device_ptr:
4389 case OMPC_allocator:
4394 case OMPC_unified_address:
4395 case OMPC_unified_shared_memory:
4396 case OMPC_reverse_offload:
4397 case OMPC_dynamic_allocators:
4398 case OMPC_atomic_default_mem_order:
4399 llvm_unreachable(
"Unexpected clause");
4401 for (
Stmt *CC :
C->children()) {
4403 DSAChecker.Visit(CC);
4406 for (
auto &
P : DSAChecker.getVarsWithInheritedDSA())
4407 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
4409 for (
const auto &
P : VarsWithInheritedDSA) {
4410 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
4413 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4414 <<
P.first <<
P.second->getSourceRange();
4415 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
4418 if (!AllowedNameModifiers.empty())
4419 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
4427 ->getStructuredBlock()
4431 if (!CurContext->isDependentContext() &&
4438 DSAStack->addTargetDirLocation(StartLoc);
4449 assert(Aligneds.size() == Alignments.size());
4450 assert(Linears.size() == LinModifiers.size());
4451 assert(Linears.size() == Steps.size());
4452 if (!DG || DG.
get().isNull())
4455 if (!DG.
get().isSingleDecl()) {
4456 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd);
4459 Decl *ADecl = DG.
get().getSingleDecl();
4460 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
4461 ADecl = FTD->getTemplatedDecl();
4474 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
4481 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
4482 const Expr *UniformedLinearThis =
nullptr;
4483 for (
const Expr *E : Uniforms) {
4485 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
4486 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
4487 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4488 FD->getParamDecl(PVD->getFunctionScopeIndex())
4490 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
4493 if (isa<CXXThisExpr>(E)) {
4494 UniformedLinearThis = E;
4498 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4508 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
4509 const Expr *AlignedThis =
nullptr;
4510 for (
const Expr *E : Aligneds) {
4512 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
4513 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4515 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4516 FD->getParamDecl(PVD->getFunctionScopeIndex())
4520 if (AlignedArgs.count(CanonPVD) > 0) {
4523 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
4524 diag::note_omp_explicit_dsa)
4528 AlignedArgs[CanonPVD] = E;
4530 .getNonReferenceType()
4531 .getUnqualifiedType()
4532 .getCanonicalType();
4535 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
4537 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
4542 if (isa<CXXThisExpr>(E)) {
4553 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4560 for (
Expr *E : Alignments) {
4563 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
4564 NewAligns.push_back(Align.
get());
4575 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
4576 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
4577 auto MI = LinModifiers.begin();
4578 for (
const Expr *E : Linears) {
4582 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
4583 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4585 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
4586 FD->getParamDecl(PVD->getFunctionScopeIndex())
4590 if (LinearArgs.count(CanonPVD) > 0) {
4594 Diag(LinearArgs[CanonPVD]->getExprLoc(),
4595 diag::note_omp_explicit_dsa)
4600 if (UniformedArgs.count(CanonPVD) > 0) {
4604 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
4605 diag::note_omp_explicit_dsa)
4609 LinearArgs[CanonPVD] = E;
4614 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
4615 PVD->getOriginalType());
4619 if (isa<CXXThisExpr>(E)) {
4620 if (UniformedLinearThis) {
4625 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
4630 UniformedLinearThis = E;
4634 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
4639 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
4642 Expr *NewStep =
nullptr;
4644 for (
Expr *E : Steps) {
4646 if (Step == E || !E) {
4647 NewSteps.push_back(E ? NewStep :
nullptr);
4651 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
4652 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
4654 if (UniformedArgs.count(CanonPVD) == 0) {
4661 NewSteps.push_back(Step);
4672 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(),
Step)
4675 NewStep = VerifyIntegerConstantExpression(NewStep).get();
4677 NewSteps.push_back(NewStep);
4679 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
4680 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
4681 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
4682 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
4683 const_cast<Expr **
>(Linears.data()), Linears.size(),
4684 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
4685 NewSteps.data(), NewSteps.size(), SR);
4687 return ConvertDeclToDeclGroup(ADecl);
4697 auto *CS = cast<CapturedStmt>(AStmt);
4705 setFunctionHasBranchProtectedScope();
4715 class OpenMPIterationSpaceChecker {
4733 Expr *LCRef =
nullptr;
4748 bool TestIsStrictOp =
false;
4750 bool SubtractStep =
false;
4763 OpenMPIterationSpaceChecker(
Sema &SemaRef, DSAStackTy &Stack,
4765 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
4766 ConditionLoc(DefaultLoc) {}
4769 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
4772 bool checkAndSetCond(
Expr *S);
4775 bool checkAndSetInc(
Expr *S);
4777 ValueDecl *getLoopDecl()
const {
return LCDecl; }
4779 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
4781 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
4783 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
4785 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
4787 bool shouldSubtractStep()
const {
return SubtractStep; }
4789 bool isStrictTestOp()
const {
return TestIsStrictOp; }
4791 Expr *buildNumIterations(
4792 Scope *S,
const bool LimitedType,
4793 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
4797 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
4800 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4801 DSAStackTy &DSA)
const;
4804 Expr *buildPrivateCounterVar()
const;
4808 Expr *buildCounterStep()
const;
4812 buildOrderedLoopData(
Scope *S,
Expr *Counter,
4813 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4817 bool dependent()
const;
4822 bool checkAndSetIncRHS(
Expr *RHS);
4833 bool OpenMPIterationSpaceChecker::dependent()
const {
4835 assert(!LB && !UB && !
Step);
4838 return LCDecl->getType()->isDependentType() ||
4839 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4840 (
Step &&
Step->isValueDependent());
4843 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
4845 Expr *NewLB,
bool EmitDiags) {
4847 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
4848 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4849 if (!NewLCDecl || !NewLB)
4852 LCRef = NewLCRefExpr;
4853 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4855 if ((Ctor->isCopyOrMoveConstructor() ||
4856 Ctor->isConvertingConstructor(
false)) &&
4857 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
4861 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
4865 bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB,
4870 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
4871 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
4876 TestIsLessOp = LessOp;
4877 TestIsStrictOp = StrictOp;
4878 ConditionSrcRange = SR;
4880 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
4886 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
4896 NewStep = Val.
get();
4913 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4915 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4916 bool IsConstZero = IsConstant && !Result.getBoolValue();
4919 if (!TestIsLessOp.hasValue())
4920 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
4921 if (UB && (IsConstZero ||
4922 (TestIsLessOp.getValue() ?
4923 (IsConstNeg || (IsUnsigned && Subtract)) :
4924 (IsConstPos || (IsUnsigned && !Subtract))))) {
4926 diag::err_omp_loop_incr_not_compatible)
4927 << LCDecl << TestIsLessOp.getValue() << NewStep->
getSourceRange();
4928 SemaRef.
Diag(ConditionLoc,
4929 diag::note_omp_loop_cond_requres_compatible_incr)
4930 << TestIsLessOp.getValue() << ConditionSrcRange;
4933 if (TestIsLessOp.getValue() == Subtract) {
4937 Subtract = !Subtract;
4942 SubtractStep = Subtract;
4949 class LoopCounterRefChecker final
4956 bool IsInitializer =
true;
4957 unsigned BaseLoopId = 0;
4960 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
4961 << (IsInitializer ? 0 : 1);
4964 const auto &&Data = Stack.isLoopControlVariable(VD);
4970 llvm::raw_svector_ostream OS(Name);
4974 diag::err_omp_wrong_dependency_iterator_type)
4976 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
4980 (DepDecl || (PrevDepDecl &&
4982 if (!DepDecl && PrevDepDecl)
4983 DepDecl = PrevDepDecl;
4985 llvm::raw_svector_ostream OS(Name);
4989 diag::err_omp_invariant_or_linear_dependency)
4995 BaseLoopId = Data.first;
5003 if (isa<VarDecl>(VD))
5004 return checkDecl(E, VD);
5010 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
5011 return checkDecl(E, VD);
5015 bool VisitStmt(
const Stmt *S) {
5018 Res = Child && Visit(Child) && Res;
5021 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
5022 const ValueDecl *CurLCDecl,
bool IsInitializer,
5024 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
5025 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
5026 unsigned getBaseLoopId()
const {
5027 assert(CurLCDecl &&
"Expected loop dependency.");
5031 assert(CurLCDecl &&
"Expected loop dependency.");
5038 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
5039 bool IsInitializer) {
5041 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
5043 if (LoopStmtChecker.Visit(S)) {
5044 DepDecl = LoopStmtChecker.getDepDecl();
5045 return LoopStmtChecker.getBaseLoopId();
5050 bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
5061 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
5065 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5066 if (!ExprTemp->cleanupsHaveSideEffects())
5067 S = ExprTemp->getSubExpr();
5070 if (
Expr *E = dyn_cast<Expr>(S))
5072 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
5073 if (BO->getOpcode() == BO_Assign) {
5075 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
5076 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5078 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5080 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
5082 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
5083 if (ME->isArrow() &&
5084 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5085 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5089 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
5090 if (DS->isSingleDecl()) {
5091 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
5092 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
5096 diag::ext_omp_loop_not_canonical_init)
5098 return setLCDeclAndLB(
5101 Var->getType().getNonReferenceType(),
5103 Var->getInit(), EmitDiags);
5107 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5108 if (CE->getOperator() == OO_Equal) {
5109 Expr *LHS = CE->getArg(0);
5110 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
5111 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
5113 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5115 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
5117 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
5118 if (ME->isArrow() &&
5119 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5120 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
5141 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
5143 if ((Ctor->isCopyOrMoveConstructor() ||
5144 Ctor->isConvertingConstructor(
false)) &&
5145 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
5147 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
5148 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
5151 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
5152 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
5157 bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
5165 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
5170 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
5171 if (BO->isRelationalOp()) {
5172 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5173 return setUB(BO->getRHS(),
5174 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
5175 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5176 BO->getSourceRange(), BO->getOperatorLoc());
5177 if (getInitLCDecl(BO->getRHS()) == LCDecl)
5178 return setUB(BO->getLHS(),
5179 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
5180 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
5181 BO->getSourceRange(), BO->getOperatorLoc());
5182 }
else if (BO->getOpcode() == BO_NE)
5183 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
5184 BO->getRHS() : BO->getLHS(),
5187 BO->getSourceRange(), BO->getOperatorLoc());
5188 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5189 if (CE->getNumArgs() == 2) {
5190 auto Op = CE->getOperator();
5193 case OO_GreaterEqual:
5196 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5197 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
5198 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5199 CE->getOperatorLoc());
5200 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
5201 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
5202 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
5203 CE->getOperatorLoc());
5205 case OO_ExclaimEqual:
5206 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
5207 CE->getArg(1) : CE->getArg(0),
5210 CE->getSourceRange(),
5211 CE->getOperatorLoc());
5220 SemaRef.
Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
5225 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
5232 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
5233 if (BO->isAdditiveOp()) {
5234 bool IsAdd = BO->getOpcode() == BO_Add;
5235 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5236 return setStep(BO->getRHS(), !IsAdd);
5237 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
5238 return setStep(BO->getLHS(),
false);
5240 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
5241 bool IsAdd = CE->getOperator() == OO_Plus;
5242 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
5243 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5244 return setStep(CE->getArg(1), !IsAdd);
5245 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
5246 return setStep(CE->getArg(0),
false);
5251 SemaRef.
Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
5256 bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
5271 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
5274 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
5275 if (!ExprTemp->cleanupsHaveSideEffects())
5276 S = ExprTemp->getSubExpr();
5280 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
5281 if (UO->isIncrementDecrementOp() &&
5282 getInitLCDecl(UO->getSubExpr()) == LCDecl)
5284 .ActOnIntegerConstant(UO->getBeginLoc(),
5285 (UO->isDecrementOp() ? -1 : 1))
5288 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
5289 switch (BO->getOpcode()) {
5292 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5293 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
5296 if (getInitLCDecl(BO->getLHS()) == LCDecl)
5297 return checkAndSetIncRHS(BO->getRHS());
5302 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
5303 switch (CE->getOperator()) {
5306 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5308 .ActOnIntegerConstant(
5310 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
5316 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5317 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
5320 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
5321 return checkAndSetIncRHS(CE->getArg(1));
5335 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
5336 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5343 auto I = Captures.find(Capture);
5344 if (I != Captures.end())
5348 Captures[Capture] = Ref;
5353 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
5354 Scope *S,
const bool LimitedType,
5355 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
5357 QualType VarType = LCDecl->getType().getNonReferenceType();
5361 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
5362 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
5363 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
5364 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
5365 if (!Upper || !Lower)
5368 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
5385 S, DefaultLoc, BO_Sub, Diff.
get(),
5394 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.
get());
5404 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
5427 unsigned NewSize = (C.
getTypeSize(Type) > 32) ? 64 : 32;
5430 assert(NewSize == 64 &&
"incorrect loop var size");
5431 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
5432 << InitSrcRange << ConditionSrcRange;
5449 Expr *OpenMPIterationSpaceChecker::buildPreCond(
5451 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
5456 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
5457 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
5463 TestIsLessOp.getValue() ?
5464 (TestIsStrictOp ? BO_LT : BO_LE) :
5465 (TestIsStrictOp ? BO_GT : BO_GE),
5466 NewLB.
get(), NewUB.
get());
5476 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
5480 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
5481 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5482 DSAStackTy &DSA)
const {
5483 auto *VD = dyn_cast<
VarDecl>(LCDecl);
5487 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
5488 const DSAStackTy::DSAVarData Data =
5489 DSA.getTopDSA(LCDecl,
false);
5493 Captures.insert(std::make_pair(LCRef, Ref));
5496 return cast<DeclRefExpr>(LCRef);
5499 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
5500 if (LCDecl && !LCDecl->isInvalidDecl()) {
5501 QualType Type = LCDecl->getType().getNonReferenceType();
5503 SemaRef, DefaultLoc, Type, LCDecl->getName(),
5504 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr,
5505 isa<VarDecl>(LCDecl)
5519 Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
5521 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
5523 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
5529 assert((OOK == OO_Plus || OOK == OO_Minus) &&
5530 "Expected only + or - operations for depend clauses.");
5537 QualType VarType = LCDecl->getType().getNonReferenceType();
5541 Expr *Upper = TestIsLessOp.getValue()
5543 : tryBuildCapture(SemaRef, UB, Captures).get();
5544 Expr *Lower = TestIsLessOp.getValue()
5545 ? tryBuildCapture(SemaRef, LB, Captures).get()
5547 if (!Upper || !Lower)
5550 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
5573 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
5581 struct LoopIterationSpace final {
5584 bool IsStrictCompare =
false;
5586 Expr *PreCond =
nullptr;
5589 Expr *NumIterations =
nullptr;
5591 Expr *CounterVar =
nullptr;
5593 Expr *PrivateCounterVar =
nullptr;
5595 Expr *CounterInit =
nullptr;
5598 Expr *CounterStep =
nullptr;
5600 bool Subtract =
false;
5612 assert(getLangOpts().OpenMP &&
"OpenMP is not active.");
5613 assert(Init &&
"Expected loop in canonical form.");
5614 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
5615 if (AssociatedLoops > 0 &&
5618 OpenMPIterationSpaceChecker ISC(*
this, *
DSAStack, ForLoc);
5619 if (!ISC.checkAndSetInit(Init,
false)) {
5621 auto *VD = dyn_cast<
VarDecl>(D);
5624 if (
VarDecl *Private = isOpenMPCapturedDecl(D)) {
5627 PrivateRef =
buildCapture(*
this, D, ISC.getLoopDeclRefExpr(),
5629 VD = cast<VarDecl>(PrivateRef->getDecl());
5632 DSAStack->addLoopControlVariable(D, VD);
5635 DSAStack->resetPossibleLoopCounter();
5636 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
5637 MarkDeclarationsReferencedInExpr(
5639 Var->getType().getNonLValueExprType(Context),
5650 DSAStackTy::DSAVarData DVar =
5654 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
5657 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
5660 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
5661 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
5662 DVar.CKind != OMPC_private))) ||
5666 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
5667 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
5672 if (DVar.RefExpr ==
nullptr)
5673 DVar.CKind = PredeterminedCKind;
5676 }
else if (LoopDeclRefExpr) {
5682 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
5687 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
5695 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
5696 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
5697 Expr *OrderedLoopCountExpr,
5699 LoopIterationSpace &ResultIterSpace,
5700 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5703 auto *For = dyn_cast_or_null<ForStmt>(S);
5706 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
5708 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
5709 if (TotalNestedLoopCount > 1) {
5710 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
5711 SemaRef.
Diag(DSA.getConstructLoc(),
5712 diag::note_omp_collapse_ordered_expr)
5715 else if (CollapseLoopCountExpr)
5717 diag::note_omp_collapse_ordered_expr)
5721 diag::note_omp_collapse_ordered_expr)
5726 assert(For->getBody());
5728 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, For->getForLoc());
5731 Stmt *Init = For->getInit();
5732 if (ISC.checkAndSetInit(Init))
5735 bool HasErrors =
false;
5738 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
5744 QualType VarType = LCDecl->getType().getNonReferenceType();
5748 SemaRef.
Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
5762 VarsWithImplicitDSA.erase(LCDecl);
5767 HasErrors |= ISC.checkAndSetCond(For->getCond());
5770 HasErrors |= ISC.checkAndSetInc(For->getInc());
5777 ResultIterSpace.PreCond =
5778 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
5779 ResultIterSpace.NumIterations = ISC.buildNumIterations(
5784 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
5785 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
5786 ResultIterSpace.CounterInit = ISC.buildCounterInit();
5787 ResultIterSpace.CounterStep = ISC.buildCounterStep();
5788 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
5789 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
5790 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
5791 ResultIterSpace.Subtract = ISC.shouldSubtractStep();
5792 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp();
5794 HasErrors |= (ResultIterSpace.PreCond ==
nullptr ||
5795 ResultIterSpace.NumIterations ==
nullptr ||
5796 ResultIterSpace.CounterVar ==
nullptr ||
5797 ResultIterSpace.PrivateCounterVar ==
nullptr ||
5798 ResultIterSpace.CounterInit ==
nullptr ||
5799 ResultIterSpace.CounterStep ==
nullptr);
5800 if (!HasErrors && DSA.isOrderedRegion()) {
5801 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
5802 if (CurrentNestedLoopCount <
5803 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
5804 DSA.getOrderedRegionParam().second->setLoopNumIterations(
5805 CurrentNestedLoopCount, ResultIterSpace.NumIterations);
5806 DSA.getOrderedRegionParam().second->setLoopCounter(
5807 CurrentNestedLoopCount, ResultIterSpace.CounterVar);
5810 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
5811 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
5815 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
5816 Pair.second.size() <= CurrentNestedLoopCount) {
5818 Pair.first->setLoopData(CurrentNestedLoopCount,
nullptr);
5822 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5823 CntValue = ISC.buildOrderedLoopData(
5824 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5825 Pair.first->getDependencyLoc());
5827 CntValue = ISC.buildOrderedLoopData(
5828 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
5829 Pair.first->getDependencyLoc(),
5830 Pair.second[CurrentNestedLoopCount].first,
5831 Pair.second[CurrentNestedLoopCount].second);
5832 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
5843 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5845 ExprResult NewStart = tryBuildCapture(SemaRef, Start.
get(), Captures);
5849 VarRef.
get()->getType())) {
5866 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
5875 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
5887 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
5894 if (VarRef.
get()->getType()->isOverloadableType() ||
5895 NewStart.
get()->getType()->isOverloadableType() ||
5896 Update.
get()->getType()->isOverloadableType()) {
5903 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
5904 VarRef.
get(), SavedUpdate.
get());
5915 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
5916 NewStart.
get(), SavedUpdate.
get());
5921 VarRef.
get()->getType())) {
5928 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
5941 if (HasBits >= Bits)
5956 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5962 MutableArrayRef<Decl *> PreInits) {
5963 if (!PreInits.empty()) {
5974 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5975 if (!Captures.empty()) {
5977 for (
const auto &Pair : Captures)
5978 PreInits.push_back(Pair.second->getDecl());
5986 Expr *PostUpdate =
nullptr;
5987 if (!PostUpdates.empty()) {
5988 for (
Expr *E : PostUpdates) {
5994 PostUpdate = PostUpdate
6009 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
6013 unsigned NestedLoopCount = 1;
6014 if (CollapseLoopCountExpr) {
6019 NestedLoopCount = Result.
Val.
getInt().getLimitedValue();
6025 unsigned OrderedLoopCount = 1;
6026 if (OrderedLoopCountExpr) {
6033 if (Result.getLimitedValue() < NestedLoopCount) {
6035 diag::err_omp_wrong_ordered_loop_count)
6038 diag::note_collapse_loop_count)
6041 OrderedLoopCount = Result.getLimitedValue();
6049 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
6051 std::max(OrderedLoopCount, NestedLoopCount));
6053 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
6055 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6056 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
6057 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
6067 for (
unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
6069 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
6070 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
6071 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
6074 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
6076 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
6077 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
6078 Captures[DRE] = DRE;
6089 Built.
clear( NestedLoopCount);
6092 return NestedLoopCount;
6125 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
6126 Expr *N0 = IterSpaces[0].NumIterations;
6130 .PerformImplicitConversion(
6144 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
6145 return NestedLoopCount;
6150 Scope *CurScope = DSA.getCurScope();
6151 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
6152 if (PreCond.isUsable()) {
6154 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
6155 PreCond.get(), IterSpaces[Cnt].PreCond);
6157 Expr *N = IterSpaces[Cnt].NumIterations;
6162 CurScope, Loc, BO_Mul, LastIteration32.
get(),
6168 if (LastIteration64.isUsable())
6170 CurScope, Loc, BO_Mul, LastIteration64.get(),
6180 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
6183 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
6186 LastIteration32.
get()->getType()->hasSignedIntegerRepresentation(),
6187 LastIteration64.get(), SemaRef))))
6188 LastIteration = LastIteration32;
6206 CurScope, LastIteration.
get()->getExprLoc(), BO_Sub,
6207 LastIteration.
get(),
6217 LastIteration.
get()->isIntegerConstantExpr(Result, SemaRef.
Context);
6221 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
6222 LastIteration = SaveRef;
6226 CurScope, SaveRef.
get()->getExprLoc(), BO_Add, SaveRef.
get(),
6235 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
6262 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
6271 UB.
get(), LastIteration.
get());
6273 LastIteration.
get()->getExprLoc(), InitLoc, IsUBGreater.
get(),
6274 LastIteration.
get(), UB.
get());
6275 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
6300 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
6303 LastIteration.
get(), CombUB.
get());
6304 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
6309 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
6313 "Unexpected number of parameters in loop combined directive");
6340 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
6351 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
6357 bool UseStrictCompare =
6359 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
6360 return LIS.IsStrictCompare;
6366 if (UseStrictCompare) {
6369 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
6379 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
6381 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
6382 NumIterations.
get());
6385 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
6386 NumIterations.
get());
6391 Expr *BoundCombUB = CombUB.
get();
6392 if (UseStrictCompare) {
6396 CurScope, CondLoc, BO_Add, BoundCombUB,
6404 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
6405 IV.get(), BoundCombUB);
6410 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
6414 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
6423 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
6454 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
6466 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
6480 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
6483 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
6484 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
6487 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
6488 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
6489 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
6493 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
6501 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
6502 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
6510 Expr *BoundPrevUB = PrevUB.
get();
6511 if (UseStrictCompare) {
6515 CurScope, CondLoc, BO_Add, BoundPrevUB,
6523 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
6524 IV.get(), BoundPrevUB);
6528 bool HasErrors =
false;
6529 Built.
Counters.resize(NestedLoopCount);
6530 Built.
Inits.resize(NestedLoopCount);
6531 Built.
Updates.resize(NestedLoopCount);
6532 Built.
Finals.resize(NestedLoopCount);
6550 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
6551 LoopIterationSpace &IS = IterSpaces[Cnt];
6558 for (
unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
6559 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
6560 IterSpaces[K].NumIterations);
6565 if (Cnt + 1 < NestedLoopCount)
6566 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div,
6579 if (Cnt + 1 < NestedLoopCount)
6580 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul,
6584 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub,
6588 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
6590 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
6593 IS.CounterInit, Captures);
6594 if (!Init.isUsable()) {
6599 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
6600 IS.CounterStep, IS.Subtract, &Captures);
6608 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
6609 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
6620 Built.
Counters[Cnt] = IS.CounterVar;
6622 Built.
Inits[Cnt] = Init.get();
6639 Built.
PreCond = PreCond.get();
6644 Built.
LB = LB.
get();
6645 Built.
UB = UB.
get();
6646 Built.
IL = IL.
get();
6647 Built.
ST = ST.
get();
6649 Built.
NLB = NextLB.
get();
6650 Built.
NUB = NextUB.
get();
6665 return NestedLoopCount;
6669 auto CollapseClauses =
6670 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
6671 if (CollapseClauses.begin() != CollapseClauses.end())
6672 return (*CollapseClauses.begin())->getNumForLoops();
6677 auto OrderedClauses =
6678 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
6679 if (OrderedClauses.begin() != OrderedClauses.end())
6680 return (*OrderedClauses.begin())->getNumForLoops();
6685 const ArrayRef<OMPClause *> Clauses) {
6689 for (
const OMPClause *Clause : Clauses) {
6691 Safelen = cast<OMPSafelenClause>(Clause);
6693 Simdlen = cast<OMPSimdlenClause>(Clause);
6694 if (Safelen && Simdlen)
6698 if (Simdlen && Safelen) {
6712 llvm::APSInt SimdlenRes = SimdlenResult.
Val.
getInt();
6713 llvm::APSInt SafelenRes = SafelenResult.
Val.
getInt();
6718 if (SimdlenRes > SafelenRes) {
6720 diag::err_omp_wrong_simdlen_safelen_values)
6735 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6741 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
6742 if (NestedLoopCount == 0)
6745 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6746 "omp simd loop exprs were not built");
6748 if (!CurContext->isDependentContext()) {
6751 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6762 setFunctionHasBranchProtectedScope();
6774 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6780 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
6781 if (NestedLoopCount == 0)
6784 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6785 "omp for loop exprs were not built");
6787 if (!CurContext->isDependentContext()) {
6790 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6798 setFunctionHasBranchProtectedScope();
6800 Clauses, AStmt, B,
DSAStack->isCancelRegion());
6809 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6813 unsigned NestedLoopCount =
6816 VarsWithImplicitDSA, B);
6817 if (NestedLoopCount == 0)
6820 assert((CurContext->isDependentContext() || B.
builtAll()) &&
6821 "omp for simd loop exprs were not built");
6823 if (!CurContext->isDependentContext()) {
6826 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
6837 setFunctionHasBranchProtectedScope();
6849 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6850 auto BaseStmt = AStmt;
6851 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6853 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6854 auto S =
C->children();
6855 if (S.begin() == S.end())
6859 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6860 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6862 Diag(SectionStmt->getBeginLoc(),
6863 diag::err_omp_sections_substmt_not_section);
6866 cast<OMPSectionDirective>(SectionStmt)
6867 ->setHasCancel(
DSAStack->isCancelRegion());
6874 setFunctionHasBranchProtectedScope();
6886 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6888 setFunctionHasBranchProtectedScope();
6902 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6904 setFunctionHasBranchProtectedScope();
6910 for (
const OMPClause *Clause : Clauses) {
6914 Copyprivate = Clause;
6915 if (Copyprivate && Nowait) {
6917 diag::err_omp_single_copyprivate_with_nowait);
6932 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6934 setFunctionHasBranchProtectedScope();
6945 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
6947 bool ErrorFound =
false;
6950 bool DependentHint =
false;
6952 if (
C->getClauseKind() == OMPC_hint) {
6954 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
6957 Expr *E = cast<OMPHintClause>(
C)->getHint();
6960 DependentHint =
true;
6963 HintLoc =
C->getBeginLoc();
6969 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
6970 if (Pair.first && DirName.
getName() && !DependentHint) {
6971 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6972 Diag(StartLoc, diag::err_omp_critical_with_hint);
6974 Diag(HintLoc, diag::note_omp_critical_hint_here)
6975 << 0 << Hint.toString(10,
false);
6977 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6978 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
6979 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
6981 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
6984 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6989 setFunctionHasBranchProtectedScope();
6993 if (!Pair.first && DirName.
getName() && !DependentHint)
6994 DSAStack->addCriticalWithHint(Dir, Hint);
7004 auto *CS = cast<CapturedStmt>(AStmt);
7015 unsigned NestedLoopCount =
7018 VarsWithImplicitDSA, B);
7019 if (NestedLoopCount == 0)
7022 assert((CurContext->isDependentContext() || B.
builtAll()) &&
7023 "omp parallel for loop exprs were not built");
7025 if (!CurContext->isDependentContext()) {
7028 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7036 setFunctionHasBranchProtectedScope();
7038 NestedLoopCount, Clauses, AStmt, B,
7048 auto *CS = cast<CapturedStmt>(AStmt);
7059 unsigned NestedLoopCount =
7062 VarsWithImplicitDSA, B);
7063 if (NestedLoopCount == 0)
7066 if (!CurContext->isDependentContext()) {
7069 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
7080 setFunctionHasBranchProtectedScope();
7082 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7092 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7093 auto BaseStmt = AStmt;
7094 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
7096 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
7097 auto S =
C->children();
7098 if (S.begin() == S.end())
7102 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
7103 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
7105 Diag(SectionStmt->getBeginLoc(),
7106 diag::err_omp_parallel_sections_substmt_not_section);
7109 cast<OMPSectionDirective>(SectionStmt)
7110 ->setHasCancel(
DSAStack->isCancelRegion());
7114 diag::err_omp_parallel_sections_not_compound_stmt);
7118 setFunctionHasBranchProtectedScope();
7121 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
7130 auto *CS = cast<CapturedStmt>(AStmt);
7138 setFunctionHasBranchProtectedScope();
7166 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7168 setFunctionHasBranchProtectedScope();
7172 DSAStack->getTaskgroupReductionRef());
7178 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
7187 const OMPClause *DependSourceClause =
nullptr;
7188 const OMPClause *DependSinkClause =
nullptr;
7189 bool ErrorFound =
false;
7193 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
7195 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
7196 if (DependSourceClause) {
7197 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
7202 DependSourceClause =
C;
7204 if (DependSinkClause) {
7205 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
7209 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
7210 if (DependSourceClause) {
7211 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
7215 DependSinkClause =
C;
7217 }
else if (
C->getClauseKind() == OMPC_threads) {
7218 TC = cast<OMPThreadsClause>(
C);
7219 }
else if (
C->getClauseKind() == OMPC_simd) {
7220 SC = cast<OMPSIMDClause>(
C);
7223 if (!ErrorFound && !SC &&
7228 Diag(StartLoc, diag::err_omp_prohibited_region_simd);
7230 }
else if (DependFound && (TC || SC)) {
7231 Diag(DependFound->
getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
7234 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
7236 diag::err_omp_ordered_directive_without_param);
7238 }
else if (TC || Clauses.empty()) {
7239 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
7241 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
7243 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
7247 if ((!AStmt && !DependFound) || ErrorFound)
7251 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
7253 setFunctionHasBranchProtectedScope();
7262 class OpenMPAtomicUpdateChecker {
7264 enum ExprAnalysisErrorCode {
7268 NotABinaryOrUnaryExpression,
7270 NotAnUnaryIncDecExpression,
7276 NotABinaryExpression,
7282 NotAnUpdateExpression,
7300 bool IsXLHSInRHSPart;
7305 bool IsPostfixUpdate;
7308 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
7309 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
7310 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
7318 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
7320 Expr *getX()
const {
return X; }
7322 Expr *getExpr()
const {
return E; }
7326 Expr *getUpdateExpr()
const {
return UpdateExpr; }
7329 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
7333 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
7336 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
7337 unsigned NoteId = 0);
7341 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
7343 ExprAnalysisErrorCode ErrorFound = NoError;
7349 if (AtomicBinOp->
getOpcode() == BO_Assign) {
7351 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
7353 if (AtomicInnerBinOp->isMultiplicativeOp() ||
7354 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
7355 AtomicInnerBinOp->isBitwiseOp()) {
7356 Op = AtomicInnerBinOp->getOpcode();
7357 OpLoc = AtomicInnerBinOp->getOperatorLoc();
7358 Expr *LHS = AtomicInnerBinOp->getLHS();
7359 Expr *RHS = AtomicInnerBinOp->getRHS();
7360 llvm::FoldingSetNodeID XId, LHSId, RHSId;
7369 IsXLHSInRHSPart =
true;
7370 }
else if (XId == RHSId) {
7372 IsXLHSInRHSPart =
false;
7374 ErrorLoc = AtomicInnerBinOp->getExprLoc();
7375 ErrorRange = AtomicInnerBinOp->getSourceRange();
7376 NoteLoc =
X->getExprLoc();
7377 NoteRange =
X->getSourceRange();
7378 ErrorFound = NotAnUpdateExpression;
7381 ErrorLoc = AtomicInnerBinOp->getExprLoc();
7382 ErrorRange = AtomicInnerBinOp->getSourceRange();
7383 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
7385 ErrorFound = NotABinaryOperator;
7390 ErrorFound = NotABinaryExpression;
7397 ErrorFound = NotAnAssignmentOp;
7399 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
7400 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
7401 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
7405 E =
X = UpdateExpr =
nullptr;
7406 return ErrorFound != NoError;
7409 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
7411 ExprAnalysisErrorCode ErrorFound = NoError;
7422 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
7423 AtomicBody = AtomicBody->IgnoreParenImpCasts();
7424 if (AtomicBody->getType()->isScalarType() ||
7425 AtomicBody->isInstantiationDependent()) {
7426 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
7427 AtomicBody->IgnoreParenImpCasts())) {
7430 AtomicCompAssignOp->getOpcode());
7431 OpLoc = AtomicCompAssignOp->getOperatorLoc();
7432 E = AtomicCompAssignOp->getRHS();
7433 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
7434 IsXLHSInRHSPart =
true;
7435 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
7436 AtomicBody->IgnoreParenImpCasts())) {
7438 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
7440 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
7441 AtomicBody->IgnoreParenImpCasts())) {
7443 if (AtomicUnaryOp->isIncrementDecrementOp()) {
7444 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
7445 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
7446 OpLoc = AtomicUnaryOp->getOperatorLoc();
7447 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
7449 IsXLHSInRHSPart =
true;
7451 ErrorFound = NotAnUnaryIncDecExpression;
7452 ErrorLoc = AtomicUnaryOp->getExprLoc();
7453 ErrorRange = AtomicUnaryOp->getSourceRange();
7454 NoteLoc = AtomicUnaryOp->getOperatorLoc();
7457 }
else if (!AtomicBody->isInstantiationDependent()) {
7458 ErrorFound = NotABinaryOrUnaryExpression;
7459 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
7460 NoteRange = ErrorRange = AtomicBody->getSourceRange();
7463 ErrorFound = NotAScalarType;
7464 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
7465 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
7468 ErrorFound = NotAnExpression;
7470 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
7472 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
7473 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
7474 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
7478 E =
X = UpdateExpr =
nullptr;
7479 if (ErrorFound == NoError && E &&
X) {
7489 IsXLHSInRHSPart ? OVEExpr : OVEX);
7496 UpdateExpr = Update.
get();
7498 return ErrorFound != NoError;
7508 auto *CS = cast<CapturedStmt>(AStmt);
7517 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
7518 C->getClauseKind() == OMPC_update ||
7519 C->getClauseKind() == OMPC_capture) {
7521 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
7523 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
7526 AtomicKind =
C->getClauseKind();
7527 AtomicKindLoc =
C->getBeginLoc();
7533 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
7534 Body = EWC->getSubExpr();
7540 bool IsXLHSInRHSPart =
false;
7541 bool IsPostfixUpdate =
false;
7564 if (AtomicKind == OMPC_read) {
7571 } ErrorFound = NoError;
7576 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7577 const auto *AtomicBinOp =
7579 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
7586 ErrorFound = NotAnLValue;
7594 const Expr *NotScalarExpr =
7598 ErrorFound = NotAScalarType;
7604 }
else if (!AtomicBody->isInstantiationDependent()) {
7605 ErrorFound = NotAnAssignmentOp;
7606 ErrorLoc = AtomicBody->getExprLoc();
7607 ErrorRange = AtomicBody->getSourceRange();
7609 : AtomicBody->getExprLoc();
7611 : AtomicBody->getSourceRange();
7614 ErrorFound = NotAnExpression;
7616 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
7618 if (ErrorFound != NoError) {
7619 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
7621 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7625 if (CurContext->isDependentContext())
7627 }
else if (AtomicKind == OMPC_write) {
7634 } ErrorFound = NoError;
7639 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7640 const auto *AtomicBinOp =
7642 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
7643 X = AtomicBinOp->
getLHS();
7644 E = AtomicBinOp->
getRHS();
7648 ErrorFound = NotAnLValue;
7656 const Expr *NotScalarExpr =
7660 ErrorFound = NotAScalarType;
7666 }
else if (!AtomicBody->isInstantiationDependent()) {
7667 ErrorFound = NotAnAssignmentOp;
7668 ErrorLoc = AtomicBody->getExprLoc();
7669 ErrorRange = AtomicBody->getSourceRange();
7671 : AtomicBody->getExprLoc();
7673 : AtomicBody->getSourceRange();
7676 ErrorFound = NotAnExpression;
7678 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
7680 if (ErrorFound != NoError) {
7681 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
7683 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
7687 if (CurContext->isDependentContext())
7689 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
7698 OpenMPAtomicUpdateChecker Checker(*
this);
7699 if (Checker.checkStatement(
7700 Body, (AtomicKind == OMPC_update)
7701 ? diag::err_omp_atomic_update_not_expression_statement
7702 : diag::err_omp_atomic_not_expression_statement,
7703 diag::note_omp_atomic_update))
7705 if (!CurContext->isDependentContext()) {
7706 E = Checker.getExpr();
7708 UE = Checker.getUpdateExpr();
7709 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7711 }
else if (AtomicKind == OMPC_capture) {
7714 NotACompoundStatement,
7715 NotTwoSubstatements,
7716 NotASpecificExpression,
7718 } ErrorFound = NoError;
7721 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
7730 const auto *AtomicBinOp =
7732 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
7733 V = AtomicBinOp->
getLHS();
7735 OpenMPAtomicUpdateChecker Checker(*
this);
7736 if (Checker.checkStatement(
7737 Body, diag::err_omp_atomic_capture_not_expression_statement,
7738 diag::note_omp_atomic_update))
7740 E = Checker.getExpr();
7742 UE = Checker.getUpdateExpr();
7743 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7744 IsPostfixUpdate = Checker.isPostfixUpdate();
7745 }
else if (!AtomicBody->isInstantiationDependent()) {
7746 ErrorLoc = AtomicBody->getExprLoc();
7747 ErrorRange = AtomicBody->getSourceRange();
7749 : AtomicBody->getExprLoc();
7751 : AtomicBody->getSourceRange();
7752 ErrorFound = NotAnAssignmentOp;
7754 if (ErrorFound != NoError) {
7755 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
7757 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7760 if (CurContext->isDependentContext())
7761 UE = V = E = X =
nullptr;
7779 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
7781 if (CS->size() == 2) {
7783 Stmt *Second = CS->body_back();
7784 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
7785 First = EWC->getSubExpr()->IgnoreParenImpCasts();
7786 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
7787 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
7789 OpenMPAtomicUpdateChecker Checker(*
this);
7790 bool IsUpdateExprFound = !Checker.checkStatement(Second);
7792 if (IsUpdateExprFound) {
7794 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
7796 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7806 llvm::FoldingSetNodeID XId, PossibleXId;
7807 Checker.getX()->Profile(XId, Context,
true);
7808 PossibleX->
Profile(PossibleXId, Context,
true);
7809 IsUpdateExprFound = XId == PossibleXId;
7810 if (IsUpdateExprFound) {
7813 E = Checker.getExpr();
7814 UE = Checker.getUpdateExpr();
7815 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7816 IsPostfixUpdate =
true;
7819 if (!IsUpdateExprFound) {
7820 IsUpdateExprFound = !Checker.checkStatement(First);
7822 if (IsUpdateExprFound) {
7824 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
7826 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
7836 llvm::FoldingSetNodeID XId, PossibleXId;
7837 Checker.getX()->Profile(XId, Context,
true);
7838 PossibleX->
Profile(PossibleXId, Context,
true);
7839 IsUpdateExprFound = XId == PossibleXId;
7840 if (IsUpdateExprFound) {
7843 E = Checker.getExpr();
7844 UE = Checker.getUpdateExpr();
7845 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
7846 IsPostfixUpdate =
false;
7850 if (!IsUpdateExprFound) {
7852 auto *FirstExpr = dyn_cast<
Expr>(
First);
7853 auto *SecondExpr = dyn_cast<
Expr>(Second);
7854 if (!FirstExpr || !SecondExpr ||
7855 !(FirstExpr->isInstantiationDependent() ||
7856 SecondExpr->isInstantiationDependent())) {
7858 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
7859 ErrorFound = NotAnAssignmentOp;
7860 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
7862 NoteRange = ErrorRange = FirstBinOp
7863 ? FirstBinOp->getSourceRange()
7867 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
7868 ErrorFound = NotAnAssignmentOp;
7869 NoteLoc = ErrorLoc = SecondBinOp
7870 ? SecondBinOp->getOperatorLoc()
7872 NoteRange = ErrorRange =
7873 SecondBinOp ? SecondBinOp->getSourceRange()
7876 Expr *PossibleXRHSInFirst =
7878 Expr *PossibleXLHSInSecond =
7880 llvm::FoldingSetNodeID X1Id, X2Id;
7881 PossibleXRHSInFirst->
Profile(X1Id, Context,
7883 PossibleXLHSInSecond->
Profile(X2Id, Context,
7885 IsUpdateExprFound = X1Id == X2Id;
7886 if (IsUpdateExprFound) {
7887 V = FirstBinOp->getLHS();
7888 X = SecondBinOp->getLHS();
7889 E = SecondBinOp->getRHS();
7891 IsXLHSInRHSPart =
false;
7892 IsPostfixUpdate =
true;
7894 ErrorFound = NotASpecificExpression;
7895 ErrorLoc = FirstBinOp->getExprLoc();
7896 ErrorRange = FirstBinOp->getSourceRange();
7897 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
7898 NoteRange = SecondBinOp->getRHS()->getSourceRange();
7906 NoteRange = ErrorRange =
7908 ErrorFound = NotTwoSubstatements;
7912 NoteRange = ErrorRange =
7914 ErrorFound = NotACompoundStatement;
7916 if (ErrorFound != NoError) {
7917 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
7919 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
7922 if (CurContext->isDependentContext())
7923 UE = V = E = X =
nullptr;
7927 setFunctionHasBranchProtectedScope();
7930 X, V, E, UE, IsXLHSInRHSPart,
7941 auto *CS = cast<CapturedStmt>(AStmt);
7948 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
7949 ThisCaptureLevel > 1; --ThisCaptureLevel) {
7963 if (
DSAStack->hasInnerTeamsRegion()) {
7965 bool OMPTeamsFound =
true;
7966 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
7967 auto I = CS->body_begin();
7968 while (I != CS->body_end()) {
7973 OMPTeamsFound =
false;
7978 assert(I != CS->body_end() &&
"Not found statement");
7984 if (!OMPTeamsFound) {
7985 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7987 diag::note_omp_nested_teams_construct_here);
7989 << isa<OMPExecutableDirective>(S);
7994 setFunctionHasBranchProtectedScope();
8006 auto *CS = cast<CapturedStmt>(AStmt);
8013 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
8014 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8024 setFunctionHasBranchProtectedScope();
8036 auto *CS = cast<CapturedStmt>(AStmt);
8043 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8044 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8057 unsigned NestedLoopCount =
8060 VarsWithImplicitDSA, B);
8061 if (NestedLoopCount == 0)
8064 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8065 "omp target parallel for loop exprs were not built");
8067 if (!CurContext->isDependentContext()) {
8070 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8078 setFunctionHasBranchProtectedScope();
8080 NestedLoopCount, Clauses, AStmt,
8087 return llvm::any_of(
8091 template <
typename... Params>
8093 const Params... ClauseTypes) {
8104 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8108 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
8109 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
8110 <<
"'map' or 'use_device_ptr'" 8115 setFunctionHasBranchProtectedScope();
8128 auto *CS = cast<CapturedStmt>(AStmt);
8135 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
8136 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8149 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
8165 auto *CS = cast<CapturedStmt>(AStmt);
8172 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
8173 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8186 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
8202 auto *CS = cast<CapturedStmt>(AStmt);
8209 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
8210 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8220 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
8221 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
8234 auto *CS = cast<CapturedStmt>(AStmt);
8242 setFunctionHasBranchProtectedScope();
8244 DSAStack->setParentTeamsRegionLoc(StartLoc);
8253 if (
DSAStack->isParentNowaitRegion()) {
8254 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
8257 if (
DSAStack->isParentOrderedRegion()) {
8258 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
8269 if (
DSAStack->isParentNowaitRegion()) {
8270 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
8273 if (
DSAStack->isParentOrderedRegion()) {
8274 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
8277 DSAStack->setParentCancelRegion(
true);
8283 ArrayRef<OMPClause *> Clauses) {
8285 bool ErrorFound =
false;
8287 if (
C->getClauseKind() == OMPC_grainsize ||
8288 C->getClauseKind() == OMPC_num_tasks) {
8292 S.
Diag(
C->getBeginLoc(),
8293 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
8297 diag::note_omp_previous_grainsize_num_tasks)
8307 ArrayRef<OMPClause *> Clauses) {
8308 const OMPClause *ReductionClause =
nullptr;
8309 const OMPClause *NogroupClause =
nullptr;
8311 if (
C->getClauseKind() == OMPC_reduction) {
8312 ReductionClause =
C;
8317 if (
C->getClauseKind() == OMPC_nogroup) {
8319 if (ReductionClause)
8324 if (ReductionClause && NogroupClause) {
8325 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
8339 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8343 unsigned NestedLoopCount =
8346 VarsWithImplicitDSA, B);
8347 if (NestedLoopCount == 0)
8350 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8351 "omp for loop exprs were not built");
8364 setFunctionHasBranchProtectedScope();
8366 NestedLoopCount, Clauses, AStmt, B);
8375 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8379 unsigned NestedLoopCount =
8382 VarsWithImplicitDSA, B);
8383 if (NestedLoopCount == 0)
8386 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8387 "omp for loop exprs were not built");
8389 if (!CurContext->isDependentContext()) {
8392 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8413 setFunctionHasBranchProtectedScope();
8415 NestedLoopCount, Clauses, AStmt, B);
8424 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8428 unsigned NestedLoopCount =
8431 *
this, *
DSAStack, VarsWithImplicitDSA, B);
8432 if (NestedLoopCount == 0)
8435 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8436 "omp for loop exprs were not built");
8438 setFunctionHasBranchProtectedScope();
8440 NestedLoopCount, Clauses, AStmt, B);
8449 auto *CS = cast<CapturedStmt>(AStmt);
8456 for (
int ThisCaptureLevel =
8457 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
8458 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8474 VarsWithImplicitDSA, B);
8475 if (NestedLoopCount == 0)
8478 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8479 "omp for loop exprs were not built");
8481 setFunctionHasBranchProtectedScope();
8483 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8493 auto *CS = cast<CapturedStmt>(AStmt);
8500 for (
int ThisCaptureLevel =
8501 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
8502 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8518 VarsWithImplicitDSA, B);
8519 if (NestedLoopCount == 0)
8522 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8523 "omp for loop exprs were not built");
8525 if (!CurContext->isDependentContext()) {
8528 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8539 setFunctionHasBranchProtectedScope();
8541 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8550 auto *CS = cast<CapturedStmt>(AStmt);
8557 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
8558 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8571 unsigned NestedLoopCount =
8573 nullptr , CS, *
this,
8574 *
DSAStack, VarsWithImplicitDSA, B);
8575 if (NestedLoopCount == 0)
8578 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8579 "omp for loop exprs were not built");
8581 if (!CurContext->isDependentContext()) {
8584 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8595 setFunctionHasBranchProtectedScope();
8597 NestedLoopCount, Clauses, AStmt, B);
8606 auto *CS = cast<CapturedStmt>(AStmt);
8613 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
8614 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8630 VarsWithImplicitDSA, B);
8631 if (NestedLoopCount == 0)
8634 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8635 "omp target parallel for simd loop exprs were not built");
8637 if (!CurContext->isDependentContext()) {
8640 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8650 setFunctionHasBranchProtectedScope();
8652 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8661 auto *CS = cast<CapturedStmt>(AStmt);
8668 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
8669 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8682 unsigned NestedLoopCount =
8685 VarsWithImplicitDSA, B);
8686 if (NestedLoopCount == 0)
8689 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8690 "omp target simd loop exprs were not built");
8692 if (!CurContext->isDependentContext()) {
8695 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8706 setFunctionHasBranchProtectedScope();
8708 NestedLoopCount, Clauses, AStmt, B);
8717 auto *CS = cast<CapturedStmt>(AStmt);
8724 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
8725 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8738 unsigned NestedLoopCount =
8740 nullptr , CS, *
this,
8741 *
DSAStack, VarsWithImplicitDSA, B);
8742 if (NestedLoopCount == 0)
8745 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8746 "omp teams distribute loop exprs were not built");
8748 setFunctionHasBranchProtectedScope();
8750 DSAStack->setParentTeamsRegionLoc(StartLoc);
8753 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8762 auto *CS = cast<CapturedStmt>(AStmt);
8769 for (
int ThisCaptureLevel =
8770 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
8771 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8788 VarsWithImplicitDSA, B);
8790 if (NestedLoopCount == 0)
8793 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8794 "omp teams distribute simd loop exprs were not built");
8796 if (!CurContext->isDependentContext()) {
8799 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8810 setFunctionHasBranchProtectedScope();
8812 DSAStack->setParentTeamsRegionLoc(StartLoc);
8815 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8824 auto *CS = cast<CapturedStmt>(AStmt);
8832 for (
int ThisCaptureLevel =
8833 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
8834 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8850 VarsWithImplicitDSA, B);
8852 if (NestedLoopCount == 0)
8855 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8856 "omp for loop exprs were not built");
8858 if (!CurContext->isDependentContext()) {
8861 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8872 setFunctionHasBranchProtectedScope();
8874 DSAStack->setParentTeamsRegionLoc(StartLoc);
8877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8886 auto *CS = cast<CapturedStmt>(AStmt);
8894 for (
int ThisCaptureLevel =
8895 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
8896 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8912 VarsWithImplicitDSA, B);
8914 if (NestedLoopCount == 0)
8917 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8918 "omp for loop exprs were not built");
8920 setFunctionHasBranchProtectedScope();
8922 DSAStack->setParentTeamsRegionLoc(StartLoc);
8925 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8936 auto *CS = cast<CapturedStmt>(AStmt);
8944 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
8945 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8954 setFunctionHasBranchProtectedScope();
8966 auto *CS = cast<CapturedStmt>(AStmt);
8973 for (
int ThisCaptureLevel =
8974 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8975 ThisCaptureLevel > 1; --ThisCaptureLevel) {
8991 VarsWithImplicitDSA, B);
8992 if (NestedLoopCount == 0)
8995 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8996 "omp target teams distribute loop exprs were not built");
8998 setFunctionHasBranchProtectedScope();
9000 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9009 auto *CS = cast<CapturedStmt>(AStmt);
9016 for (
int ThisCaptureLevel =
9017 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
9018 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9034 VarsWithImplicitDSA, B);
9035 if (NestedLoopCount == 0)
9038 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9039 "omp target teams distribute parallel for loop exprs were not built");
9041 if (!CurContext->isDependentContext()) {
9044 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9052 setFunctionHasBranchProtectedScope();
9054 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9064 auto *CS = cast<CapturedStmt>(AStmt);
9071 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(
9072 OMPD_target_teams_distribute_parallel_for_simd);
9073 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9086 unsigned NestedLoopCount =
9089 nullptr , CS, *
this,
9090 *
DSAStack, VarsWithImplicitDSA, B);
9091 if (NestedLoopCount == 0)
9094 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9095 "omp target teams distribute parallel for simd loop exprs were not " 9098 if (!CurContext->isDependentContext()) {
9101 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9112 setFunctionHasBranchProtectedScope();
9114 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9123 auto *CS = cast<CapturedStmt>(AStmt);
9130 for (
int ThisCaptureLevel =
9131 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
9132 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9148 VarsWithImplicitDSA, B);
9149 if (NestedLoopCount == 0)
9152 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9153 "omp target teams distribute simd loop exprs were not built");
9155 if (!CurContext->isDependentContext()) {
9158 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9169 setFunctionHasBranchProtectedScope();
9171 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9181 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
9183 case OMPC_num_threads:
9184 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
9187 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
9190 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
9192 case OMPC_allocator:
9193 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
9196 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
9199 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
9202 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
9204 case OMPC_num_teams:
9205 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
9207 case OMPC_thread_limit:
9208 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
9211 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
9213 case OMPC_grainsize:
9214 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
9216 case OMPC_num_tasks:
9217 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
9220 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
9224 case OMPC_proc_bind:
9227 case OMPC_firstprivate:
9228 case OMPC_lastprivate:
9230 case OMPC_reduction:
9231 case OMPC_task_reduction:
9232 case OMPC_in_reduction:
9236 case OMPC_copyprivate:
9239 case OMPC_mergeable:
9253 case OMPC_dist_schedule:
9254 case OMPC_defaultmap:
9259 case OMPC_use_device_ptr:
9260 case OMPC_is_device_ptr:
9261 case OMPC_unified_address:
9262 case OMPC_unified_shared_memory:
9263 case OMPC_reverse_offload:
9264 case OMPC_dynamic_allocators:
9265 case OMPC_atomic_default_mem_order:
9266 llvm_unreachable(
"Clause is not allowed.");
9283 case OMPD_target_parallel:
9284 case OMPD_target_parallel_for:
9285 case OMPD_target_parallel_for_simd:
9288 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
9289 CaptureRegion = OMPD_target;
9291 case OMPD_target_teams_distribute_parallel_for:
9292 case OMPD_target_teams_distribute_parallel_for_simd:
9295 if (NameModifier ==
OMPD_unknown || NameModifier == OMPD_parallel)
9296 CaptureRegion = OMPD_teams;
9298 case OMPD_teams_distribute_parallel_for:
9299 case OMPD_teams_distribute_parallel_for_simd:
9300 CaptureRegion = OMPD_teams;
9302 case OMPD_target_update:
9303 case OMPD_target_enter_data:
9304 case OMPD_target_exit_data:
9305 CaptureRegion = OMPD_task;
9309 case OMPD_parallel_sections:
9310 case OMPD_parallel_for:
9311 case OMPD_parallel_for_simd:
9313 case OMPD_target_simd:
9314 case OMPD_target_teams:
9315 case OMPD_target_teams_distribute:
9316 case OMPD_target_teams_distribute_simd:
9317 case OMPD_distribute_parallel_for:
9318 case OMPD_distribute_parallel_for_simd:
9321 case OMPD_taskloop_simd:
9322 case OMPD_target_data:
9325 case OMPD_threadprivate:
9327 case OMPD_taskyield:
9330 case OMPD_cancellation_point:
9332 case OMPD_declare_reduction:
9333 case OMPD_declare_mapper:
9334 case OMPD_declare_simd:
9335 case OMPD_declare_target:
9336 case OMPD_end_declare_target:
9346 case OMPD_taskgroup:
9347 case OMPD_distribute:
9350 case OMPD_distribute_simd:
9351 case OMPD_teams_distribute:
9352 case OMPD_teams_distribute_simd:
9354 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
9356 llvm_unreachable(
"Unknown OpenMP directive");
9359 case OMPC_num_threads:
9361 case OMPD_target_parallel:
9362 case OMPD_target_parallel_for:
9363 case OMPD_target_parallel_for_simd:
9364 CaptureRegion = OMPD_target;
9366 case OMPD_teams_distribute_parallel_for:
9367 case OMPD_teams_distribute_parallel_for_simd:
9368 case OMPD_target_teams_distribute_parallel_for:
9369 case OMPD_target_teams_distribute_parallel_for_simd:
9370 CaptureRegion = OMPD_teams;
9373 case OMPD_parallel_sections:
9374 case OMPD_parallel_for:
9375 case OMPD_parallel_for_simd:
9376 case OMPD_distribute_parallel_for:
9377 case OMPD_distribute_parallel_for_simd:
9380 case OMPD_target_data:
9381 case OMPD_target_enter_data:
9382 case OMPD_target_exit_data:
9383 case OMPD_target_update:
9385 case OMPD_target_simd:
9386 case OMPD_target_teams:
9387 case OMPD_target_teams_distribute:
9388 case OMPD_target_teams_distribute_simd:
9392 case OMPD_taskloop_simd:
9393 case OMPD_threadprivate:
9395 case OMPD_taskyield:
9398 case OMPD_cancellation_point:
9400 case OMPD_declare_reduction:
9401 case OMPD_declare_mapper:
9402 case OMPD_declare_simd:
9403 case OMPD_declare_target:
9404 case OMPD_end_declare_target:
9414 case OMPD_taskgroup:
9415 case OMPD_distribute:
9418 case OMPD_distribute_simd:
9419 case OMPD_teams_distribute:
9420 case OMPD_teams_distribute_simd:
9422 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
9424 llvm_unreachable(
"Unknown OpenMP directive");
9427 case OMPC_num_teams:
9429 case OMPD_target_teams:
9430 case OMPD_target_teams_distribute:
9431 case OMPD_target_teams_distribute_simd:
9432 case OMPD_target_teams_distribute_parallel_for:
9433 case OMPD_target_teams_distribute_parallel_for_simd:
9434 CaptureRegion = OMPD_target;
9436 case OMPD_teams_distribute_parallel_for:
9437 case OMPD_teams_distribute_parallel_for_simd:
9439 case OMPD_teams_distribute:
9440 case OMPD_teams_distribute_simd:
9443 case OMPD_distribute_parallel_for:
9444 case OMPD_distribute_parallel_for_simd:
9447 case OMPD_taskloop_simd:
9448 case OMPD_target_data:
9449 case OMPD_target_enter_data:
9450 case OMPD_target_exit_data:
9451 case OMPD_target_update:
9454 case OMPD_parallel_sections:
9455 case OMPD_parallel_for:
9456 case OMPD_parallel_for_simd:
9458 case OMPD_target_simd:
9459 case OMPD_target_parallel:
9460 case OMPD_target_parallel_for:
9461 case OMPD_target_parallel_for_simd:
9462 case OMPD_threadprivate:
9464 case OMPD_taskyield:
9467 case OMPD_cancellation_point:
9469 case OMPD_declare_reduction:
9470 case OMPD_declare_mapper:
9471 case OMPD_declare_simd:
9472 case OMPD_declare_target:
9473 case OMPD_end_declare_target:
9482 case OMPD_taskgroup:
9483 case OMPD_distribute:
9486 case OMPD_distribute_simd:
9488 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
9490 llvm_unreachable(
"Unknown OpenMP directive");
9493 case OMPC_thread_limit:
9495 case OMPD_target_teams:
9496 case OMPD_target_teams_distribute:
9497 case OMPD_target_teams_distribute_simd:
9498 case OMPD_target_teams_distribute_parallel_for:
9499 case OMPD_target_teams_distribute_parallel_for_simd:
9500 CaptureRegion = OMPD_target;
9502 case OMPD_teams_distribute_parallel_for:
9503 case OMPD_teams_distribute_parallel_for_simd:
9505 case OMPD_teams_distribute:
9506 case OMPD_teams_distribute_simd:
9509 case OMPD_distribute_parallel_for:
9510 case OMPD_distribute_parallel_for_simd:
9513 case OMPD_taskloop_simd:
9514 case OMPD_target_data:
9515 case OMPD_target_enter_data:
9516 case OMPD_target_exit_data:
9517 case OMPD_target_update:
9520 case OMPD_parallel_sections:
9521 case OMPD_parallel_for:
9522 case OMPD_parallel_for_simd:
9524 case OMPD_target_simd:
9525 case OMPD_target_parallel:
9526 case OMPD_target_parallel_for:
9527 case OMPD_target_parallel_for_simd:
9528 case OMPD_threadprivate:
9530 case OMPD_taskyield:
9533 case OMPD_cancellation_point:
9535 case OMPD_declare_reduction:
9536 case OMPD_declare_mapper:
9537 case OMPD_declare_simd:
9538 case OMPD_declare_target:
9539 case OMPD_end_declare_target:
9548 case OMPD_taskgroup:
9549 case OMPD_distribute:
9552 case OMPD_distribute_simd:
9554 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
9556 llvm_unreachable(
"Unknown OpenMP directive");
9561 case OMPD_parallel_for:
9562 case OMPD_parallel_for_simd:
9563 case OMPD_distribute_parallel_for:
9564 case OMPD_distribute_parallel_for_simd:
9565 case OMPD_teams_distribute_parallel_for:
9566 case OMPD_teams_distribute_parallel_for_simd:
9567 case OMPD_target_parallel_for:
9568 case OMPD_target_parallel_for_simd:
9569 case OMPD_target_teams_distribute_parallel_for:
9570 case OMPD_target_teams_distribute_parallel_for_simd:
9571 CaptureRegion = OMPD_parallel;
9579 case OMPD_taskloop_simd:
9580 case OMPD_target_data:
9581 case OMPD_target_enter_data:
9582 case OMPD_target_exit_data:
9583 case OMPD_target_update:
9585 case OMPD_teams_distribute:
9586 case OMPD_teams_distribute_simd:
9587 case OMPD_target_teams_distribute:
9588 case OMPD_target_teams_distribute_simd:
9590 case OMPD_target_simd:
9591 case OMPD_target_parallel:
9594 case OMPD_parallel_sections:
9595 case OMPD_threadprivate:
9597 case OMPD_taskyield:
9600 case OMPD_cancellation_point:
9602 case OMPD_declare_reduction:
9603 case OMPD_declare_mapper:
9604 case OMPD_declare_simd:
9605 case OMPD_declare_target:
9606 case OMPD_end_declare_target:
9613 case OMPD_taskgroup:
9614 case OMPD_distribute:
9617 case OMPD_distribute_simd:
9618 case OMPD_target_teams:
9620 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
9622 llvm_unreachable(
"Unknown OpenMP directive");
9625 case OMPC_dist_schedule:
9627 case OMPD_teams_distribute_parallel_for:
9628 case OMPD_teams_distribute_parallel_for_simd:
9629 case OMPD_teams_distribute:
9630 case OMPD_teams_distribute_simd:
9631 case OMPD_target_teams_distribute_parallel_for:
9632 case OMPD_target_teams_distribute_parallel_for_simd:
9633 case OMPD_target_teams_distribute:
9634 case OMPD_target_teams_distribute_simd:
9635 CaptureRegion = OMPD_teams;
9637 case OMPD_distribute_parallel_for:
9638 case OMPD_distribute_parallel_for_simd:
9639 case OMPD_distribute:
9640 case OMPD_distribute_simd:
9643 case OMPD_parallel_for:
9644 case OMPD_parallel_for_simd:
9645 case OMPD_target_parallel_for_simd:
9646 case OMPD_target_parallel_for:
9649 case OMPD_taskloop_simd:
9650 case OMPD_target_data:
9651 case OMPD_target_enter_data:
9652 case OMPD_target_exit_data:
9653 case OMPD_target_update:
9656 case OMPD_target_simd:
9657 case OMPD_target_parallel:
9660 case OMPD_parallel_sections:
9661 case OMPD_threadprivate:
9663 case OMPD_taskyield:
9666 case OMPD_cancellation_point:
9668 case OMPD_declare_reduction:
9669 case OMPD_declare_mapper:
9670 case OMPD_declare_simd:
9671 case OMPD_declare_target:
9672 case OMPD_end_declare_target:
9681 case OMPD_taskgroup:
9684 case OMPD_target_teams:
9686 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
9688 llvm_unreachable(
"Unknown OpenMP directive");
9693 case OMPD_target_update:
9694 case OMPD_target_enter_data:
9695 case OMPD_target_exit_data:
9697 case OMPD_target_simd:
9698 case OMPD_target_teams:
9699 case OMPD_target_parallel:
9700 case OMPD_target_teams_distribute:
9701 case OMPD_target_teams_distribute_simd:
9702 case OMPD_target_parallel_for:
9703 case OMPD_target_parallel_for_simd:
9704 case OMPD_target_teams_distribute_parallel_for:
9705 case OMPD_target_teams_distribute_parallel_for_simd:
9706 CaptureRegion = OMPD_task;
9708 case OMPD_target_data:
9711 case OMPD_teams_distribute_parallel_for:
9712 case OMPD_teams_distribute_parallel_for_simd:
9714 case OMPD_teams_distribute:
9715 case OMPD_teams_distribute_simd:
9716 case OMPD_distribute_parallel_for:
9717 case OMPD_distribute_parallel_for_simd:
9720 case OMPD_taskloop_simd:
9723 case OMPD_parallel_sections:
9724 case OMPD_parallel_for:
9725 case OMPD_parallel_for_simd:
9726 case OMPD_threadprivate:
9728 case OMPD_taskyield:
9731 case OMPD_cancellation_point:
9733 case OMPD_declare_reduction:
9734 case OMPD_declare_mapper:
9735 case OMPD_declare_simd:
9736 case OMPD_declare_target:
9737 case OMPD_end_declare_target:
9746 case OMPD_taskgroup:
9747 case OMPD_distribute:
9750 case OMPD_distribute_simd:
9752 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
9754 llvm_unreachable(
"Unknown OpenMP directive");
9757 case OMPC_firstprivate:
9758 case OMPC_lastprivate:
9759 case OMPC_reduction:
9760 case OMPC_task_reduction:
9761 case OMPC_in_reduction:
9764 case OMPC_proc_bind:
9768 case OMPC_allocator:
9774 case OMPC_copyprivate:
9778 case OMPC_mergeable:
9792 case OMPC_grainsize:
9794 case OMPC_num_tasks:
9796 case OMPC_defaultmap:
9801 case OMPC_use_device_ptr:
9802 case OMPC_is_device_ptr:
9803 case OMPC_unified_address:
9804 case OMPC_unified_shared_memory:
9805 case OMPC_reverse_offload:
9806 case OMPC_dynamic_allocators:
9807 case OMPC_atomic_default_mem_order:
9808 llvm_unreachable(
"Unexpected OpenMP clause.");
9810 return CaptureRegion;
9819 Expr *ValExpr = Condition;
9820 Stmt *HelperValStmt =
nullptr;
9825 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
9829 ValExpr = Val.
get();
9834 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
9835 ValExpr = MakeFullExpr(ValExpr).get();
9836 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9837 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
9842 return new (Context)
9843 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
9844 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
9851 Expr *ValExpr = Condition;
9855 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
9859 ValExpr = MakeFullExpr(Val.
get()).
get();
9862 return new (Context)
OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
9871 IntConvertDiagnoser()
9875 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
9879 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
9884 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
9893 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
9902 llvm_unreachable(
"conversion functions are permitted");
9905 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
9910 bool StrictlyPositive) {
9919 ValExpr = Value.
get();
9923 Result.isSigned() &&
9924 !((!StrictlyPositive && Result.isNonNegative()) ||
9925 (StrictlyPositive && Result.isStrictlyPositive()))) {
9926 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
9939 Expr *ValExpr = NumThreads;
9940 Stmt *HelperValStmt =
nullptr;
9951 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
9952 ValExpr = MakeFullExpr(ValExpr).get();
9953 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9954 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
9959 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
9964 bool StrictlyPositive) {
9971 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
9974 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
9975 (!StrictlyPositive && !Result.isNonNegative())) {
9976 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
9981 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9986 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
9987 DSAStack->setAssociatedLoops(Result.getExtValue());
9988 else if (CKind == OMPC_ordered)
9989 DSAStack->setAssociatedLoops(Result.getExtValue());
9999 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
10002 return new (Context)
10012 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
10015 return new (Context)
10021 DSAStackTy *Stack) {
10022 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
10023 if (!OMPAllocatorHandleT.
isNull())
10026 bool ErrorFound =
false;
10027 for (
int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
10028 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
10029 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
10030 StringRef Allocator =
10031 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
10033 auto *VD = dyn_cast_or_null<ValueDecl>(
10046 if (OMPAllocatorHandleT.
isNull())
10047 OMPAllocatorHandleT = AllocatorType;
10052 Stack->setAllocator(AllocatorKind, Res.
get());
10055 S.
Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
10059 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
10071 ExprResult Allocator = DefaultLvalueConversion(A);
10074 Allocator = PerformImplicitConversion(Allocator.
get(),
10075 DSAStack->getOMPAllocatorHandleT(),
10080 return new (Context)
10094 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
10097 return new (Context)
10104 Expr *NumForLoops) {
10110 if (NumForLoops && LParenLoc.
isValid()) {
10112 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
10115 NumForLoops = NumForLoopsResult.
get();
10117 NumForLoops =
nullptr;
10120 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
10121 StartLoc, LParenLoc, EndLoc);
10122 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
10133 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
10134 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
10136 case OMPC_proc_bind:
10137 Res = ActOnOpenMPProcBindClause(
10138 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
10139 LParenLoc, EndLoc);
10141 case OMPC_atomic_default_mem_order:
10142 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
10143 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
10144 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
10148 case OMPC_num_threads:
10151 case OMPC_allocator:
10152 case OMPC_collapse:
10153 case OMPC_schedule:
10155 case OMPC_firstprivate:
10156 case OMPC_lastprivate:
10158 case OMPC_reduction:
10159 case OMPC_task_reduction:
10160 case OMPC_in_reduction:
10164 case OMPC_copyprivate:
10168 case OMPC_mergeable:
10170 case OMPC_allocate:
10182 case OMPC_num_teams:
10183 case OMPC_thread_limit:
10184 case OMPC_priority:
10185 case OMPC_grainsize:
10187 case OMPC_num_tasks:
10189 case OMPC_dist_schedule:
10190 case OMPC_defaultmap:
10195 case OMPC_use_device_ptr:
10196 case OMPC_is_device_ptr:
10197 case OMPC_unified_address:
10198 case OMPC_unified_shared_memory:
10199 case OMPC_reverse_offload:
10200 case OMPC_dynamic_allocators:
10201 llvm_unreachable(
"Clause is not allowed.");
10210 llvm::raw_svector_ostream Out(Buffer);
10211 unsigned Bound = Last >= 2 ? Last - 2 : 0;
10212 unsigned Skipped = Exclude.size();
10213 auto S = Exclude.begin(), E = Exclude.end();
10214 for (
unsigned I = First; I <
Last; ++I) {
10215 if (std::find(S, E, I) != E) {
10220 if (I == Bound - Skipped)
10222 else if (I != Bound + 1 - Skipped)
10235 "OMPC_DEFAULT_unknown not greater than 0");
10236 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
10243 case OMPC_DEFAULT_none:
10244 DSAStack->setDefaultDSANone(KindKwLoc);
10246 case OMPC_DEFAULT_shared:
10247 DSAStack->setDefaultDSAShared(KindKwLoc);
10250 llvm_unreachable(
"Clause kind is not allowed.");
10253 return new (Context)
10263 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
10269 return new (Context)
10277 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
10279 OMPC_atomic_default_mem_order, 0,
10285 LParenLoc, EndLoc);
10295 case OMPC_schedule:
10296 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
10297 assert(Argument.size() == NumberOfElements &&
10298 ArgumentLoc.size() == NumberOfElements);
10299 Res = ActOnOpenMPScheduleClause(
10300 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
10301 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
10302 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
10303 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
10304 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
10307 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
10308 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
10309 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
10312 case OMPC_dist_schedule:
10313 Res = ActOnOpenMPDistScheduleClause(
10314 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
10315 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
10317 case OMPC_defaultmap:
10318 enum {
Modifier, DefaultmapKind };
10319 Res = ActOnOpenMPDefaultmapClause(
10320 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
10321 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
10322 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
10326 case OMPC_num_threads:
10329 case OMPC_allocator:
10330 case OMPC_collapse:
10332 case OMPC_proc_bind:
10334 case OMPC_firstprivate:
10335 case OMPC_lastprivate:
10337 case OMPC_reduction:
10338 case OMPC_task_reduction:
10339 case OMPC_in_reduction:
10343 case OMPC_copyprivate:
10347 case OMPC_mergeable:
10349 case OMPC_allocate:
10361 case OMPC_num_teams:
10362 case OMPC_thread_limit:
10363 case OMPC_priority:
10364 case OMPC_grainsize:
10366 case OMPC_num_tasks:
10372 case OMPC_use_device_ptr:
10373 case OMPC_is_device_ptr:
10374 case OMPC_unified_address:
10375 case OMPC_unified_shared_memory:
10376 case OMPC_reverse_offload:
10377 case OMPC_dynamic_allocators:
10378 case OMPC_atomic_default_mem_order:
10379 llvm_unreachable(
"Clause is not allowed.");
10390 Excluded.push_back(M2);
10391 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
10392 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
10393 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
10394 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
10395 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
10418 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
10419 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
10420 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
10421 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
10422 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
10428 std::string Values;
10438 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
10445 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
10446 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
10447 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
10448 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
10449 diag::err_omp_schedule_nonmonotonic_static);
10452 Expr *ValExpr = ChunkSize;
10453 Stmt *HelperValStmt =
nullptr;
10460 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
10464 ValExpr = Val.
get();
10471 if (Result.isSigned() && !Result.isStrictlyPositive()) {
10472 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
10477 DSAStack->getCurrentDirective(), OMPC_schedule) !=
10479 !CurContext->isDependentContext()) {
10480 ValExpr = MakeFullExpr(ValExpr).get();
10481 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
10482 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
10488 return new (Context)
10490 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
10499 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
10502 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
10505 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
10507 case OMPC_mergeable:
10508 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
10511 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
10514 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
10517 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
10520 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
10523 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
10526 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
10529 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
10532 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
10534 case OMPC_unified_address:
10535 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
10537 case OMPC_unified_shared_memory:
10538 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
10540 case OMPC_reverse_offload:
10541 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
10543 case OMPC_dynamic_allocators:
10544 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
10548 case OMPC_num_threads:
10551 case OMPC_allocator:
10552 case OMPC_collapse:
10553 case OMPC_schedule:
10555 case OMPC_firstprivate:
10556 case OMPC_lastprivate:
10558 case OMPC_reduction:
10559 case OMPC_task_reduction:
10560 case OMPC_in_reduction:
10564 case OMPC_copyprivate:
10566 case OMPC_proc_bind:
10568 case OMPC_allocate:
10573 case OMPC_num_teams:
10574 case OMPC_thread_limit:
10575 case OMPC_priority:
10576 case OMPC_grainsize:
10577 case OMPC_num_tasks:
10579 case OMPC_dist_schedule:
10580 case OMPC_defaultmap:
10585 case OMPC_use_device_ptr:
10586 case OMPC_is_device_ptr:
10587 case OMPC_atomic_default_mem_order:
10588 llvm_unreachable(
"Clause is not allowed.");
10684 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10686 case OMPC_firstprivate:
10687 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10689 case OMPC_lastprivate:
10690 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10693 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
10695 case OMPC_reduction:
10696 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10697 EndLoc, ReductionOrMapperIdScopeSpec,
10698 ReductionOrMapperId);
10700 case OMPC_task_reduction:
10701 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10702 EndLoc, ReductionOrMapperIdScopeSpec,
10703 ReductionOrMapperId);
10705 case OMPC_in_reduction:
10706 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
10707 EndLoc, ReductionOrMapperIdScopeSpec,
10708 ReductionOrMapperId);
10711 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
10712 LinKind, DepLinMapLoc, ColonLoc, EndLoc);
10715 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
10719 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
10721 case OMPC_copyprivate:
10722 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
10725 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
10728 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
10729 StartLoc, LParenLoc, EndLoc);
10732 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc,
10733 ReductionOrMapperIdScopeSpec,
10734 ReductionOrMapperId, MapType, IsMapTypeImplicit,
10735 DepLinMapLoc, ColonLoc, VarList, Locs);
10738 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
10739 ReductionOrMapperId, Locs);
10742 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
10743 ReductionOrMapperId, Locs);
10745 case OMPC_use_device_ptr:
10746 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
10748 case OMPC_is_device_ptr:
10749 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
10751 case OMPC_allocate:
10752 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
10757 case OMPC_num_threads:
10760 case OMPC_allocator:
10761 case OMPC_collapse:
10763 case OMPC_proc_bind:
10764 case OMPC_schedule:
10768 case OMPC_mergeable:
10778 case OMPC_num_teams:
10779 case OMPC_thread_limit:
10780 case OMPC_priority:
10781 case OMPC_grainsize:
10783 case OMPC_num_tasks:
10785 case OMPC_dist_schedule:
10786 case OMPC_defaultmap:
10789 case OMPC_unified_address:
10790 case OMPC_unified_shared_memory:
10791 case OMPC_reverse_offload:
10792 case OMPC_dynamic_allocators:
10793 case OMPC_atomic_default_mem_order:
10794 llvm_unreachable(
"Clause is not allowed.");
10805 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
10806 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
10811 Res = DefaultLvalueConversion(Res.
get());
10824 for (
Expr *RefExpr : VarList) {
10825 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
10828 Expr *SimpleRefExpr = RefExpr;
10832 Vars.push_back(RefExpr);
10833 PrivateCopies.push_back(
nullptr);
10840 auto *VD = dyn_cast<
VarDecl>(D);
10845 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
10867 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
10868 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
10879 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10886 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10896 if (
DSAStack->checkMappableExprComponentListsForDecl(
10900 ConflictKind = WhereFoundClauseKind;
10903 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10925 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
10926 ActOnUninitializedDecl(VDPrivate);
10933 if (!VD && !CurContext->isDependentContext())
10935 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
10936 Vars.push_back((VD || CurContext->isDependentContext())
10937 ? RefExpr->IgnoreParens()
10939 PrivateCopies.push_back(VDPrivateRefExpr);
10950 class DiagsUninitializedSeveretyRAII {
10954 bool IsIgnored =
false;
10959 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
10961 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
10965 ~DiagsUninitializedSeveretyRAII() {
10980 bool IsImplicitClause =
10984 for (
Expr *RefExpr : VarList) {
10985 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
10988 Expr *SimpleRefExpr = RefExpr;
10992 Vars.push_back(RefExpr);
10993 PrivateCopies.push_back(
nullptr);
10994 Inits.push_back(
nullptr);
11000 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
11002 auto *VD = dyn_cast<
VarDecl>(D);
11007 if (RequireCompleteType(ELoc, Type,
11008 diag::err_omp_firstprivate_incomplete_type))
11019 DSAStackTy::DSAVarData TopDVar;
11020 if (!IsImplicitClause) {
11021 DSAStackTy::DSAVarData DVar =
11025 bool IsConstant = ElemType.
isConstant(Context);
11033 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
11035 DVar.CKind != OMPC_lastprivate) &&
11037 Diag(ELoc, diag::err_omp_wrong_dsa)
11055 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
11056 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
11057 Diag(ELoc, diag::err_omp_wrong_dsa)
11083 DVar =
DSAStack->getImplicitDSA(D,
true);
11084 if (DVar.CKind != OMPC_shared &&
11088 Diag(ELoc, diag::err_omp_required_access)
11115 if (DVar.CKind == OMPC_reduction &&
11119 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
11131 if (
DSAStack->checkMappableExprComponentListsForDecl(
11136 ConflictKind = WhereFoundClauseKind;
11139 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
11152 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11159 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11168 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
11174 Expr *VDInitRefExpr =
nullptr;
11181 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
11184 ".firstprivate.temp");
11199 ".firstprivate.temp");
11201 RefExpr->getExprLoc());
11202 AddInitializerToDecl(VDPrivate,
11203 DefaultLvalueConversion(VDInitRefExpr).
get(),
11207 if (IsImplicitClause) {
11208 Diag(RefExpr->getExprLoc(),
11209 diag::note_omp_task_predetermined_firstprivate_here);
11213 CurContext->addDecl(VDPrivate);
11216 RefExpr->getExprLoc());
11218 if (!VD && !CurContext->isDependentContext()) {
11219 if (TopDVar.CKind == OMPC_lastprivate) {
11220 Ref = TopDVar.PrivateCopy;
11223 if (!isOpenMPCapturedDecl(D))
11224 ExprCaptures.push_back(Ref->getDecl());
11227 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
11228 Vars.push_back((VD || CurContext->isDependentContext())
11229 ? RefExpr->IgnoreParens()
11231 PrivateCopies.push_back(VDPrivateRefExpr);
11232 Inits.push_back(VDInitRefExpr);
11239 Vars, PrivateCopies, Inits,
11253 for (
Expr *RefExpr : VarList) {
11254 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
11257 Expr *SimpleRefExpr = RefExpr;
11261 Vars.push_back(RefExpr);
11262 SrcExprs.push_back(
nullptr);
11263 DstExprs.push_back(
nullptr);
11264 AssignmentOps.push_back(
nullptr);
11271 auto *VD = dyn_cast<
VarDecl>(D);
11276 if (RequireCompleteType(ELoc, Type,
11277 diag::err_omp_lastprivate_incomplete_type))
11301 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
11302 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
11304 DVar.CKind != OMPC_firstprivate) &&
11305 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
11306 Diag(ELoc, diag::err_omp_wrong_dsa)
11319 DSAStackTy::DSAVarData TopDVar = DVar;
11323 DVar =
DSAStack->getImplicitDSA(D,
true);
11324 if (DVar.CKind != OMPC_shared) {
11325 Diag(ELoc, diag::err_omp_required_access)
11353 ExprResult AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
11354 PseudoDstExpr, PseudoSrcExpr);
11358 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
11363 if (!VD && !CurContext->isDependentContext()) {
11364 if (TopDVar.CKind == OMPC_firstprivate) {
11365 Ref = TopDVar.PrivateCopy;
11368 if (!isOpenMPCapturedDecl(D))
11369 ExprCaptures.push_back(Ref->
getDecl());
11371 if (TopDVar.CKind == OMPC_firstprivate ||
11372 (!isOpenMPCapturedDecl(D) &&
11374 ExprResult RefRes = DefaultLvalueConversion(Ref);
11378 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11382 ExprPostUpdates.push_back(
11383 IgnoredValueConversions(PostUpdateRes.
get()).
get());
11386 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
11387 Vars.push_back((VD || CurContext->isDependentContext())
11388 ? RefExpr->IgnoreParens()
11390 SrcExprs.push_back(PseudoSrcExpr);
11391 DstExprs.push_back(PseudoDstExpr);
11392 AssignmentOps.push_back(AssignmentOp.
get());
11399 Vars, SrcExprs, DstExprs, AssignmentOps,
11409 for (
Expr *RefExpr : VarList) {
11410 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
11413 Expr *SimpleRefExpr = RefExpr;
11417 Vars.push_back(RefExpr);
11423 auto *VD = dyn_cast<
VarDecl>(D);
11431 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
11432 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
11441 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
11443 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
11444 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
11445 ? RefExpr->IgnoreParens()
11456 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
11461 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
11462 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
11463 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
11467 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
11474 bool VisitStmt(
Stmt *S) {
11476 if (Child && Visit(Child))
11481 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
11488 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
11495 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
11500 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
11501 return CapturedExpr;
11503 return BaseTransform::TransformMemberExpr(E);
11505 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
11509 template <
typename T,
typename U>
11512 for (U &Set : Lookups) {
11513 for (
auto *D : Set) {
11514 if (T Res = Gen(cast<ValueDecl>(D)))
11524 for (
auto RD : D->
redecls()) {
11529 auto ND = cast<NamedDecl>(RD);
11547 AssociatedClasses);
11560 for (
auto *NS : AssociatedNamespaces) {
11573 for (
auto *D : R) {
11574 auto *Underlying = D;
11575 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
11576 Underlying = USD->getTargetDecl();
11578 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
11579 !isa<OMPDeclareMapperDecl>(Underlying))
11586 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
11587 Underlying = USD->getTargetDecl();
11589 Lookups.emplace_back();
11590 Lookups.back().addDecl(Underlying);
11613 Lookups.emplace_back();
11614 Lookups.back().append(Lookup.
begin(), Lookup.
end());
11617 }
else if (
auto *ULE =
11618 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
11620 Decl *PrevD =
nullptr;
11624 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
11625 Lookups.back().addDecl(DRD);
11632 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
11642 ResSet.
append(Set.begin(), Set.end());
11644 ResSet.
addDecl(Set[Set.size() - 1]);
11649 true,
true, ResSet.
begin(), ResSet.
end());
11665 Lookup.suppressDiagnostics();
11669 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
11670 TyRec->getDecl()->getDefinition()) {
11673 if (Lookup.empty()) {
11674 Lookups.emplace_back();
11675 Lookups.back().append(Lookup.begin(), Lookup.end());
11682 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11692 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
11702 if (SemaRef.
IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
11704 VD->getType().getUnqualifiedType()))) {
11706 Loc, VD->getType(), Ty, Paths.
front(),
11710 VD, VD->getType().getNonReferenceType(),
VK_LValue, Loc);
11716 if (ReductionIdScopeSpec.
isSet()) {
11717 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
11725 struct ReductionData {
11743 ReductionData() =
delete;
11745 ReductionData(
unsigned Size) {
11746 Vars.reserve(Size);
11747 Privates.reserve(Size);
11748 LHSs.reserve(Size);
11749 RHSs.reserve(Size);
11750 ReductionOps.reserve(Size);
11751 TaskgroupDescriptors.reserve(Size);
11752 ExprCaptures.reserve(Size);
11753 ExprPostUpdates.reserve(Size);
11757 void push(
Expr *Item,
Expr *ReductionOp) {
11758 Vars.emplace_back(Item);
11759 Privates.emplace_back(
nullptr);
11760 LHSs.emplace_back(
nullptr);
11761 RHSs.emplace_back(
nullptr);
11762 ReductionOps.emplace_back(ReductionOp);
11763 TaskgroupDescriptors.emplace_back(
nullptr);
11767 Expr *TaskgroupDescriptor) {
11768 Vars.emplace_back(Item);
11769 Privates.emplace_back(Private);
11770 LHSs.emplace_back(LHS);
11771 RHSs.emplace_back(RHS);
11772 ReductionOps.emplace_back(ReductionOp);
11773 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
11782 if (Length ==
nullptr) {
11789 SingleElement =
true;
11790 ArraySizes.push_back(llvm::APSInt::get(1));
11796 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
11797 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
11798 ArraySizes.push_back(ConstantLengthValue);
11806 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
11807 Length = TempOASE->getLength();
11808 if (Length ==
nullptr) {
11815 ArraySizes.push_back(llvm::APSInt::get(1));
11821 llvm::APSInt ConstantLengthValue = Result.
Val.
getInt();
11822 if (ConstantLengthValue.getSExtValue() != 1)
11825 ArraySizes.push_back(ConstantLengthValue);
11831 if (!SingleElement) {
11832 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
11834 ArraySizes.push_back(llvm::APSInt::get(1));
11849 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
11888 case OO_Array_Delete:
11897 case OO_GreaterEqual:
11899 case OO_MinusEqual:
11901 case OO_SlashEqual:
11902 case OO_PercentEqual:
11903 case OO_CaretEqual:
11907 case OO_GreaterGreater:
11908 case OO_LessLessEqual:
11909 case OO_GreaterGreaterEqual:
11910 case OO_EqualEqual:
11911 case OO_ExclaimEqual:
11914 case OO_MinusMinus:
11920 case OO_Conditional:
11923 llvm_unreachable(
"Unexpected reduction identifier");
11926 if (II->isStr(
"max"))
11928 else if (II->isStr(
"min"))
11934 if (ReductionIdScopeSpec.
isValid())
11940 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
11941 bool FirstIter =
true;
11942 for (
Expr *RefExpr : VarList) {
11943 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
11951 if (!FirstIter && IR != ER)
11956 Expr *SimpleRefExpr = RefExpr;
11965 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11966 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11967 Expr *ReductionOp =
nullptr;
11969 (DeclareReductionRef.
isUnset() ||
11970 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
11971 ReductionOp = DeclareReductionRef.
get();
11973 RD.push(RefExpr, ReductionOp);
11979 Expr *TaskgroupDescriptor =
nullptr;
11984 Type = ASE->getType().getNonReferenceType();
11989 Type = ATy->getElementType();
11996 auto *VD = dyn_cast<
VarDecl>(D);
12002 diag::err_omp_reduction_incomplete_type))
12008 false, ASE || OASE))
12015 if (!ASE && !OASE) {
12018 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
12019 DSARefChecker Check(Stack);
12020 if (Check.Visit(VDDef->
getInit())) {
12021 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
12040 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
12041 if (DVar.CKind == OMPC_reduction) {
12042 S.
Diag(ELoc, diag::err_omp_once_referenced)
12045 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
12049 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
12063 DVar = Stack->getImplicitDSA(D,
true);
12064 if (DVar.CKind != OMPC_shared) {
12065 S.
Diag(ELoc, diag::err_omp_required_access)
12078 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
12079 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
12083 (DeclareReductionRef.
isUnset() ||
12084 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
12085 RD.push(RefExpr, DeclareReductionRef.
get());
12088 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
12090 S.
Diag(ReductionId.getBeginLoc(),
12091 diag::err_omp_unknown_reduction_identifier)
12092 << Type << ReductionIdRange;
12104 if (DeclareReductionRef.
isUnset()) {
12105 if ((BOK == BO_GT || BOK == BO_LT) &&
12106 !(Type->isScalarType() ||
12107 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
12108 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
12110 if (!ASE && !OASE) {
12111 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
12114 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12119 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
12120 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
12121 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
12123 if (!ASE && !OASE) {
12124 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
12127 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12134 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
12143 bool ConstantLengthOASE =
false;
12145 bool SingleElement;
12148 Context, OASE, SingleElement, ArraySizes);
12151 if (ConstantLengthOASE && !SingleElement) {
12152 for (llvm::APSInt &Size : ArraySizes)
12158 if ((OASE && !ConstantLengthOASE) ||
12163 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
12164 S.
Diag(ELoc, diag::note_vla_unsupported);
12166 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
12167 S.
targetDiag(ELoc, diag::note_vla_unsupported);
12180 }
else if (!ASE && !OASE &&
12188 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
12190 Expr *Init =
nullptr;
12193 if (DeclareReductionRef.
isUsable()) {
12195 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
12196 if (DRD->getInitializer()) {
12198 RHSVD->setInit(DRDRef);
12208 if (Type->isScalarType() || Type->isAnyComplexType())
12213 if (Type->isScalarType() || Type->isAnyComplexType()) {
12222 Type = ComplexTy->getElementType();
12223 if (Type->isRealFloatingType()) {
12224 llvm::APFloat InitValue =
12225 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
12229 }
else if (Type->isScalarType()) {
12232 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
12249 if (Type->isIntegerType() || Type->isPointerType()) {
12254 llvm::APInt InitValue =
12255 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
12256 : llvm::APInt::getMinValue(Size)
12257 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
12258 : llvm::APInt::getMaxValue(Size);
12260 if (Type->isPointerType()) {
12266 Init = CastExpr.
get();
12268 }
else if (Type->isRealFloatingType()) {
12269 llvm::APFloat InitValue = llvm::APFloat::getLargest(
12300 llvm_unreachable(
"Unexpected reduction operation");
12303 if (Init && DeclareReductionRef.
isUnset())
12307 if (RHSVD->isInvalidDecl())
12309 if (!RHSVD->hasInit() &&
12311 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
12312 << Type << ReductionIdRange;
12313 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
12316 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12322 PrivateVD->
setInit(RHSVD->getInit());
12326 if (DeclareReductionRef.
isUsable()) {
12327 QualType RedTy = DeclareReductionRef.
get()->getType();
12331 if (!BasePath.empty()) {
12335 CK_UncheckedDerivedToBase, LHS.
get(),
12336 &BasePath, LHS.
get()->getValueKind());
12338 CK_UncheckedDerivedToBase, RHS.get(),
12339 &BasePath, RHS.get()->getValueKind());
12342 QualType Params[] = {PtrRedTy, PtrRedTy};
12352 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
12354 if (BOK != BO_LT && BOK != BO_GT) {
12356 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
12357 BO_Assign, LHSDRE, ReductionOp.
get());
12359 auto *ConditionalOp =
new (Context)
12363 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
12364 BO_Assign, LHSDRE, ConditionalOp);
12381 if (ClauseKind == OMPC_in_reduction) {
12384 const Expr *ParentReductionOp;
12385 Expr *ParentBOKTD, *ParentReductionOpTD;
12386 DSAStackTy::DSAVarData ParentBOKDSA =
12387 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
12389 DSAStackTy::DSAVarData ParentReductionOpDSA =
12390 Stack->getTopMostTaskgroupReductionData(
12391 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
12392 bool IsParentBOK = ParentBOKDSA.DKind !=
OMPD_unknown;
12393 bool IsParentReductionOp = ParentReductionOpDSA.DKind !=
OMPD_unknown;
12394 if (!IsParentBOK && !IsParentReductionOp) {
12395 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
12398 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
12399 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
12400 IsParentReductionOp) {
12401 bool EmitError =
true;
12402 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
12403 llvm::FoldingSetNodeID RedId, ParentRedId;
12404 ParentReductionOp->
Profile(ParentRedId, Context,
true);
12405 DeclareReductionRef.
get()->Profile(RedId, Context,
12407 EmitError = RedId != ParentRedId;
12410 S.
Diag(ReductionId.getBeginLoc(),
12411 diag::err_omp_reduction_identifier_mismatch)
12412 << ReductionIdRange << RefExpr->getSourceRange();
12414 diag::note_omp_previous_reduction_identifier)
12416 << (IsParentBOK ? ParentBOKDSA.RefExpr
12417 : ParentReductionOpDSA.RefExpr)
12418 ->getSourceRange();
12422 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
12423 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
12430 TransformExprToCaptures RebuildToCapture(S, D);
12432 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).
get();
12433 Ref = RebuildToCapture.getCapturedExpr();
12435 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
12438 RD.ExprCaptures.emplace_back(Ref->
getDecl());
12444 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
12449 Stack->getCurrentDirective() == OMPD_taskgroup) {
12450 S.
Diag(RefExpr->getExprLoc(),
12451 diag::err_omp_reduction_non_addressable_expression)
12452 << RefExpr->getSourceRange();
12455 RD.ExprPostUpdates.emplace_back(
12462 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
12463 if (CurrDir == OMPD_taskgroup) {
12464 if (DeclareReductionRef.
isUsable())
12465 Stack->addTaskgroupReductionData(D, ReductionIdRange,
12466 DeclareReductionRef.
get());
12468 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
12470 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
12471 TaskgroupDescriptor);
12473 return RD.Vars.empty();
12481 ReductionData RD(VarList.size());
12483 StartLoc, LParenLoc, ColonLoc, EndLoc,
12484 ReductionIdScopeSpec, ReductionId,
12485 UnresolvedReductions, RD))
12489 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12491 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
12501 ReductionData RD(VarList.size());
12503 StartLoc, LParenLoc, ColonLoc, EndLoc,
12504 ReductionIdScopeSpec, ReductionId,
12505 UnresolvedReductions, RD))
12509 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12511 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
12521 ReductionData RD(VarList.size());
12523 StartLoc, LParenLoc, ColonLoc, EndLoc,
12524 ReductionIdScopeSpec, ReductionId,
12525 UnresolvedReductions, RD))
12529 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
12531 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
12538 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
12540 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
12549 const auto *VD = dyn_cast_or_null<VarDecl>(D);
12551 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
12553 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
12555 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
12571 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
12572 !Ty->isPointerType())) {
12573 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
12579 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12596 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
12597 LinKind = OMPC_LINEAR_val;
12598 for (
Expr *RefExpr : VarList) {
12599 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
12602 Expr *SimpleRefExpr = RefExpr;
12606 Vars.push_back(RefExpr);
12607 Privates.push_back(
nullptr);
12608 Inits.push_back(
nullptr);
12615 auto *VD = dyn_cast<
VarDecl>(D);
12621 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
12622 if (DVar.RefExpr) {
12629 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
12637 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
12643 if (!VD && !CurContext->isDependentContext()) {
12645 if (!isOpenMPCapturedDecl(D)) {
12646 ExprCaptures.push_back(Ref->
getDecl());
12648 ExprResult RefRes = DefaultLvalueConversion(Ref);
12652 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
12653 SimpleRefExpr, RefRes.
get());
12656 ExprPostUpdates.push_back(
12657 IgnoredValueConversions(PostUpdateRes.
get()).
get());
12661 if (LinKind == OMPC_LINEAR_uval)
12662 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
12664 InitExpr = VD ? SimpleRefExpr : Ref;
12665 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
12669 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
12670 Vars.push_back((VD || CurContext->isDependentContext())
12671 ? RefExpr->IgnoreParens()
12673 Privates.push_back(PrivateRef);
12674 Inits.push_back(InitRef);
12681 Expr *CalcStepExpr =
nullptr;
12686 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
12689 StepExpr = Val.
get();
12697 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
12698 CalcStep = ActOnFinishFullExpr(CalcStep.get(),
false);
12704 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
12705 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
12706 << (Vars.size() > 1);
12707 if (!IsConstant && CalcStep.isUsable()) {
12710 CalcStepExpr = CalcStep.get();
12715 ColonLoc, EndLoc, Vars, Privates, Inits,
12716 StepExpr, CalcStepExpr,
12722 Expr *NumIterations,
Sema &SemaRef,
12723 Scope *S, DSAStackTy *Stack) {
12734 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
12735 bool HasErrors =
false;
12736 auto CurInit = Clause.inits().begin();
12737 auto CurPrivate = Clause.privates().begin();
12742 Expr *SimpleRefExpr = RefExpr;
12743 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
12745 if (Res.second || !D) {
12746 Updates.push_back(
nullptr);
12747 Finals.push_back(
nullptr);
12751 auto &&Info = Stack->isLoopControlVariable(D);
12758 diag::err_omp_linear_distribute_var_non_loop_iteration);
12759 Updates.push_back(
nullptr);
12760 Finals.push_back(
nullptr);
12764 Expr *InitExpr = *CurInit;
12767 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
12769 if (LinKind == OMPC_LINEAR_uval)
12770 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
12774 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
12782 InitExpr, IV,
Step,
false);
12784 Update = *CurPrivate;
12793 InitExpr, NumIterations,
Step,
false);
12795 Final = *CurPrivate;
12799 if (!Update.isUsable() || !Final.isUsable()) {
12800 Updates.push_back(
nullptr);
12801 Finals.push_back(
nullptr);
12804 Updates.push_back(Update.get());
12805 Finals.push_back(Final.get());
12810 Clause.setUpdates(Updates);
12811 Clause.setFinals(Finals);
12819 for (
Expr *RefExpr : VarList) {
12820 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
12823 Expr *SimpleRefExpr = RefExpr;
12827 Vars.push_back(RefExpr);
12834 auto *VD = dyn_cast<
VarDecl>(D);
12840 const Type *Ty = QType.getTypePtrOrNull();
12842 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
12843 << QType << getLangOpts().CPlusPlus << ERange;
12848 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12855 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
12856 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
12857 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
12863 if (!VD && isOpenMPCapturedDecl(D))
12865 Vars.push_back(DefaultFunctionArrayConversion(
12866 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
12875 if (Alignment !=
nullptr) {
12877 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
12880 Alignment = AlignResult.
get();
12886 EndLoc, Vars, Alignment);
12897 for (
Expr *RefExpr : VarList) {
12898 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
12899 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12901 Vars.push_back(RefExpr);
12902 SrcExprs.push_back(
nullptr);
12903 DstExprs.push_back(
nullptr);
12904 AssignmentOps.push_back(
nullptr);
12914 if (!DE || !isa<VarDecl>(DE->getDecl())) {
12915 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
12916 << 0 << RefExpr->getSourceRange();
12920 Decl *D = DE->getDecl();
12921 auto *VD = cast<VarDecl>(D);
12924 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
12926 Vars.push_back(DE);
12927 SrcExprs.push_back(
nullptr);
12928 DstExprs.push_back(
nullptr);
12929 AssignmentOps.push_back(
nullptr);
12935 if (!
DSAStack->isThreadPrivate(VD)) {
12936 Diag(ELoc, diag::err_omp_required_access)
12949 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
12953 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
12954 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
12960 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
12962 if (AssignmentOp.isInvalid())
12964 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
12966 if (AssignmentOp.isInvalid())
12969 DSAStack->addDSA(VD, DE, OMPC_copyin);
12970 Vars.push_back(DE);
12971 SrcExprs.push_back(PseudoSrcExpr);
12972 DstExprs.push_back(PseudoDstExpr);
12973 AssignmentOps.push_back(AssignmentOp.get());
12980 SrcExprs, DstExprs, AssignmentOps);
12991 for (
Expr *RefExpr : VarList) {
12992 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
12995 Expr *SimpleRefExpr = RefExpr;
12999 Vars.push_back(RefExpr);
13000 SrcExprs.push_back(
nullptr);
13001 DstExprs.push_back(
nullptr);
13002 AssignmentOps.push_back(
nullptr);
13009 auto *VD = dyn_cast<
VarDecl>(D);
13014 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
13015 DSAStackTy::DSAVarData DVar =
13017 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
13019 Diag(ELoc, diag::err_omp_wrong_dsa)
13030 DVar =
DSAStack->getImplicitDSA(D,
false);
13031 if (DVar.CKind == OMPC_shared) {
13032 Diag(ELoc, diag::err_omp_required_access)
13034 <<
"threadprivate or private in the enclosing context";
13043 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
13050 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13060 .getUnqualifiedType();
13062 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.src",
13066 buildVarDecl(*
this, RefExpr->getBeginLoc(), Type,
".copyprivate.dst",
13070 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
13074 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
13080 assert(VD || isOpenMPCapturedDecl(D));
13082 VD ? RefExpr->IgnoreParens()
13084 SrcExprs.push_back(PseudoSrcExpr);
13085 DstExprs.push_back(PseudoDstExpr);
13086 AssignmentOps.push_back(AssignmentOp.
get());
13093 Vars, SrcExprs, DstExprs, AssignmentOps);
13100 if (VarList.empty())
13111 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
13112 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
13113 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
13117 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
13119 DepKind == OMPC_DEPEND_sink)) {
13120 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
13121 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
13129 llvm::APSInt DepCounter(32);
13130 llvm::APSInt TotalDepCount(32);
13131 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
13132 if (
const Expr *OrderedCountExpr =
13133 DSAStack->getParentOrderedRegionParam().first) {
13134 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
13135 TotalDepCount.setIsUnsigned(
true);
13138 for (
Expr *RefExpr : VarList) {
13139 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
13140 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
13142 Vars.push_back(RefExpr);
13148 if (DepKind == OMPC_DEPEND_sink) {
13149 if (
DSAStack->getParentOrderedRegionParam().first &&
13150 DepCounter >= TotalDepCount) {
13151 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
13163 if (CurContext->isDependentContext()) {
13165 Vars.push_back(RefExpr);
13171 Expr *LHS = SimpleExpr;
13172 Expr *RHS =
nullptr;
13173 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
13175 OOLoc = BO->getOperatorLoc();
13178 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
13179 OOK = OCE->getOperator();
13180 OOLoc = OCE->getOperatorLoc();
13183 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
13184 OOK = MCE->getMethodDecl()
13187 .getCXXOverloadedOperator();
13188 OOLoc = MCE->getCallee()->getExprLoc();
13197 Vars.push_back(RefExpr);
13203 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
13204 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
13208 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
13209 RHS, OMPC_depend,
false);
13213 if (!CurContext->isDependentContext() &&
13214 DSAStack->getParentOrderedRegionParam().first &&
13215 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
13217 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
13219 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
13222 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
13225 OpsOffs.emplace_back(RHS, OOK);
13228 if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
13230 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
13231 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
13232 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
13233 << RefExpr->getSourceRange();
13236 bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
13237 getDiagnostics().setSuppressAllDiagnostics(
true);
13239 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
13240 getDiagnostics().setSuppressAllDiagnostics(Suppress);
13241 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
13242 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
13243 << RefExpr->getSourceRange();
13247 Vars.push_back(RefExpr->IgnoreParenImpCasts());
13250 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
13251 TotalDepCount > VarList.size() &&
13252 DSAStack->getParentOrderedRegionParam().first &&
13253 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
13254 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
13255 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
13257 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
13262 DepKind, DepLoc, ColonLoc, Vars,
13263 TotalDepCount.getZExtValue());
13264 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
13265 DSAStack->isParentOrderedRegion())
13266 DSAStack->addDoacrossDependClause(
C, OpsOffs);
13273 Expr *ValExpr = Device;
13274 Stmt *HelperValStmt =
nullptr;
13285 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
13286 ValExpr = MakeFullExpr(ValExpr).get();
13287 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13288 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
13292 return new (Context)
OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
13293 StartLoc, LParenLoc, EndLoc);
13298 bool FullCheck =
true) {
13301 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
13306 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
13321 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
13322 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
13323 return ATy->getSize().getSExtValue() != 1;
13328 assert(OASE &&
"Expecting array section if not an array subscript.");
13329 const Expr *LowerBound = OASE->getLowerBound();
13330 const Expr *Length = OASE->getLength();
13339 llvm::APSInt ConstLowerBound = Result.
Val.
getInt();
13340 if (ConstLowerBound.getSExtValue())
13363 llvm::APSInt ConstLength = Result.
Val.
getInt();
13364 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
13377 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
13380 assert(OASE &&
"Expecting array section if not an array subscript.");
13381 const Expr *Length = OASE->getLength();
13387 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
13388 return ATy->getSize().getSExtValue() != 1;
13398 llvm::APSInt ConstLength = Result.
Val.
getInt();
13399 return ConstLength.getSExtValue() != 1;
13432 const Expr *RelevantExpr =
nullptr;
13451 bool AllowUnitySizeArraySection =
true;
13452 bool AllowWholeSizeArraySection =
true;
13454 while (!RelevantExpr) {
13457 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
13458 if (!isa<VarDecl>(CurE->getDecl()))
13461 RelevantExpr = CurE;
13465 AllowUnitySizeArraySection =
false;
13466 AllowWholeSizeArraySection =
false;
13469 CurComponents.emplace_back(CurE, CurE->getDecl());
13470 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
13473 if (isa<CXXThisExpr>(BaseE))
13475 RelevantExpr = CurE;
13479 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
13481 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
13482 << CurE->getSourceRange();
13490 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
13495 if (FD->isBitField()) {
13497 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
13517 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
13518 << CurE->getSourceRange();
13531 AllowUnitySizeArraySection =
false;
13532 AllowWholeSizeArraySection =
false;
13535 CurComponents.emplace_back(CurE, FD);
13536 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
13541 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
13542 << 0 << CurE->getSourceRange();
13553 AllowWholeSizeArraySection =
false;
13555 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13557 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.
getASTContext())) {
13558 if (!Result.
Val.
getInt().isNullValue()) {
13559 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
13560 diag::err_omp_invalid_map_this_expr);
13561 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
13562 diag::note_omp_invalid_subscript_on_this_ptr_map);
13569 CurComponents.emplace_back(CurE,
nullptr);
13570 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
13571 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
13586 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
13587 << 0 << CurE->getSourceRange();
13596 if (AllowWholeSizeArraySection) {
13603 if (NotWhole || IsPointer)
13604 AllowWholeSizeArraySection =
false;
13605 }
else if (AllowUnitySizeArraySection && NotUnity) {
13609 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
13610 << CurE->getSourceRange();
13614 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
13617 if (CurE->getLength()->EvaluateAsInt(ResultR,
13619 if (!ResultR.
Val.
getInt().isOneValue()) {
13620 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
13621 diag::err_omp_invalid_map_this_expr);
13622 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
13623 diag::note_omp_invalid_length_on_this_ptr_mapping);
13626 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
13628 if (!ResultL.
Val.
getInt().isNullValue()) {
13629 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
13630 diag::err_omp_invalid_map_this_expr);
13631 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
13632 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
13639 CurComponents.emplace_back(CurE,
nullptr);
13644 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
13651 return RelevantExpr;
13658 bool CurrentRegionOnly,
13669 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
13670 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
13671 "Map clause expression with unexpected base!");
13674 bool IsEnclosedByDataEnvironmentExpr =
false;
13675 const Expr *EnclosingExpr =
nullptr;
13677 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
13678 VD, CurrentRegionOnly,
13679 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
13680 ERange, CKind, &EnclosingExpr,
13684 assert(!StackComponents.empty() &&
13685 "Map clause expression with no components!");
13686 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
13687 "Map clause expression with unexpected base!");
13691 const Expr *RE = StackComponents.front().getAssociatedExpression();
13697 auto CI = CurComponents.rbegin();
13698 auto CE = CurComponents.rend();
13699 auto SI = StackComponents.rbegin();
13700 auto SE = StackComponents.rend();
13701 for (; CI != CE && SI != SE; ++CI, ++SI) {
13706 if (CurrentRegionOnly &&
13707 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
13708 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
13709 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
13710 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
13711 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
13712 diag::err_omp_multiple_array_items_in_map_clause)
13713 << CI->getAssociatedExpression()->getSourceRange();
13714 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
13715 diag::note_used_here)
13716 << SI->getAssociatedExpression()->getSourceRange();
13721 if (CI->getAssociatedExpression()->getStmtClass() !=
13722 SI->getAssociatedExpression()->getStmtClass())
13726 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
13732 for (; SI != SE; ++SI) {
13734 if (
const auto *ASE =
13735 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
13736 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
13737 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
13738 SI->getAssociatedExpression())) {
13745 SemaRef, SI->getAssociatedExpression(), Type))
13755 if (CI == CE && SI == SE) {
13756 if (CurrentRegionOnly) {
13757 if (CKind == OMPC_map) {
13758 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
13760 assert(CKind == OMPC_to || CKind == OMPC_from);
13761 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13764 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
13765 << RE->getSourceRange();
13770 IsEnclosedByDataEnvironmentExpr =
true;
13775 std::prev(CI)->getAssociatedDeclaration()->getType();
13777 std::prev(CI)->getAssociatedExpression()->getExprLoc();
13796 if (CI == CE || SI == SE) {
13799 diag::err_omp_pointer_mapped_along_with_derived_section)
13801 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
13802 << RE->getSourceRange();
13805 if (CI->getAssociatedExpression()->getStmtClass() !=
13806 SI->getAssociatedExpression()->getStmtClass() ||
13807 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
13808 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
13809 assert(CI != CE && SI != SE);
13810 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
13812 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
13813 << RE->getSourceRange();
13823 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
13824 if (CKind == OMPC_map) {
13825 if (CI != CE || SI != SE) {
13829 CI != CE ? CurComponents.begin() : StackComponents.begin();
13830 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
13832 while (It !=
End && !It->getAssociatedDeclaration())
13833 std::advance(It, 1);
13834 assert(It !=
End &&
13835 "Expected at least one component with the declaration.");
13836 if (It !=
Begin && It->getAssociatedDeclaration()
13838 .getCanonicalType()
13839 ->isAnyPointerType()) {
13840 IsEnclosedByDataEnvironmentExpr =
false;
13841 EnclosingExpr =
nullptr;
13845 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
13847 assert(CKind == OMPC_to || CKind == OMPC_from);
13848 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
13851 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
13852 << RE->getSourceRange();
13858 if (!CurrentRegionOnly && SI != SE)
13859 EnclosingExpr = RE;
13863 IsEnclosedByDataEnvironmentExpr |=
13864 (!CurrentRegionOnly && CI != CE && SI == SE);
13869 if (CurrentRegionOnly)
13883 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
13885 diag::err_omp_original_storage_is_shared_and_does_not_contain)
13901 Expr *UnresolvedMapper) {
13915 Lookups.emplace_back();
13916 Lookups.back().append(Lookup.
begin(), Lookup.
end());
13919 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
13923 auto *DMD = cast<OMPDeclareMapperDecl>(D);
13924 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
13925 Lookups.back().addDecl(DMD);
13933 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
13943 URS.
append(Set.begin(), Set.end());
13948 false,
true, URS.
begin(), URS.
end());
13959 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13969 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13979 if (SemaRef.
IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
13981 VD->getType().getUnqualifiedType()))) {
13983 Loc, VD->getType(), Type, Paths.
front(),
13992 SemaRef.
Diag(Loc, diag::err_omp_invalid_mapper)
13993 << Type << MapperId.
getName();
14002 struct MappableVarListInfo {
14004 ArrayRef<Expr *> VarList;
14014 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
14017 VarComponents.reserve(VarList.size());
14018 VarBaseDeclarations.reserve(VarList.size());
14033 ArrayRef<Expr *> UnresolvedMappers,
14035 bool IsMapTypeImplicit =
false) {
14037 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
14038 "Unexpected clause kind with mappable expressions!");
14046 MapperId.
setName(DeclNames.getIdentifier(
14051 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
14052 bool UpdateUMIt =
false;
14053 Expr *UnresolvedMapper =
nullptr;
14061 for (
Expr *RE : MVLI.VarList) {
14062 assert(RE &&
"Null expr in omp to/from/map clause");
14066 if (UpdateUMIt && UMIt != UMEnd) {
14070 "Expect the size of UnresolvedMappers to match with that of VarList");
14074 UnresolvedMapper = *UMIt;
14083 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
14087 MVLI.UDMapperList.push_back(ER.
get());
14090 MVLI.ProcessedVarList.push_back(RE);
14098 diag::err_omp_expected_named_var_member_or_array_expression)
14109 SemaRef, SimpleExpr, CurComponents, CKind,
false);
14113 assert(!CurComponents.empty() &&
14114 "Invalid mappable expression information.");
14116 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
14118 DSAS->addMappedClassesQualTypes(TE->getType());
14121 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
14125 MVLI.UDMapperList.push_back(ER.
get());
14127 MVLI.ProcessedVarList.push_back(RE);
14128 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14129 MVLI.VarComponents.back().append(CurComponents.begin(),
14130 CurComponents.end());
14131 MVLI.VarBaseDeclarations.push_back(
nullptr);
14138 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
14139 assert(CurDeclaration &&
"Null decl on map clause.");
14142 "Expecting components to have associated only canonical declarations.");
14144 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
14145 const auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
14147 assert((VD || FD) &&
"Only variables or fields are expected here!");
14154 if (VD && DSAS->isThreadPrivate(VD)) {
14155 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
14156 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
14171 true, CurComponents, CKind))
14173 if (CKind == OMPC_map &&
14175 false, CurComponents, CKind))
14182 auto I = llvm::find_if(
14187 assert(I != CurComponents.end() &&
"Null decl on map clause.");
14189 I->getAssociatedDeclaration()->getType().getNonReferenceType();
14199 if (CKind == OMPC_map) {
14205 if (DKind == OMPD_target_enter_data &&
14206 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
14207 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
14208 << (IsMapTypeImplicit ? 1 : 0)
14218 if (DKind == OMPD_target_exit_data &&
14219 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
14220 MapType == OMPC_MAP_delete)) {
14221 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
14222 << (IsMapTypeImplicit ? 1 : 0)
14232 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
14234 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
14246 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
14247 Type.getCanonicalType(), UnresolvedMapper);
14250 MVLI.UDMapperList.push_back(ER.
get());
14253 MVLI.ProcessedVarList.push_back(RE);
14257 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
14263 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
14264 MVLI.VarComponents.back().append(CurComponents.begin(),
14265 CurComponents.end());
14266 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 14280 OMPC_MAP_MODIFIER_unknown};
14284 unsigned Count = 0;
14285 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
14286 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
14287 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
14288 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
14292 "Modifiers exceed the allowed number of map type modifiers");
14293 Modifiers[Count] = MapTypeModifiers[I];
14294 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
14298 MappableVarListInfo MVLI(VarList);
14300 MapperIdScopeSpec, MapperId, UnresolvedMappers,
14301 MapType, IsMapTypeImplicit);
14306 MVLI.VarBaseDeclarations, MVLI.VarComponents,
14307 MVLI.UDMapperList, Modifiers, ModifiersLoc,
14309 MapperId, MapType, IsMapTypeImplicit, MapLoc);
14316 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
14317 if (ReductionType.isNull())
14324 if (ReductionType.hasQualifiers()) {
14325 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
14329 if (ReductionType->isFunctionType()) {
14330 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
14333 if (ReductionType->isReferenceType()) {
14334 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
14337 if (ReductionType->isArrayType()) {
14338 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
14341 return ReductionType;
14346 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
14349 Decls.reserve(ReductionTypes.size());
14352 forRedeclarationInCurContext());
14357 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
14359 bool InCompoundScope =
true;
14360 if (S !=
nullptr) {
14366 LookupName(Lookup, S);
14367 FilterLookupForScope(Lookup, DC, S,
false,
14369 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
14372 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.
next());
14373 if (InCompoundScope) {
14374 auto I = UsedAsPrevious.find(PrevDecl);
14375 if (I == UsedAsPrevious.end())
14376 UsedAsPrevious[PrevDecl] =
false;
14378 UsedAsPrevious[D] =
true;
14380 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
14381 PrevDecl->getLocation();
14384 if (InCompoundScope) {
14385 for (
const auto &PrevData : UsedAsPrevious) {
14386 if (!PrevData.second) {
14387 PrevDRD = PrevData.first;
14392 }
else if (PrevDeclInScope !=
nullptr) {
14393 auto *PrevDRDInScope = PrevDRD =
14394 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
14396 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
14398 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
14399 }
while (PrevDRDInScope !=
nullptr);
14401 for (
const auto &TyData : ReductionTypes) {
14402 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
14403 bool Invalid =
false;
14404 if (I != PreviousRedeclTypes.end()) {
14405 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
14407 Diag(I->second, diag::note_previous_definition);
14410 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
14412 Name, TyData.first, PrevDRD);
14414 DRD->setAccess(AS);
14415 Decls.push_back(DRD);
14417 DRD->setInvalidDecl();
14422 return DeclGroupPtrTy::make(
14427 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14430 PushFunctionScope();
14431 setFunctionHasBranchProtectedScope();
14432 getCurFunction()->setHasOMPDeclareReductionCombiner();
14435 PushDeclContext(S, DRD);
14439 PushExpressionEvaluationContext(
14440 ExpressionEvaluationContext::PotentiallyEvaluated);
14442 QualType ReductionType = DRD->getType();
14459 if (S !=
nullptr) {
14460 PushOnScopeChains(OmpInParm, S);
14461 PushOnScopeChains(OmpOutParm, S);
14463 DRD->addDecl(OmpInParm);
14464 DRD->addDecl(OmpOutParm);
14470 DRD->setCombinerData(InE, OutE);
14474 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14475 DiscardCleanupsInEvaluationContext();
14476 PopExpressionEvaluationContext();
14479 PopFunctionScopeInfo();
14481 if (Combiner !=
nullptr)
14482 DRD->setCombiner(Combiner);
14484 DRD->setInvalidDecl();
14488 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14491 PushFunctionScope();
14492 setFunctionHasBranchProtectedScope();
14495 PushDeclContext(S, DRD);
14499 PushExpressionEvaluationContext(
14500 ExpressionEvaluationContext::PotentiallyEvaluated);
14502 QualType ReductionType = DRD->getType();
14519 if (S !=
nullptr) {
14520 PushOnScopeChains(OmpPrivParm, S);
14521 PushOnScopeChains(OmpOrigParm, S);
14523 DRD->addDecl(OmpPrivParm);
14524 DRD->addDecl(OmpOrigParm);
14530 DRD->setInitializerData(OrigE, PrivE);
14531 return OmpPrivParm;
14536 auto *DRD = cast<OMPDeclareReductionDecl>(D);
14537 DiscardCleanupsInEvaluationContext();
14538 PopExpressionEvaluationContext();
14541 PopFunctionScopeInfo();
14543 if (Initializer !=
nullptr) {
14545 }
else if (OmpPrivParm->
hasInit()) {
14546 DRD->setInitializer(OmpPrivParm->
getInit(),
14551 DRD->setInvalidDecl();
14557 for (
Decl *D : DeclReductions.
get()) {
14560 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
14566 return DeclReductions;
14575 if (getLangOpts().CPlusPlus) {
14577 CheckExtraCXXDefaultArguments(D);
14580 return CreateParsedType(T, TInfo);
14585 assert(ParsedType.
isUsable() &&
"Expect usable parsed mapper type");
14587 QualType MapperType = GetTypeFromParser(ParsedType.
get());
14588 assert(!MapperType.isNull() &&
"Expect valid mapper type");
14592 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
14593 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
14602 Decl *PrevDeclInScope) {
14604 forRedeclarationInCurContext());
14609 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
14611 bool InCompoundScope =
true;
14612 if (S !=
nullptr) {
14618 LookupName(Lookup, S);
14619 FilterLookupForScope(Lookup, DC, S,
false,
14621 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
14624 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.
next());
14625 if (InCompoundScope) {
14626 auto I = UsedAsPrevious.find(PrevDecl);
14627 if (I == UsedAsPrevious.end())
14628 UsedAsPrevious[PrevDecl] =
false;
14630 UsedAsPrevious[D] =
true;
14632 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
14633 PrevDecl->getLocation();
14636 if (InCompoundScope) {
14637 for (
const auto &PrevData : UsedAsPrevious) {
14638 if (!PrevData.second) {
14639 PrevDMD = PrevData.first;
14644 }
else if (PrevDeclInScope) {
14645 auto *PrevDMDInScope = PrevDMD =
14646 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
14648 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
14650 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
14651 }
while (PrevDMDInScope !=
nullptr);
14654 bool Invalid =
false;
14655 if (I != PreviousRedeclTypes.end()) {
14656 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
14657 << MapperType << Name;
14658 Diag(I->second, diag::note_previous_definition);
14662 MapperType, VN, PrevDMD);
14664 DMD->setAccess(AS);
14666 DMD->setInvalidDecl();
14669 PushFunctionScope();
14670 setFunctionHasBranchProtectedScope();
14684 PushOnScopeChains(VD, S);
14695 PopFunctionScopeInfo();
14699 PushOnScopeChains(D, S,
false);
14710 Expr *ValExpr = NumTeams;
14711 Stmt *HelperValStmt =
nullptr;
14722 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
14723 ValExpr = MakeFullExpr(ValExpr).get();
14724 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14725 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
14730 StartLoc, LParenLoc, EndLoc);
14737 Expr *ValExpr = ThreadLimit;
14738 Stmt *HelperValStmt =
nullptr;
14749 if (CaptureRegion !=
OMPD_unknown && !CurContext->isDependentContext()) {
14750 ValExpr = MakeFullExpr(ValExpr).get();
14751 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14752 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
14757 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14764 Expr *ValExpr = Priority;
14779 Expr *ValExpr = Grainsize;
14795 Expr *ValExpr = NumTasks;
14813 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
14816 return new (Context)
14825 std::string Values;
14829 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14833 Expr *ValExpr = ChunkSize;
14834 Stmt *HelperValStmt =
nullptr;
14841 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14845 ValExpr = Val.
get();
14852 if (Result.isSigned() && !Result.isStrictlyPositive()) {
14853 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14858 DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
14860 !CurContext->isDependentContext()) {
14861 ValExpr = MakeFullExpr(ValExpr).get();
14862 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14863 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
14869 return new (Context)
14871 Kind, ValExpr, HelperValStmt);
14879 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
14883 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
14885 OMPC_DEFAULTMAP_MODIFIER_tofrom);
14889 OMPC_DEFAULTMAP_scalar);
14893 Diag(Loc, diag::err_omp_unexpected_clause_value)
14897 DSAStack->setDefaultDMAToFromScalar(StartLoc);
14899 return new (Context)
14904 DeclContext *CurLexicalContext = getCurLexicalContext();
14908 !isa<CXXRecordDecl>(CurLexicalContext) &&
14909 !isa<ClassTemplateDecl>(CurLexicalContext) &&
14910 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
14911 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
14912 Diag(Loc, diag::err_omp_region_not_file_context);
14915 ++DeclareTargetNestingLevel;
14920 assert(DeclareTargetNestingLevel > 0 &&
14921 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
14922 --DeclareTargetNestingLevel;
14928 OMPDeclareTargetDeclAttr::MapTypeTy MT,
14931 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
14938 VarOrFuncDeclFilterCCC CCC(*
this);
14940 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr, CCC,
14941 CTK_ErrorRecovery)) {
14942 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
14944 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
14953 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
14954 isa<FunctionTemplateDecl>(ND)) {
14958 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
14959 cast<ValueDecl>(ND));
14961 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
14964 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
14965 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Id.
getLoc());
14966 }
else if (*Res != MT) {
14967 Diag(Id.
getLoc(), diag::err_omp_declare_target_to_and_link)
14977 if (!D || !isa<VarDecl>(D))
14979 auto *VD = cast<VarDecl>(D);
14980 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
14982 SemaRef.
Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
14983 SemaRef.
Diag(SL, diag::note_used_here) << SR;
14987 Sema &SemaRef, DSAStackTy *Stack,
14989 return VD->
hasAttr<OMPDeclareTargetDeclAttr>() ||
15000 if (
auto *VD = dyn_cast<VarDecl>(D)) {
15002 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
15003 !VD->isStaticDataMember())
15007 if (
DSAStack->isThreadPrivate(VD)) {
15008 Diag(SL, diag::err_omp_threadprivate_in_target);
15013 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
15014 D = FTD->getTemplatedDecl();
15015 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
15017 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
15018 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
15019 assert(IdLoc.
isValid() &&
"Source location is expected");
15020 Diag(IdLoc, diag::err_omp_function_in_link_clause);
15021 Diag(FD->getLocation(), diag::note_defined_here) << FD;
15025 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
15031 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
15033 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
15034 isa<FunctionTemplateDecl>(D)) {
15035 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
15036 Context, OMPDeclareTargetDeclAttr::MT_To);
15039 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
15054 MappableVarListInfo MVLI(VarList);
15056 MapperIdScopeSpec, MapperId, UnresolvedMappers);
15057 if (MVLI.ProcessedVarList.empty())
15061 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
15062 MVLI.VarComponents, MVLI.UDMapperList,
15071 MappableVarListInfo MVLI(VarList);
15073 MapperIdScopeSpec, MapperId, UnresolvedMappers);
15074 if (MVLI.ProcessedVarList.empty())
15078 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
15079 MVLI.VarComponents, MVLI.UDMapperList,
15085 MappableVarListInfo MVLI(VarList);
15089 for (
Expr *RefExpr : VarList) {
15090 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
15093 Expr *SimpleRefExpr = RefExpr;
15097 MVLI.ProcessedVarList.push_back(RefExpr);
15098 PrivateCopies.push_back(
nullptr);
15099 Inits.push_back(
nullptr);
15108 auto *VD = dyn_cast<
VarDecl>(D);
15112 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
15113 << 0 << RefExpr->getSourceRange();
15121 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
15122 if (VDPrivate->isInvalidDecl())
15125 CurContext->addDecl(VDPrivate);
15127 *
this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15131 buildVarDecl(*
this, RefExpr->getExprLoc(), Type,
".devptr.temp");
15133 *
this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
15134 AddInitializerToDecl(VDPrivate,
15135 DefaultLvalueConversion(VDInitRefExpr).
get(),
15143 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
15144 PrivateCopies.push_back(VDPrivateRefExpr);
15145 Inits.push_back(VDInitRefExpr);
15150 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
15154 MVLI.VarBaseDeclarations.push_back(D);
15155 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15156 MVLI.VarComponents.back().push_back(
15160 if (MVLI.ProcessedVarList.empty())
15164 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
15165 MVLI.VarBaseDeclarations, MVLI.VarComponents);
15170 MappableVarListInfo MVLI(VarList);
15171 for (
Expr *RefExpr : VarList) {
15172 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
15175 Expr *SimpleRefExpr = RefExpr;
15179 MVLI.ProcessedVarList.push_back(RefExpr);
15189 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
15190 << 0 << RefExpr->getSourceRange();
15196 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
15198 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15206 const Expr *ConflictExpr;
15207 if (
DSAStack->checkMappableExprComponentListsForDecl(
15212 ConflictExpr = R.front().getAssociatedExpression();
15215 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
15224 DSAStack->addMappableExpressionComponents(
15225 D, MC, OMPC_is_device_ptr);
15228 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
15233 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
15234 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
15235 "Unexpected device pointer expression!");
15236 MVLI.VarBaseDeclarations.push_back(
15237 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
15238 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15239 MVLI.VarComponents.back().push_back(MC);
15242 if (MVLI.ProcessedVarList.empty())
15246 MVLI.VarBaseDeclarations,
15247 MVLI.VarComponents);
15259 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
15262 AllocatorRes = PerformImplicitConversion(AllocatorRes.
get(),
15263 DSAStack->getOMPAllocatorHandleT(),
15268 Allocator = AllocatorRes.
get();
15275 if (LangOpts.OpenMPIsDevice &&
15277 targetDiag(StartLoc, diag::err_expected_allocator_expression);
15281 for (
Expr *RefExpr : VarList) {
15282 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
15285 Expr *SimpleRefExpr = RefExpr;
15289 Vars.push_back(RefExpr);
15295 auto *VD = dyn_cast<
VarDecl>(D);
15297 if (!VD && !CurContext->isDependentContext())
15299 Vars.push_back((VD || CurContext->isDependentContext())
15300 ? RefExpr->IgnoreParens()
15308 ColonLoc, EndLoc, Vars);
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically scheduled 'omp for' loops.
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
void setIsOMPStructuredBlock(bool IsOMPStructuredBlock)
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp master' after parsing of the associated statement.
QualType withConst() const
Retrieves a version of this type with const applied.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp flush'.
void setImplicit(bool I=true)
Represents a function declaration or definition.
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
This represents 'thread_limit' clause in the '#pragma omp ...' directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp section' after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'task_reduction' clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
OMPDeclareMapperDecl * ActOnOpenMPDeclareMapperDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare mapper'.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. '#pragma omp declare target'.
A (possibly-)qualified type.
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Simple class containing the result of Sema::CorrectTypo.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and 'x', 'v' and 'expr' parts of the atomic construct (see S...
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
ArrayRef< OMPClause * > clauses()
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target update'.
static Opcode getOpForCompoundAssignment(Opcode Opc)
SourceLocation getExprLoc() const
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancel'.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
static bool isOpenMPDeviceDelayedContext(Sema &S)
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
This represents 'atomic_default_mem_order' clause in the '#pragma omp requires' directive.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute' after parsing of the associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp critical' after parsing of the associated statement.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'untied' clause.
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
bool isStandaloneDirective() const
Returns whether or not this is a Standalone directive.
Filter makeFilter()
Create a filter for this result set.
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target data' after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Class that handles pre-initialization statement for some clauses, like 'shedule', 'firstprivate' etc...
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
bool isRealFloatingType() const
Floating point categories.
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
void addConst()
Add the const type qualifier to this QualType.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
static bool hasClauses(ArrayRef< OMPClause *> Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
bool isRecordType() const
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause *> Clauses)
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Decl - This represents one declaration (or definition), e.g.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
This represents 'grainsize' clause in the '#pragma omp ...' directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
static constexpr unsigned NumberOfModifiers
Number of allowed map-type-modifiers.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents 'if' clause in the '#pragma omp ...' directive.
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'threads' clause.
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
This represents 'priority' clause in the '#pragma omp ...' directive.
static bool classof(const OMPClause *T)
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target teams' after parsing of the associated statement.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of '#pragma omp declare mapper'.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for simd' after parsing of the associated statement.
const TargetInfo & getTargetInfo() const
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
bool isEmpty() const
Evaluates true when this declaration name is empty.
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp task' after parsing of the associated statement.
void setInitStyle(InitializationStyle Style)
Describes the capture of a variable or of this, or of a C++1y init-capture.
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Represents a C++ constructor within a class.
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for' after parsing of the associa...
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for' after parsing of the associated statement...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Retains information about a function, method, or block that is currently being parsed.
void setNothrow(bool Nothrow=true)
This represents 'read' clause in the '#pragma omp atomic' directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Represents a variable declaration or definition.
ActionResult< Stmt * > StmtResult
Information about one declarator, including the parsed type information and the identifier.
This represents 'num_threads' clause in the '#pragma omp ...' directive.
bool isEnumeralType() const
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
const T * getAs() const
Member-template getAs<specific type>'.
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Extra information about a function prototype.
This represents 'defaultmap' clause in the '#pragma omp ...' directive.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isInvalidDecl() const
void setBegin(SourceLocation b)
static const Expr * getExprAsWritten(const Expr *E)
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp barrier'.
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
bool hasDefinition() const
This represents 'reverse_offload' clause in the '#pragma omp requires' directive. ...
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for' after parsing of the associated statement.
This represents 'nogroup' clause in the '#pragma omp ...' directive.
This represents 'allocator' clause in the '#pragma omp ...' directive.
This represents 'safelen' clause in the '#pragma omp ...' directive.
Expr * LastIteration
Loop last iteration number.
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of '#pragma omp declare reduction'.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed '#pragma omp declare simd' after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
void ActOnUninitializedDecl(Decl *dcl)
OpenMPMapModifierKind
OpenMP modifier kind for 'map' clause.
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.
clauselist_range clauselists()
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
One of these records is kept for each identifier that is lexed.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D)
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, ArrayRef< OMPClause *> ClauseList)
Called at the end of '#pragma omp declare mapper'.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
A C++ nested-name-specifier augmented with source location information.
The results of name lookup within a DeclContext.
This represents 'simd' clause in the '#pragma omp ...' directive.
void CreateClauses(ASTContext &C, ArrayRef< OMPClause *> CL)
Creates an array of clauses to this mapper declaration and intializes them.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Represents a member of a struct/union/class.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute' after parsing of the associated statement...
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'dynamic_allocators' clause.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause *> Clauses)
End of OpenMP region.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
bool isReferenceType() const
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in 'omp declare mapper' construct.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare mapper' construct.
Defines some OpenMP-specific enums and functions.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target exit data' after parsing of the associated statement...
Expr * getSafelen() const
Return safe iteration space distance.
__DEVICE__ int max(int __a, int __b)
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl *> PreInits)
Build preinits statement for the given declarations.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp critical' directive.
void EndOpenMPClause()
End analysis of clauses.
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed '#pragma omp target enter data' after parsing of the associated statement...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
bool isInvalidType() const
DeclClass * getAsSingle() const
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, SourceRange SR)
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
bool isCompleteType(SourceLocation Loc, QualType T)
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed 'to' clause.
Represents the results of name lookup.
DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID)
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp simd' after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing 'omp distribute' with 'omp for' in a same construct...
Expr * EUB
DistributeEnsureUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
APValue Val
Val - This is the value the expression can be folded to.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nogroup' clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'read' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute parallel for simd' after parsing of the as...
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
ValueDecl * getAssociatedDeclaration() const
Concrete class used by the front-end to report problems and issues.
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'capture' clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Look up the name of an OpenMP user-defined reduction operation.
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
SmallVector< MappableComponent, 8 > MappableExprComponentList
This represents 'default' clause in the '#pragma omp ...' directive.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Scope - A scope is a transient data structure that is used while parsing the program.
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the '#pragma omp threadprivate'.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
This represents 'final' clause in the '#pragma omp ...' directive.
This represents 'mergeable' clause in the '#pragma omp ...' directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses)
Creates directive with a list of Clauses.
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Represents a C++ nested-name-specifier or a global scope specifier.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
const LangOptions & getLangOpts() const
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
bool isFloat128Type() const
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp for' after parsing of the associated statement.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
bool isScalarType() const
An ordinary object is located at an address in memory.
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute' after parsing of the associated statement...
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
Represents the body of a CapturedStmt, and serves as its DeclContext.
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
const LangOptions & LangOpts
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
Expr * NUB
Update of UpperBound for statically scheduled 'omp for' loops.
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e.g., it is an unsigned integer type or a vector.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Expr * Cond
Loop condition.
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
DiagnosticsEngine & getDiagnostics() const
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Expr * PreCond
Loop pre-condition.
OpenMP 4.0 [2.4, Array Sections].
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
This represents 'dynamic_allocators' clause in the '#pragma omp requires' directive.
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'write' clause.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause *> Clauses)
ConditionalOperator - The ?: ternary operator.
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Describes the capture of either a variable, or 'this', or variable-length array type.
This represents 'threads' clause in the '#pragma omp ...' directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
Expr * getSimdlen() const
Return safe iteration space distance.
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'nowait' clause.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp sections' after parsing of the associated statement.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like 'private', 'firstprivate', 'reduction' etc.
The return type of classify().
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
DeclarationNameTable DeclarationNames
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build 'ordered' clause.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * DistCond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct whe...
Expr * IterationVarRef
Loop iteration variable.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * Init
Distribute loop iteration variable init used when composing 'omp distribute' with 'omp for' in a same...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
This represents '#pragma omp requires...' directive.
Scope * getCurScope() const
Retrieve the parser's current scope.
This represents implicit clause 'depend' for the '#pragma omp task' directive.
Allows QualTypes to be sorted and hence used in maps and sets.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
This represents 'proc_bind' clause in the '#pragma omp ...' directive.
This represents 'capture' clause in the '#pragma omp atomic' directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
This represents one expression.
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Allow any unmodeled side effect.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents 'simdlen' clause in the '#pragma omp ...' directive.
Look up the name of an OpenMP user-defined mapper.
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
const T * castAs() const
Member-template castAs<specific type>.
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'mergeable' clause.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
std::string getAsString() const
Retrieve the human-readable string for this name.
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
OpenMPClauseKind
OpenMP clauses.
bool isFileContext() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskyield'.
SourceLocation getBeginLoc() const
DeclContext * getDeclContext()
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
bool isAnyComplexType() const
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is used in 'private' clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target parallel for simd' after parsing of the associated statemen...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
This represents 'ordered' clause in the '#pragma omp ...' directive.
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
Expr * ParForInDistCond
'omp parallel for' loop condition used when composed with 'omp distribute' in the same construct and ...
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'in_reduction' clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
This represents 'collapse' clause in the '#pragma omp ...' directive.
Represents a C++ conversion function within a class.
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
The result type of a method or function.
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop' after parsing of the associated statement.
OpenMPProcBindClauseKind
OpenMP attributes for 'proc_bind' clause.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel' after parsing of the associated statement.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target simd' after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause *> ClauseList)
Called on well-formed '#pragma omp requires'.
Expr * NumIterations
Loop number of iterations.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause *> Clauses)
Check restrictions on Requires directive.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
This represents 'seq_cst' clause in the '#pragma omp atomic' directive.
This represents 'untied' clause in the '#pragma omp ...' directive.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Expr * ST
Stride - local variable passed to runtime.
This represents 'unified_address' clause in the '#pragma omp requires' directive. ...
bool isStructureOrClassType() const
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'atomic_default_mem_order' clause.
This represents 'num_teams' clause in the '#pragma omp ...' directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
This captures a statement into a function.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
QualType getCanonicalType() const
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
SourceLocation LParenLoc
Location of '('.
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
ASTContext & getASTContext() const
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents 'hint' clause in the '#pragma omp ...' directive.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
SourceLocation getOperatorLoc() const
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
Diagnostic builder for CUDA/OpenMP devices errors which may or may not be deferred.
This represents '#pragma omp declare reduction ...' directive.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute simd' after parsing of the associated statement...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Pseudo declaration for capturing expressions.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
This is a basic class for representing single OpenMP executable directive.
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList, ArrayRef< OMPClause *> Clauses, DeclContext *Owner=nullptr)
Called on well-formed '#pragma omp allocate'.
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL, ArrayRef< OMPClause *> CL)
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents 'schedule' clause in the '#pragma omp ...' directive.
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr *> PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
void setReferenced(bool R=true)
OpenMPDirectiveKind
OpenMP directives.
IdentifierTable & getIdentifierTable()
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for simd' after parsing of the associate...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute simd' after parsing of the associated statement...
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
SourceLocation getColonLoc() const
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed '#pragma omp cancellation point'.
OpenMPLinearClauseKind Modifier
Modifier of 'linear' clause.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
ExprResult DefaultLvalueConversion(Expr *E)
C-style initialization with assignment.
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
This file defines OpenMP nodes for declarative directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
This is a basic class for representing single OpenMP clause.
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'update' clause.
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const
Return true if the provided declaration VD should be captured by reference.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp ordered' after parsing of the associated statement.
Look up any declaration with any name.
bool isAnyPointerType() const
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
A class for iterating through a result set and possibly filtering out results.
This declaration is only a declaration.
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target' after parsing of the associated statement.
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda's captured variables in the OpenMP region before the original lambda...
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
void setMapperVarRef(Expr *MapperVarRefE)
Set the variable declared in the mapper.
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'seq_cst' clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
SourceLocation EndLoc
Ending location of the clause.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
DefaultMapAttributes
Attributes of the defaultmap clause.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr *> Vars, Expr *TailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
static bool isKnownEmitted(Sema &S, FunctionDecl *FD)
Do we know that we will eventually codegen the given function?
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
QualType withRestrict() const
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
This represents 'device' clause in the '#pragma omp ...' directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isFloat16Type() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
EvalResult is a struct with detailed info about an evaluated expression.
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
const Scope * getParent() const
getParent - Return the scope that this is nested in.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const Expr * getInit() const
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
This represents clause 'linear' in the '#pragma omp ...' directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is captured by 'target' directive.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of '#pragma omp declare reduction'.
virtual bool hasFloat16Type() const
Determine whether the _Float16 type is supported on this target.
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like 'threadprivate', 'copyin' or 'copyprivate'.
DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a DeviceDiagBuilder that emits the diagnostic if the current context is "used as device code"...
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored, perform any conversions that are required.
SourceLocation getEndLoc() const
Returns the ending location of the clause.
Class that represents a component of a mappable expression.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed 'from' clause.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp target teams distribute simd' after parsing of the associated stat...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point...
Not an overloaded operator.
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. '#pragme omp end declare target'.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Complex values, per C99 6.2.5p11.
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
This file defines OpenMP AST classes for executable directives and clauses.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S'...
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, NonOdrUseReason NOUR=NOUR_None)
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Expr * Inc
Loop increment.
DeclContext * getCurLexicalContext() const
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Base for LValueReferenceType and RValueReferenceType.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
ImplicitParamDecl * getParam(unsigned i) const
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed 'reduction' clause.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in 'omp declare reduction' construct.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build 'VarRef = Start.
OpenMPDefaultClauseKind
OpenMP attributes for 'default' clause.
virtual bool hasFloat128Type() const
Determine whether the __float128 type is supported on this target.
void addDecl(Decl *D)
Add the declaration D into this context.
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for simd' after parsing of the associated stat...
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause *> CL)
Create requires node.
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
Capturing the *this object by reference.
This represents 'write' clause in the '#pragma omp atomic' directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
const Type * getTypePtrOrNull() const
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel for simd' after parsing of the associated statement...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp taskloop simd' after parsing of the associated statement...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool isSet() const
Deprecated.
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp teams' after parsing of the associated statement.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
void Deallocate(void *Ptr) const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskgroup'.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don't want any more diagnosti...
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
This represents 'nowait' clause in the '#pragma omp ...' directive.
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the '#pragma omp declare target'.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Represents a C++ struct/union/class.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
This represents 'num_tasks' clause in the '#pragma omp ...' directive.
sema::FunctionScopeInfo * getCurFunction() const
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp taskwait'.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Privates[]
Gets the list of initial values for linear variables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Do not present this diagnostic, ignore it.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp atomic' after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp single' after parsing of the associated statement.
This represents '#pragma omp declare mapper ...' directive.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
__DEVICE__ int min(int __a, int __b)
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed '#pragma omp threadprivate'.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
This represents 'dist_schedule' clause in the '#pragma omp ...' directive.
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
Expr * Cond
Distribute Loop condition used when composing 'omp distribute' with 'omp for' in a same construct...
Stmt * PreInits
Init statement for all captured expressions.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::DenseMap< CanonicalDeclPtr< FunctionDecl >, FunctionDeclAndLoc > DeviceKnownEmittedFns
An inverse call graph, mapping known-emitted functions to one of their known-emitted callers (plus th...
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
This structure contains most locations needed for by an OMPVarListClause.
bool isStaticDataMember() const
Determines whether this is a static data member.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
bool empty() const
Return true if no decls were found.
An l-value expression is a reference to an object with independent storage.
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel sections' after parsing of the associated statement...
A wrapper class around a pointer that always points to its canonical declaration. ...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
A trivial tuple used to represent a source range.
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
This represents a decl that may have a name.
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
bool isTranslationUnit() const
void setAccess(AccessSpecifier AS)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
bool isConstant(const ASTContext &Ctx) const
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
static OMPClauseWithPostUpdate * get(OMPClause *C)
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'reverse_offload' clause.
Describes an entity that is being initialized.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr *> UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of ':'.
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
This represents '#pragma omp threadprivate ...' directive.
VerifyDiagnosticConsumer::Directive Directive
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Represents the canonical version of C arrays with a specified constant size.
bool getSuppressAllDiagnostics() const
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
SourceLocation getLocation() const
QualType getType() const
Return the type wrapped by this type source info.
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp teams distribute parallel for' after parsing of the associated sta...
Expr * getLength()
Get length of array section.
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp distribute parallel for' after parsing of the associated statement...
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
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.
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed 'map' clause.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
SourceLocation StartLoc
Starting location of the clause (the clause keyword).