32 #include "llvm/ADT/IndexedMap.h" 33 #include "llvm/ADT/PointerEmbeddedInt.h" 34 #include "llvm/Frontend/OpenMP/OMPConstants.h" 35 using namespace clang;
62 const Expr *RefExpr =
nullptr;
65 DSAVarData() =
default;
69 : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
70 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
72 using OperatorOffsetTy =
74 using DoacrossDependMapTy =
75 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
82 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
86 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
87 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
88 using LoopControlVariablesMapTy =
89 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92 struct MappedExprComponentTy {
96 using MappedExprComponentsTy =
97 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
98 using CriticalsWithHintsTy =
99 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
100 struct ReductionData {
101 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104 ReductionData() =
default;
111 ReductionOp = RefExpr;
114 using DeclReductionMapTy =
115 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
116 struct DefaultmapInfo {
120 DefaultmapInfo() =
default;
122 : ImplicitBehavior(M), SLoc(Loc) {}
125 struct SharingMapTy {
126 DeclSAMapTy SharingMap;
127 DeclReductionMapTy ReductionMap;
128 UsedRefMapTy AlignedMap;
129 UsedRefMapTy NontemporalMap;
130 MappedExprComponentsTy MappedExprComponents;
131 LoopControlVariablesMapTy LCVMap;
137 Scope *CurScope =
nullptr;
142 DoacrossDependMapTy DoacrossDepends;
147 unsigned AssociatedLoops = 1;
148 bool HasMutipleLoops =
false;
149 const Decl *PossiblyLoopCounter =
nullptr;
150 bool NowaitRegion =
false;
151 bool CancelRegion =
false;
152 bool LoopStart =
false;
153 bool BodyComplete =
false;
156 Expr *TaskgroupReductionRef =
nullptr;
163 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
165 SharingMapTy() =
default;
171 DeclSAMapTy Threadprivates;
178 bool ForceCapturing =
false;
181 bool ForceCaptureByReferenceInTargetExecutable =
false;
182 CriticalsWithHintsTy Criticals;
183 unsigned IgnoredStackElements = 0;
187 using const_iterator = StackTy::const_reverse_iterator;
188 const_iterator begin()
const {
189 return Stack.empty() ? const_iterator()
190 : Stack.back().first.rbegin() + IgnoredStackElements;
192 const_iterator end()
const {
193 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
195 using iterator = StackTy::reverse_iterator;
198 : Stack.back().first.rbegin() + IgnoredStackElements;
201 return Stack.empty() ?
iterator() : Stack.back().first.rend();
206 bool isStackEmpty()
const {
207 return Stack.empty() ||
208 Stack.back().second != CurrentNonCapturingFunctionScope ||
209 Stack.back().first.size() <= IgnoredStackElements;
211 size_t getStackSize()
const {
212 return isStackEmpty() ? 0
213 : Stack.back().first.size() - IgnoredStackElements;
216 SharingMapTy *getTopOfStackOrNull() {
217 size_t Size = getStackSize();
220 return &Stack.back().first[Size - 1];
222 const SharingMapTy *getTopOfStackOrNull()
const {
223 return const_cast<DSAStackTy&
>(*this).getTopOfStackOrNull();
225 SharingMapTy &getTopOfStack() {
226 assert(!isStackEmpty() &&
"no current directive");
227 return *getTopOfStackOrNull();
229 const SharingMapTy &getTopOfStack()
const {
230 return const_cast<DSAStackTy&
>(*this).getTopOfStack();
233 SharingMapTy *getSecondOnStackOrNull() {
234 size_t Size = getStackSize();
237 return &Stack.back().first[Size - 2];
239 const SharingMapTy *getSecondOnStackOrNull()
const {
240 return const_cast<DSAStackTy&
>(*this).getSecondOnStackOrNull();
249 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
250 assert(Level < getStackSize() &&
"no such stack element");
251 return Stack.back().first[
Level];
253 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
254 return const_cast<DSAStackTy&
>(*this).getStackElemAtLevel(Level);
257 DSAVarData getDSA(const_iterator &Iter,
ValueDecl *D)
const;
260 bool isOpenMPLocal(
VarDecl *D, const_iterator Iter)
const;
267 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
273 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
276 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
278 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
280 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
282 OMPPredefinedAllocators[AllocatorKind] = Allocator;
285 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
286 return OMPPredefinedAllocators[AllocatorKind];
289 bool isClauseParsingMode()
const {
return ClauseKindMode !=
OMPC_unknown; }
291 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
292 return ClauseKindMode;
296 bool isBodyComplete()
const {
297 const SharingMapTy *Top = getTopOfStackOrNull();
298 return Top && Top->BodyComplete;
300 void setBodyComplete() {
301 getTopOfStack().BodyComplete =
true;
304 bool isForceVarCapturing()
const {
return ForceCapturing; }
305 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
307 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
308 ForceCaptureByReferenceInTargetExecutable =
V;
310 bool isForceCaptureByReferenceInTargetExecutable()
const {
311 return ForceCaptureByReferenceInTargetExecutable;
316 assert(!IgnoredStackElements &&
317 "cannot change stack while ignoring elements");
319 Stack.back().second != CurrentNonCapturingFunctionScope)
320 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
321 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
322 Stack.back().first.back().DefaultAttrLoc = Loc;
326 assert(!IgnoredStackElements &&
327 "cannot change stack while ignoring elements");
328 assert(!Stack.back().first.empty() &&
329 "Data-sharing attributes stack is empty!");
330 Stack.back().first.pop_back();
335 class ParentDirectiveScope {
339 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
340 : Self(Self), Active(
false) {
344 ~ParentDirectiveScope() { disable(); }
347 --Self.IgnoredStackElements;
353 ++Self.IgnoredStackElements;
362 "Expected loop-based directive.");
363 getTopOfStack().LoopStart =
true;
368 "Expected loop-based directive.");
369 getTopOfStack().LoopStart =
false;
372 bool isLoopStarted()
const {
374 "Expected loop-based directive.");
375 return !getTopOfStack().LoopStart;
378 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
379 getTopOfStack().PossiblyLoopCounter =
383 const Decl *getPossiblyLoopCunter()
const {
384 return getTopOfStack().PossiblyLoopCounter;
387 void pushFunction() {
388 assert(!IgnoredStackElements &&
389 "cannot change stack while ignoring elements");
391 assert(!isa<CapturingScopeInfo>(CurFnScope));
392 CurrentNonCapturingFunctionScope = CurFnScope;
396 assert(!IgnoredStackElements &&
397 "cannot change stack while ignoring elements");
398 if (!Stack.empty() && Stack.back().second == OldFSI) {
399 assert(Stack.back().first.empty());
402 CurrentNonCapturingFunctionScope =
nullptr;
404 if (!isa<CapturingScopeInfo>(FSI)) {
405 CurrentNonCapturingFunctionScope = FSI;
414 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
417 if (I != Criticals.end())
436 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
441 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
444 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
457 const Expr *ReductionRef);
463 Expr *&TaskgroupDescriptor)
const;
468 const Expr *&ReductionRef,
469 Expr *&TaskgroupDescriptor)
const;
471 Expr *getTaskgroupReductionRef()
const {
472 assert(getTopOfStack().
Directive == OMPD_taskgroup &&
473 "taskgroup reference expression requested for non taskgroup " 475 return getTopOfStack().TaskgroupReductionRef;
479 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
480 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
481 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
487 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
489 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
496 bool FromParent)
const;
504 bool FromParent)
const;
510 unsigned Level,
bool NotLastprivate =
false)
const;
514 bool hasExplicitDirective(
516 unsigned Level)
const;
520 const llvm::function_ref<
bool(
523 bool FromParent)
const;
527 const SharingMapTy *Top = getTopOfStackOrNull();
528 return Top ? Top->Directive : OMPD_unknown;
532 assert(!isStackEmpty() &&
"No directive at specified level.");
533 return getStackElemAtLevel(Level).Directive;
537 unsigned OpenMPCaptureLevel)
const {
540 return CaptureRegions[OpenMPCaptureLevel];
544 const SharingMapTy *
Parent = getSecondOnStackOrNull();
545 return Parent ? Parent->Directive : OMPD_unknown;
550 RequiresDecls.push_back(RD);
554 template <
typename ClauseType>
555 bool hasRequiresDeclWithClause() {
558 return isa<ClauseType>(
C);
565 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList)
const {
566 bool IsDuplicate =
false;
569 for (
const OMPClause *CPrev : D->clauselists()) {
570 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
571 SemaRef.
Diag(CNew->getBeginLoc(),
572 diag::err_omp_requires_clause_redeclaration)
574 SemaRef.
Diag(CPrev->getBeginLoc(),
575 diag::note_omp_requires_previous_clause)
587 TargetLocations.push_back(LocStart);
591 ArrayRef<SourceLocation> getEncounteredTargetLocs()
const {
592 return TargetLocations;
597 getTopOfStack().DefaultAttr = DSA_none;
598 getTopOfStack().DefaultAttrLoc = Loc;
602 getTopOfStack().DefaultAttr = DSA_shared;
603 getTopOfStack().DefaultAttrLoc = Loc;
609 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
610 DMI.ImplicitBehavior = M;
615 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
620 return isStackEmpty() ? DSA_unspecified
621 : getTopOfStack().DefaultAttr;
625 : getTopOfStack().DefaultAttrLoc;
629 return isStackEmpty()
631 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
634 getDefaultmapModifierAtLevel(
unsigned Level,
636 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
638 bool isDefaultmapCapturedByRef(
unsigned Level,
641 getDefaultmapModifierAtLevel(Level, Kind);
642 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
643 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
644 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
645 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
646 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
653 case OMPC_DEFAULTMAP_scalar:
654 case OMPC_DEFAULTMAP_pointer:
656 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
657 (M == OMPC_DEFAULTMAP_MODIFIER_default);
658 case OMPC_DEFAULTMAP_aggregate:
659 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
663 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
665 bool mustBeFirstprivateAtLevel(
unsigned Level,
668 getDefaultmapModifierAtLevel(Level, Kind);
669 return mustBeFirstprivateBase(M, Kind);
673 return mustBeFirstprivateBase(M, Kind);
677 bool isThreadPrivate(
VarDecl *D) {
678 const DSAVarData DVar = getTopDSA(D,
false);
683 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
686 getTopOfStack().OrderedRegion.emplace(Param, Clause);
688 getTopOfStack().OrderedRegion.reset();
692 bool isOrderedRegion()
const {
693 if (
const SharingMapTy *Top = getTopOfStackOrNull())
694 return Top->OrderedRegion.hasValue();
698 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
699 if (
const SharingMapTy *Top = getTopOfStackOrNull())
700 if (Top->OrderedRegion.hasValue())
701 return Top->OrderedRegion.getValue();
702 return std::make_pair(
nullptr,
nullptr);
706 bool isParentOrderedRegion()
const {
707 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
708 return Parent->OrderedRegion.hasValue();
712 std::pair<const Expr *, OMPOrderedClause *>
713 getParentOrderedRegionParam()
const {
714 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
715 if (
Parent->OrderedRegion.hasValue())
716 return Parent->OrderedRegion.getValue();
717 return std::make_pair(
nullptr,
nullptr);
720 void setNowaitRegion(
bool IsNowait =
true) {
721 getTopOfStack().NowaitRegion = IsNowait;
725 bool isParentNowaitRegion()
const {
726 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
727 return Parent->NowaitRegion;
731 void setParentCancelRegion(
bool Cancel =
true) {
732 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
733 Parent->CancelRegion |= Cancel;
736 bool isCancelRegion()
const {
737 const SharingMapTy *Top = getTopOfStackOrNull();
738 return Top ? Top->CancelRegion :
false;
742 void setAssociatedLoops(
unsigned Val) {
743 getTopOfStack().AssociatedLoops = Val;
745 getTopOfStack().HasMutipleLoops =
true;
748 unsigned getAssociatedLoops()
const {
749 const SharingMapTy *Top = getTopOfStackOrNull();
750 return Top ? Top->AssociatedLoops : 0;
753 bool hasMutipleLoops()
const {
754 const SharingMapTy *Top = getTopOfStackOrNull();
755 return Top ? Top->HasMutipleLoops :
false;
761 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
762 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
765 bool hasInnerTeamsRegion()
const {
766 return getInnerTeamsRegionLoc().
isValid();
770 const SharingMapTy *Top = getTopOfStackOrNull();
774 Scope *getCurScope()
const {
775 const SharingMapTy *Top = getTopOfStackOrNull();
776 return Top ? Top->CurScope :
nullptr;
779 const SharingMapTy *Top = getTopOfStackOrNull();
785 bool checkMappableExprComponentListsForDecl(
786 const ValueDecl *VD,
bool CurrentRegionOnly,
787 const llvm::function_ref<
799 if (CurrentRegionOnly)
804 for (; SI != SE; ++SI) {
805 auto MI = SI->MappedExprComponents.find(VD);
806 if (MI != SI->MappedExprComponents.end())
808 MI->second.Components)
809 if (Check(L, MI->second.Kind))
817 bool checkMappableExprComponentListsForDeclAtLevel(
819 const llvm::function_ref<
823 if (getStackSize() <= Level)
826 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
827 auto MI = StackElem.MappedExprComponents.find(VD);
828 if (MI != StackElem.MappedExprComponents.end())
830 MI->second.Components)
831 if (Check(L, MI->second.Kind))
838 void addMappableExpressionComponents(
842 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
844 MEC.Components.resize(MEC.Components.size() + 1);
845 MEC.Components.back().append(Components.begin(), Components.end());
846 MEC.Kind = WhereFoundClauseKind;
849 unsigned getNestingLevel()
const {
850 assert(!isStackEmpty());
851 return getStackSize() - 1;
854 const OperatorOffsetTy &OpsOffs) {
855 SharingMapTy *
Parent = getSecondOnStackOrNull();
857 Parent->DoacrossDepends.try_emplace(C, OpsOffs);
859 llvm::iterator_range<DoacrossDependMapTy::const_iterator>
860 getDoacrossDependClauses()
const {
861 const SharingMapTy &StackElem = getTopOfStack();
863 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
864 return llvm::make_range(Ref.begin(), Ref.end());
866 return llvm::make_range(StackElem.DoacrossDepends.end(),
867 StackElem.DoacrossDepends.end());
871 void addMappedClassesQualTypes(
QualType QT) {
872 SharingMapTy &StackElem = getTopOfStack();
873 StackElem.MappedClassesQualTypes.insert(QT);
877 bool isClassPreviouslyMapped(
QualType QT)
const {
878 const SharingMapTy &StackElem = getTopOfStack();
879 return StackElem.MappedClassesQualTypes.count(QT) != 0;
883 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
884 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
885 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
886 "Expected declare target link global.");
887 for (
auto &Elem : *
this) {
889 Elem.DeclareTargetLinkVarDecls.push_back(E);
897 ArrayRef<DeclRefExpr *> getLinkGlobals()
const {
899 "Expected target executable directive.");
900 return getTopOfStack().DeclareTargetLinkVarDecls;
910 DKind == OMPD_unknown;
916 if (
const auto *FE = dyn_cast<FullExpr>(E))
917 E = FE->getSubExpr();
919 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
920 E = MTE->getSubExpr();
922 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
923 E = Binder->getSubExpr();
925 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
926 E = ICE->getSubExprAsWritten();
935 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
936 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
937 D = ME->getMemberDecl();
938 const auto *VD = dyn_cast<
VarDecl>(D);
945 FD = FD->getCanonicalDecl();
956 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
959 auto *VD = dyn_cast<
VarDecl>(D);
968 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
969 DVar.CKind = OMPC_shared;
975 if (VD && VD->hasGlobalStorage())
976 DVar.CKind = OMPC_shared;
980 DVar.CKind = OMPC_shared;
989 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
990 (VD->getStorageClass() ==
SC_Auto || VD->getStorageClass() ==
SC_None)) {
991 DVar.CKind = OMPC_private;
995 DVar.DKind = Iter->Directive;
998 if (Iter->SharingMap.count(D)) {
999 const DSAInfo &Data = Iter->SharingMap.lookup(D);
1000 DVar.RefExpr = Data.RefExpr.getPointer();
1001 DVar.PrivateCopy = Data.PrivateCopy;
1002 DVar.CKind = Data.Attributes;
1003 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1011 switch (Iter->DefaultAttr) {
1013 DVar.CKind = OMPC_shared;
1014 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1018 case DSA_unspecified:
1023 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1027 DVar.CKind = OMPC_shared;
1037 DSAVarData DVarTemp;
1038 const_iterator I = Iter, E = end();
1046 DVarTemp = getDSA(I, D);
1047 if (DVarTemp.CKind != OMPC_shared) {
1048 DVar.RefExpr =
nullptr;
1049 DVar.CKind = OMPC_firstprivate;
1052 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1054 (DVarTemp.CKind ==
OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1063 return getDSA(++Iter, D);
1066 const Expr *DSAStackTy::addUniqueAligned(
const ValueDecl *D,
1067 const Expr *NewDE) {
1068 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1070 SharingMapTy &StackElem = getTopOfStack();
1071 auto It = StackElem.AlignedMap.find(D);
1072 if (It == StackElem.AlignedMap.end()) {
1073 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1074 StackElem.AlignedMap[D] = NewDE;
1077 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1081 const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1082 const Expr *NewDE) {
1083 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1085 SharingMapTy &StackElem = getTopOfStack();
1086 auto It = StackElem.NontemporalMap.find(D);
1087 if (It == StackElem.NontemporalMap.end()) {
1088 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1089 StackElem.NontemporalMap[D] = NewDE;
1092 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1097 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1099 SharingMapTy &StackElem = getTopOfStack();
1100 StackElem.LCVMap.try_emplace(
1101 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1104 const DSAStackTy::LCDeclInfo
1105 DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1106 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1108 const SharingMapTy &StackElem = getTopOfStack();
1109 auto It = StackElem.LCVMap.find(D);
1110 if (It != StackElem.LCVMap.end())
1112 return {0,
nullptr};
1115 const DSAStackTy::LCDeclInfo
1116 DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1117 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1118 assert(Parent &&
"Data-sharing attributes stack is empty");
1120 auto It = Parent->LCVMap.find(D);
1121 if (It != Parent->LCVMap.end())
1123 return {0,
nullptr};
1126 const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1127 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1128 assert(Parent &&
"Data-sharing attributes stack is empty");
1129 if (Parent->LCVMap.size() < I)
1131 for (
const auto &Pair : Parent->LCVMap)
1132 if (Pair.second.first == I)
1141 DSAInfo &Data = Threadprivates[D];
1142 Data.Attributes = A;
1143 Data.RefExpr.setPointer(E);
1144 Data.PrivateCopy =
nullptr;
1146 DSAInfo &Data = getTopOfStack().SharingMap[D];
1147 assert(Data.Attributes ==
OMPC_unknown || (A == Data.Attributes) ||
1148 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1149 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1150 (isLoopControlVariable(D).first && A == OMPC_private));
1151 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1152 Data.RefExpr.setInt(
true);
1155 const bool IsLastprivate =
1156 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1157 Data.Attributes = A;
1158 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1159 Data.PrivateCopy = PrivateCopy;
1161 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1162 Data.Attributes = A;
1163 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1164 Data.PrivateCopy =
nullptr;
1171 StringRef Name,
const AttrVec *Attrs =
nullptr,
1186 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1193 bool RefersToCapture =
false) {
1204 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1206 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1207 "Additional reduction info may be specified only for reduction items.");
1208 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1209 assert(ReductionData.ReductionRange.isInvalid() &&
1210 getTopOfStack().Directive == OMPD_taskgroup &&
1211 "Additional reduction info may be specified only once for reduction " 1213 ReductionData.set(BOK, SR);
1214 Expr *&TaskgroupReductionRef =
1215 getTopOfStack().TaskgroupReductionRef;
1216 if (!TaskgroupReductionRef) {
1218 SemaRef.Context.VoidPtrTy,
".task_red.");
1219 TaskgroupReductionRef =
1225 const Expr *ReductionRef) {
1227 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1229 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1230 "Additional reduction info may be specified only for reduction items.");
1231 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1232 assert(ReductionData.ReductionRange.isInvalid() &&
1233 getTopOfStack().Directive == OMPD_taskgroup &&
1234 "Additional reduction info may be specified only once for reduction " 1236 ReductionData.set(ReductionRef, SR);
1237 Expr *&TaskgroupReductionRef =
1238 getTopOfStack().TaskgroupReductionRef;
1239 if (!TaskgroupReductionRef) {
1241 SemaRef.Context.VoidPtrTy,
".task_red.");
1242 TaskgroupReductionRef =
1247 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1249 Expr *&TaskgroupDescriptor)
const {
1251 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1252 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1253 const DSAInfo &Data = I->SharingMap.lookup(D);
1254 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1256 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1257 if (!ReductionData.ReductionOp ||
1258 ReductionData.ReductionOp.is<
const Expr *>())
1259 return DSAVarData();
1260 SR = ReductionData.ReductionRange;
1261 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1262 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1263 "expression for the descriptor is not " 1265 TaskgroupDescriptor = I->TaskgroupReductionRef;
1266 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1267 Data.PrivateCopy, I->DefaultAttrLoc);
1269 return DSAVarData();
1272 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1274 Expr *&TaskgroupDescriptor)
const {
1276 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1277 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1278 const DSAInfo &Data = I->SharingMap.lookup(D);
1279 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1281 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1282 if (!ReductionData.ReductionOp ||
1283 !ReductionData.ReductionOp.is<
const Expr *>())
1284 return DSAVarData();
1285 SR = ReductionData.ReductionRange;
1286 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1287 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference " 1288 "expression for the descriptor is not " 1290 TaskgroupDescriptor = I->TaskgroupReductionRef;
1291 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1292 Data.PrivateCopy, I->DefaultAttrLoc);
1294 return DSAVarData();
1297 bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1299 for (const_iterator E = end(); I != E; ++I) {
1300 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1302 Scope *TopScope = I->CurScope ? I->CurScope->
getParent() :
nullptr;
1303 Scope *CurScope = getCurScope();
1304 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1306 return CurScope != TopScope;
1313 bool AcceptIfMutable =
true,
1314 bool *IsClassType =
nullptr) {
1322 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1324 RD = CTD->getTemplatedDecl();
1327 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1334 bool AcceptIfMutable =
true,
1335 bool ListItemNotVar =
false) {
1339 unsigned Diag = ListItemNotVar
1340 ? diag::err_omp_const_list_item
1341 : IsClassType ? diag::err_omp_const_not_mutable_variable
1342 : diag::err_omp_const_variable;
1344 if (!ListItemNotVar && D) {
1349 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1357 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1362 auto *VD = dyn_cast<
VarDecl>(D);
1363 auto TI = Threadprivates.find(D);
1364 if (TI != Threadprivates.end()) {
1365 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1369 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1372 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1381 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1382 SemaRef.getLangOpts().OpenMPUseTLS &&
1383 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1385 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1392 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1393 VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1394 !isLoopControlVariable(D).first) {
1395 const_iterator IterTarget =
1396 std::find_if(begin(), end(), [](
const SharingMapTy &Data) {
1399 if (IterTarget != end()) {
1400 const_iterator ParentIterTarget = IterTarget + 1;
1401 for (const_iterator Iter = begin();
1402 Iter != ParentIterTarget; ++Iter) {
1403 if (isOpenMPLocal(VD, Iter)) {
1411 if (!isClauseParsingMode() || IterTarget != begin()) {
1412 auto DSAIter = IterTarget->SharingMap.find(D);
1413 if (DSAIter != IterTarget->SharingMap.end() &&
1415 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1419 const_iterator
End = end();
1420 if (!SemaRef.isOpenMPCapturedByRef(
1425 IterTarget->ConstructLoc);
1444 if (VD && VD->isStaticDataMember()) {
1446 const_iterator I = begin();
1447 const_iterator EndI = end();
1448 if (FromParent && I != EndI)
1450 auto It = I->SharingMap.find(D);
1451 if (It != I->SharingMap.end()) {
1452 const DSAInfo &Data = It->getSecond();
1453 DVar.RefExpr = Data.RefExpr.getPointer();
1454 DVar.PrivateCopy = Data.PrivateCopy;
1455 DVar.CKind = Data.Attributes;
1456 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1457 DVar.DKind = I->Directive;
1461 DVar.CKind = OMPC_shared;
1468 if (SemaRef.LangOpts.OpenMP <= 31) {
1476 DSAVarData DVarTemp = hasInnermostDSA(
1479 return C == OMPC_firstprivate || C == OMPC_shared;
1481 MatchesAlways, FromParent);
1482 if (DVarTemp.CKind !=
OMPC_unknown && DVarTemp.RefExpr)
1485 DVar.CKind = OMPC_shared;
1492 const_iterator I = begin();
1493 const_iterator EndI = end();
1494 if (FromParent && I != EndI)
1496 auto It = I->SharingMap.find(D);
1497 if (It != I->SharingMap.end()) {
1498 const DSAInfo &Data = It->getSecond();
1499 DVar.RefExpr = Data.RefExpr.getPointer();
1500 DVar.PrivateCopy = Data.PrivateCopy;
1501 DVar.CKind = Data.Attributes;
1502 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1503 DVar.DKind = I->Directive;
1509 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1510 bool FromParent)
const {
1511 if (isStackEmpty()) {
1513 return getDSA(I, D);
1516 const_iterator StartI = begin();
1517 const_iterator EndI = end();
1518 if (FromParent && StartI != EndI)
1520 return getDSA(StartI, D);
1523 const DSAStackTy::DSAVarData
1527 bool FromParent)
const {
1531 const_iterator I = begin();
1532 const_iterator EndI = end();
1533 if (FromParent && I != EndI)
1535 for (; I != EndI; ++I) {
1536 if (!DPred(I->Directive) &&
1537 !isImplicitOrExplicitTaskingRegion(I->Directive))
1539 const_iterator NewI = I;
1540 DSAVarData DVar = getDSA(NewI, D);
1541 if (I == NewI && CPred(DVar.CKind))
1547 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1550 bool FromParent)
const {
1554 const_iterator StartI = begin();
1555 const_iterator EndI = end();
1556 if (FromParent && StartI != EndI)
1558 if (StartI == EndI || !DPred(StartI->Directive))
1560 const_iterator NewI = StartI;
1561 DSAVarData DVar = getDSA(NewI, D);
1562 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1565 bool DSAStackTy::hasExplicitDSA(
1567 unsigned Level,
bool NotLastprivate)
const {
1568 if (getStackSize() <=
Level)
1571 const SharingMapTy &StackElem = getStackElemAtLevel(
Level);
1572 auto I = StackElem.SharingMap.find(D);
1573 if (I != StackElem.SharingMap.end() &&
1574 I->getSecond().RefExpr.getPointer() &&
1575 CPred(I->getSecond().Attributes) &&
1576 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1579 auto LI = StackElem.LCVMap.find(D);
1580 if (LI != StackElem.LCVMap.end())
1581 return CPred(OMPC_private);
1585 bool DSAStackTy::hasExplicitDirective(
1587 unsigned Level)
const {
1588 if (getStackSize() <= Level)
1590 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1591 return DPred(StackElem.Directive);
1594 bool DSAStackTy::hasDirective(
1598 bool FromParent)
const {
1600 size_t Skip = FromParent ? 2 : 1;
1601 for (const_iterator I = begin() +
std::min(Skip, getStackSize()), E = end();
1603 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1609 void Sema::InitDataSharingAttributesStack() {
1610 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
1613 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1615 void Sema::pushOpenMPFunctionRegion() {
1625 "Expected OpenMP device compilation.");
1641 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1642 "Expected OpenMP device compilation.");
1646 case FunctionEmissionStatus::Emitted:
1647 Kind = DeviceDiagBuilder::K_Immediate;
1651 : DeviceDiagBuilder::K_Immediate;
1653 case FunctionEmissionStatus::TemplateDiscarded:
1654 case FunctionEmissionStatus::OMPDiscarded:
1655 Kind = DeviceDiagBuilder::K_Nop;
1657 case FunctionEmissionStatus::CUDADiscarded:
1658 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
1667 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1668 "Expected OpenMP host compilation.");
1672 case FunctionEmissionStatus::Emitted:
1673 Kind = DeviceDiagBuilder::K_Immediate;
1676 Kind = DeviceDiagBuilder::K_Deferred;
1678 case FunctionEmissionStatus::TemplateDiscarded:
1679 case FunctionEmissionStatus::OMPDiscarded:
1680 case FunctionEmissionStatus::CUDADiscarded:
1681 Kind = DeviceDiagBuilder::K_Nop;
1689 bool CheckForDelayedContext) {
1690 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1691 "Expected OpenMP device compilation.");
1692 assert(Callee &&
"Callee may not be null.");
1700 assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&
1701 CalleeS != FunctionEmissionStatus::CUDADiscarded &&
1702 "CUDADiscarded unexpected in OpenMP device function check");
1703 if ((CallerS == FunctionEmissionStatus::Emitted ||
1706 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1709 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1710 Diag(Callee->
getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1711 diag::note_omp_marked_device_type_here)
1719 (!Caller && !CheckForDelayedContext) ||
1720 (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1721 markKnownEmitted(*
this, Caller, Callee, Loc,
1723 return CheckForDelayedContext &&
1725 FunctionEmissionStatus::Emitted;
1728 DeviceCallGraph[Caller].insert({Callee, Loc});
1733 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1734 "Expected OpenMP host compilation.");
1735 assert(Callee &&
"Callee may not be null.");
1744 (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&
1745 CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&
1746 "CUDADiscarded unexpected in OpenMP host function check");
1747 if (CallerS == FunctionEmissionStatus::Emitted &&
1748 CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1751 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1752 Diag(Callee->
getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1753 diag::note_omp_marked_device_type_here)
1760 if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1761 if ((!CheckCaller && !Caller) ||
1763 getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1766 return CheckCaller &&
1770 DeviceCallGraph[Caller].insert({Callee, Loc});
1774 void Sema::checkOpenMPDeviceExpr(
const Expr *E) {
1775 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1776 "OpenMP device compilation mode is expected.");
1784 targetDiag(E->
getExprLoc(), diag::err_omp_unsupported_type)
1785 << static_cast<unsigned>(Context.
getTypeSize(Ty)) << Ty
1791 if (LO.OpenMP <= 45) {
1793 return OMPC_DEFAULTMAP_scalar;
1794 return OMPC_DEFAULTMAP_aggregate;
1797 return OMPC_DEFAULTMAP_pointer;
1799 return OMPC_DEFAULTMAP_scalar;
1800 return OMPC_DEFAULTMAP_aggregate;
1804 unsigned OpenMPCaptureLevel)
const {
1805 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1808 bool IsByRef =
true;
1814 bool IsVariableUsedInMapClause =
false;
1870 if (Ty->isReferenceType())
1876 bool IsVariableAssociatedWithSection =
false;
1878 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1880 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1887 if (WhereFoundClauseKind != OMPC_map)
1890 auto EI = MapExprComponents.rbegin();
1891 auto EE = MapExprComponents.rend();
1893 assert(EI != EE &&
"Invalid map expression!");
1895 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1896 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1902 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1903 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1904 isa<MemberExpr>(EI->getAssociatedExpression())) {
1905 IsVariableAssociatedWithSection =
true;
1914 if (IsVariableUsedInMapClause) {
1917 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1923 (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1924 !Ty->isAnyPointerType()) ||
1925 !Ty->isScalarType() ||
1926 DSAStack->isDefaultmapCapturedByRef(
1933 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1935 ((IsVariableUsedInMapClause &&
1936 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1944 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
1945 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1962 unsigned Sema::getOpenMPNestingLevel()
const {
1963 assert(getLangOpts().OpenMP);
1964 return DSAStack->getNestingLevel();
1969 !
DSAStack->isClauseParsingMode()) ||
1973 return isOpenMPTargetExecutionDirective(K);
1980 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
1983 auto *VD = dyn_cast<
VarDecl>(D);
1985 if (VD && VD->isConstexpr())
1992 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1998 if (VD && !VD->hasLocalStorage() &&
1999 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2000 if (isInOpenMPDeclareTargetContext()) {
2003 if (LangOpts.OpenMP <= 45 &&
2004 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2005 checkDeclIsAllowedInOpenMPTarget(
nullptr, VD);
2007 }
else if (isInOpenMPTargetExecutionDirective()) {
2011 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2017 if (CheckScopeInfo) {
2018 bool OpenMPFound =
false;
2019 for (
unsigned I = StopAt + 1; I > 0; --I) {
2021 if(!isa<CapturingScopeInfo>(FSI))
2023 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2033 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2034 (!
DSAStack->isClauseParsingMode() ||
2035 DSAStack->getParentDirective() != OMPD_unknown)) {
2036 auto &&Info =
DSAStack->isLoopControlVariable(D);
2038 (VD && VD->hasLocalStorage() &&
2039 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2040 (VD &&
DSAStack->isForceVarCapturing()))
2041 return VD ? VD : Info.second;
2042 DSAStackTy::DSAVarData DVarPrivate =
2045 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2055 (VD &&
DSAStack->getDefaultDSA() == DSA_none))
2056 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2061 void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2062 unsigned Level)
const {
2065 FunctionScopesIndex -= Regions.size();
2069 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2075 assert(LangOpts.OpenMP &&
"OpenMP must be enabled.");
2077 DSAStack->resetPossibleLoopCounter();
2083 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2085 if (
DSAStack->getAssociatedLoops() > 0 &&
2087 DSAStack->resetPossibleLoopCounter(D);
2092 DSAStack->isLoopControlVariable(D).first) &&
2098 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2099 if (
DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2107 (
DSAStack->isClauseParsingMode() &&
2108 DSAStack->getClauseParsingMode() == OMPC_private) ||
2114 DSAStack->isTaskgroupReductionRef(D, Level));
2119 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2122 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I >
Level; --I) {
2123 const unsigned NewLevel = I - 1;
2126 if (isOpenMPPrivate(K)) {
2134 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2144 if (
DSAStack->mustBeFirstprivateAtLevel(
2146 OMPC = OMPC_firstprivate;
2151 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2155 unsigned Level)
const {
2156 assert(LangOpts.OpenMP &&
"OpenMP is not allowed");
2159 const auto *VD = dyn_cast<
VarDecl>(D);
2165 void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2167 void Sema::finalizeOpenMPDelayedAnalysis() {
2168 assert(LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2170 for (
const auto &CallerCallees : DeviceCallGraph) {
2172 OMPDeclareTargetDeclAttr::getDeviceType(
2173 CallerCallees.getFirst()->getMostRecentDecl());
2175 if (LangOpts.OpenMPIsDevice && DevTy &&
2176 *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2179 if (!LangOpts.OpenMPIsDevice && DevTy &&
2180 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2183 &Callee : CallerCallees.getSecond()) {
2186 OMPDeclareTargetDeclAttr::getDeviceType(FD);
2187 if (LangOpts.OpenMPIsDevice && DevTy &&
2188 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2192 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2194 Diag(FD->
getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2195 diag::note_omp_marked_device_type_here)
2199 if (!LangOpts.OpenMPIsDevice && DevTy &&
2200 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2204 Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2205 << NoHostDevTy << 1;
2206 Diag(FD->
getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2207 diag::note_omp_marked_device_type_here)
2218 DSAStack->push(DKind, DirName, CurScope, Loc);
2219 PushExpressionEvaluationContext(
2220 ExpressionEvaluationContext::PotentiallyEvaluated);
2233 static std::pair<ValueDecl *, bool>
2235 SourceRange &ERange,
bool AllowArraySection =
false);
2245 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2247 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2249 for (
Expr *DE : Clause->varlists()) {
2250 if (DE->isValueDependent() || DE->isTypeDependent()) {
2251 PrivateCopies.push_back(
nullptr);
2254 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2255 auto *VD = cast<VarDecl>(DRE->getDecl());
2257 const DSAStackTy::DSAVarData DVar =
2259 if (DVar.CKind == OMPC_lastprivate) {
2266 *
this, DE->getExprLoc(), Type.getUnqualifiedType(),
2267 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() :
nullptr, DRE);
2268 ActOnUninitializedDecl(VDPrivate);
2270 PrivateCopies.push_back(
nullptr);
2274 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2278 PrivateCopies.push_back(
nullptr);
2281 Clause->setPrivateCopies(PrivateCopies);
2285 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2287 for (
Expr *RefExpr : Clause->varlists()) {
2288 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2291 Expr *SimpleRefExpr = RefExpr;
2295 PrivateRefs.push_back(RefExpr);
2300 const DSAStackTy::DSAVarData DVar =
2302 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2305 Clause->setPrivateRefs(PrivateRefs);
2310 if (!CurContext->isDependentContext())
2315 DiscardCleanupsInEvaluationContext();
2316 PopExpressionEvaluationContext();
2320 Expr *NumIterations,
Sema &SemaRef,
2321 Scope *S, DSAStackTy *Stack);
2330 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2331 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2333 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2334 return VD->hasGlobalStorage() &&
2341 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2342 return std::make_unique<VarDeclFilterCCC>(*this);
2352 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
2353 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
2355 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
2356 isa<FunctionDecl>(ND))) {
2363 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
2364 return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2375 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
2382 VarDeclFilterCCC CCC(*
this);
2384 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr, CCC,
2385 CTK_ErrorRecovery)) {
2386 diagnoseTypo(Corrected,
2387 PDiag(Lookup.
empty()
2388 ? diag::err_undeclared_var_use_suggest
2389 : diag::err_omp_expected_var_arg_suggest)
2391 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
2394 : diag::err_omp_expected_var_arg)
2408 Diag(Id.
getLoc(), diag::err_omp_global_var_arg)
2413 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2424 !getCurLexicalContext()->isTranslationUnit()) {
2426 << getOpenMPDirectiveName(Kind) << VD;
2430 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2441 << getOpenMPDirectiveName(Kind) << VD;
2445 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2454 (!getCurLexicalContext()->isFileContext() ||
2455 !getCurLexicalContext()->Encloses(CanonicalVD->
getDeclContext()))) {
2457 << getOpenMPDirectiveName(Kind) << VD;
2461 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2469 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2471 << getOpenMPDirectiveName(Kind) << VD;
2475 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2483 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
2486 << getOpenMPDirectiveName(Kind) << VD;
2501 CurContext->addDecl(D);
2508 class LocalVarRefChecker final
2514 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2515 if (VD->hasLocalStorage()) {
2517 diag::err_omp_local_var_in_threadprivate_init)
2519 SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2520 << VD << VD->getSourceRange();
2526 bool VisitStmt(
const Stmt *S) {
2528 if (Child && Visit(Child))
2533 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
2540 for (
Expr *RefExpr : VarList) {
2541 auto *DE = cast<DeclRefExpr>(RefExpr);
2542 auto *VD = cast<VarDecl>(DE->getDecl());
2546 VD->setReferenced();
2547 VD->markUsed(Context);
2558 if (RequireCompleteType(ILoc, VD->getType(),
2559 diag::err_omp_threadprivate_incomplete_type)) {
2565 if (VD->getType()->isReferenceType()) {
2566 Diag(ILoc, diag::err_omp_ref_type_arg)
2567 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2570 Diag(VD->getLocation(),
2571 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2579 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2580 getLangOpts().OpenMPUseTLS &&
2581 getASTContext().getTargetInfo().isTLSSupported())) ||
2582 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2583 !VD->isLocalVarDecl())) {
2584 Diag(ILoc, diag::err_omp_var_thread_local)
2588 Diag(VD->getLocation(),
2589 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2596 if (
const Expr *Init = VD->getAnyInitializer()) {
2597 LocalVarRefChecker Checker(*
this);
2598 if (Checker.Visit(Init))
2602 Vars.push_back(RefExpr);
2604 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2607 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2610 if (!Vars.empty()) {
2618 static OMPAllocateDeclAttr::AllocatorTypeTy
2621 return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2625 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2626 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2628 for (
int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2629 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2630 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
2631 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2632 llvm::FoldingSetNodeID AEId, DAEId;
2635 if (AEId == DAEId) {
2636 AllocatorKindRes = AllocatorKind;
2640 return AllocatorKindRes;
2645 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
2646 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
2648 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
2649 Expr *PrevAllocator = A->getAllocator();
2650 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2652 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2653 if (AllocatorsMatch &&
2654 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2655 Allocator && PrevAllocator) {
2658 llvm::FoldingSetNodeID AEId, PAEId;
2661 AllocatorsMatch = AEId == PAEId;
2663 if (!AllocatorsMatch) {
2665 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2669 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2671 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
2679 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2681 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2682 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2683 << (Allocator ? 1 : 0) << AllocatorStream.str()
2684 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2686 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2687 << PrevAllocatorRange;
2695 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2697 if (VD->
hasAttr<OMPAllocateDeclAttr>())
2704 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
2708 ML->DeclarationMarkedOpenMPAllocate(VD, A);
2714 assert(Clauses.size() <= 1 &&
"Expected at most one clause.");
2715 Expr *Allocator =
nullptr;
2716 if (Clauses.empty()) {
2721 if (LangOpts.OpenMPIsDevice &&
2723 targetDiag(Loc, diag::err_expected_allocator_clause);
2725 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2727 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2730 for (
Expr *RefExpr : VarList) {
2731 auto *DE = cast<DeclRefExpr>(RefExpr);
2732 auto *VD = cast<VarDecl>(DE->getDecl());
2736 VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2737 (VD->getStorageClass() ==
SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2738 !VD->isLocalVarDecl()))
2744 AllocatorKind, Allocator))
2751 if (Allocator && VD->hasGlobalStorage()) {
2752 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2753 Diag(Allocator->getExprLoc(),
2754 diag::err_omp_expected_predefined_allocator)
2755 << Allocator->getSourceRange();
2756 bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2758 Diag(VD->getLocation(),
2759 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2765 Vars.push_back(RefExpr);
2767 DE->getSourceRange());
2772 Owner = getCurLexicalContext();
2783 if (!CurContext->isFileContext()) {
2784 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
2786 D = CheckOMPRequiresDecl(Loc, ClauseList);
2788 CurContext->addDecl(D);
2801 DSAStack->getEncounteredTargetLocs();
2802 if (!TargetLocations.empty()) {
2803 for (
const OMPClause *CNew : ClauseList) {
2805 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2806 isa<OMPUnifiedAddressClause>(CNew) ||
2807 isa<OMPReverseOffloadClause>(CNew) ||
2808 isa<OMPDynamicAllocatorsClause>(CNew)) {
2809 Diag(Loc, diag::err_omp_target_before_requires)
2812 Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2818 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
2826 const DSAStackTy::DSAVarData &DVar,
2827 bool IsLoopIterVar =
false) {
2829 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2834 PDSA_StaticMemberShared,
2835 PDSA_StaticLocalVarShared,
2836 PDSA_LoopIterVarPrivate,
2837 PDSA_LoopIterVarLinear,
2838 PDSA_LoopIterVarLastprivate,
2839 PDSA_ConstVarShared,
2840 PDSA_GlobalVarShared,
2841 PDSA_TaskVarFirstprivate,
2842 PDSA_LocalVarPrivate,
2844 } Reason = PDSA_Implicit;
2845 bool ReportHint =
false;
2847 auto *VD = dyn_cast<
VarDecl>(D);
2848 if (IsLoopIterVar) {
2849 if (DVar.CKind == OMPC_private)
2850 Reason = PDSA_LoopIterVarPrivate;
2851 else if (DVar.CKind == OMPC_lastprivate)
2852 Reason = PDSA_LoopIterVarLastprivate;
2854 Reason = PDSA_LoopIterVarLinear;
2856 DVar.CKind == OMPC_firstprivate) {
2857 Reason = PDSA_TaskVarFirstprivate;
2858 ReportLoc = DVar.ImplicitDSALoc;
2859 }
else if (VD && VD->isStaticLocal())
2860 Reason = PDSA_StaticLocalVarShared;
2861 else if (VD && VD->isStaticDataMember())
2862 Reason = PDSA_StaticMemberShared;
2863 else if (VD && VD->isFileVarDecl())
2864 Reason = PDSA_GlobalVarShared;
2866 Reason = PDSA_ConstVarShared;
2867 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2869 Reason = PDSA_LocalVarPrivate;
2871 if (Reason != PDSA_Implicit) {
2872 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2873 << Reason << ReportHint
2874 << getOpenMPDirectiveName(Stack->getCurrentDirective());
2875 }
else if (DVar.ImplicitDSALoc.isValid()) {
2876 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2883 bool IsAggregateOrDeclareTarget) {
2886 case OMPC_DEFAULTMAP_MODIFIER_alloc:
2887 Kind = OMPC_MAP_alloc;
2889 case OMPC_DEFAULTMAP_MODIFIER_to:
2892 case OMPC_DEFAULTMAP_MODIFIER_from:
2893 Kind = OMPC_MAP_from;
2895 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
2896 Kind = OMPC_MAP_tofrom;
2898 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
2900 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
2901 case OMPC_DEFAULTMAP_MODIFIER_none:
2902 case OMPC_DEFAULTMAP_MODIFIER_default:
2907 if (IsAggregateOrDeclareTarget) {
2908 Kind = OMPC_MAP_tofrom;
2911 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
2918 class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
2921 bool ErrorFound =
false;
2922 bool TryCaptureCXXThisMembers =
false;
2927 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2936 if (TryCaptureCXXThisMembers ||
2940 return C.capturesThis();
2942 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
2943 TryCaptureCXXThisMembers =
true;
2945 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
2955 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2958 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2959 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2960 Visit(CED->getInit());
2963 }
else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2967 VD = VD->getCanonicalDecl();
2972 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
2974 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2979 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2982 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2991 if (DVar.CKind ==
OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2992 isImplicitOrExplicitTaskingRegion(DKind) &&
2993 VarsWithInheritedDSA.count(VD) == 0) {
2994 VarsWithInheritedDSA[VD] = E;
3009 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3010 OMPC_DEFAULTMAP_MODIFIER_none;
3012 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3016 if (!Stack->checkMappableExprComponentListsForDecl(
3021 auto MI = MapExprComponents.rbegin();
3022 auto ME = MapExprComponents.rend();
3023 return MI != ME && MI->getAssociatedDeclaration() == VD;
3025 VarsWithInheritedDSA[VD] = E;
3032 !Stack->isLoopControlVariable(VD).first) {
3033 if (!Stack->checkMappableExprComponentListsForDecl(
3040 return StackComponents.size() == 1 ||
3042 std::next(StackComponents.rbegin()),
3043 StackComponents.rend(),
3044 [](const OMPClauseMappableExprCommon::
3045 MappableComponent &MC) {
3046 return MC.getAssociatedDeclaration() ==
3048 (isa<OMPArraySectionExpr>(
3049 MC.getAssociatedExpression()) ||
3050 isa<ArraySubscriptExpr>(
3051 MC.getAssociatedExpression()));
3054 bool IsFirstprivate =
false;
3056 if (
const auto *RD =
3057 VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3058 IsFirstprivate = RD->isLambda();
3060 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3061 if (IsFirstprivate) {
3062 ImplicitFirstprivate.emplace_back(E);
3065 Stack->getDefaultmapModifier(ClauseKind);
3067 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3068 ImplicitMap[
Kind].emplace_back(E);
3078 DVar = Stack->hasInnermostDSA(
3087 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3093 DVar = Stack->getImplicitDSA(VD,
false);
3095 !Stack->isLoopControlVariable(VD).first) {
3096 ImplicitFirstprivate.push_back(E);
3103 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3104 Stack->addToParentTargetRegionLinkGlobals(E);
3118 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3121 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3125 !Stack->isLoopControlVariable(FD).first &&
3126 !Stack->checkMappableExprComponentListsForDecl(
3131 return isa<CXXThisExpr>(
3133 StackComponents.back().getAssociatedExpression())
3140 if (FD->isBitField())
3145 if (Stack->isClassPreviouslyMapped(TE->getType()))
3149 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3152 ImplicitMap[
Kind].emplace_back(E);
3161 DVar = Stack->hasInnermostDSA(
3170 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3176 DVar = Stack->getImplicitDSA(FD,
false);
3178 !Stack->isLoopControlVariable(FD).first) {
3184 ImplicitFirstprivate.push_back(E);
3193 const auto *VD = cast<ValueDecl>(
3194 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3195 if (!Stack->checkMappableExprComponentListsForDecl(
3201 auto CCI = CurComponents.rbegin();
3202 auto CCE = CurComponents.rend();
3203 for (const auto &SC : llvm::reverse(StackComponents)) {
3205 if (CCI->getAssociatedExpression()->getStmtClass() !=
3206 SC.getAssociatedExpression()->getStmtClass())
3207 if (!(isa<OMPArraySectionExpr>(
3208 SC.getAssociatedExpression()) &&
3209 isa<ArraySubscriptExpr>(
3210 CCI->getAssociatedExpression())))
3213 const Decl *CCD = CCI->getAssociatedDeclaration();
3214 const Decl *SCD = SC.getAssociatedDeclaration();
3215 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3216 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3219 std::advance(CCI, 1);
3227 }
else if (!TryCaptureCXXThisMembers) {
3237 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
3239 for (
Stmt *CC :
C->children()) {
3246 VisitSubCaptures(S);
3248 void VisitStmt(
Stmt *S) {
3260 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3262 VarDecl *VD = Cap.getCapturedVar();
3266 Stack->checkMappableExprComponentListsForDecl(
3273 Cap.getLocation(),
true);
3277 bool isErrorFound()
const {
return ErrorFound; }
3278 ArrayRef<Expr *> getImplicitFirstprivate()
const {
3279 return ImplicitFirstprivate;
3282 return ImplicitMap[
Kind];
3285 return VarsWithInheritedDSA;
3289 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
3302 case OMPD_parallel_for:
3303 case OMPD_parallel_for_simd:
3304 case OMPD_parallel_sections:
3305 case OMPD_parallel_master:
3307 case OMPD_teams_distribute:
3308 case OMPD_teams_distribute_simd: {
3313 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3314 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3315 std::make_pair(StringRef(),
QualType())
3321 case OMPD_target_teams:
3322 case OMPD_target_parallel:
3323 case OMPD_target_parallel_for:
3324 case OMPD_target_parallel_for_simd:
3325 case OMPD_target_teams_distribute:
3326 case OMPD_target_teams_distribute_simd: {
3336 std::make_pair(
".global_tid.", KmpInt32Ty),
3337 std::make_pair(
".part_id.", KmpInt32PtrTy),
3338 std::make_pair(
".privates.", VoidPtrTy),
3343 std::make_pair(StringRef(),
QualType())
3349 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3350 AlwaysInlineAttr::CreateImplicit(
3352 AlwaysInlineAttr::Keyword_forceinline));
3354 std::make_pair(StringRef(),
QualType())
3360 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3361 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3362 std::make_pair(StringRef(),
QualType())
3367 ParamsTeamsOrParallel, 2);
3371 case OMPD_target_simd: {
3381 std::make_pair(
".global_tid.", KmpInt32Ty),
3382 std::make_pair(
".part_id.", KmpInt32PtrTy),
3383 std::make_pair(
".privates.", VoidPtrTy),
3388 std::make_pair(StringRef(),
QualType())
3394 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3395 AlwaysInlineAttr::CreateImplicit(
3397 AlwaysInlineAttr::Keyword_forceinline));
3399 std::make_pair(StringRef(),
QualType()),
3411 case OMPD_taskgroup:
3412 case OMPD_distribute:
3413 case OMPD_distribute_simd:
3416 case OMPD_target_data: {
3418 std::make_pair(StringRef(),
QualType())
3434 std::make_pair(
".global_tid.", KmpInt32Ty),
3435 std::make_pair(
".part_id.", KmpInt32PtrTy),
3436 std::make_pair(
".privates.", VoidPtrTy),
3441 std::make_pair(StringRef(),
QualType())
3447 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3448 AlwaysInlineAttr::CreateImplicit(
3450 AlwaysInlineAttr::Keyword_forceinline));
3454 case OMPD_taskloop_simd:
3455 case OMPD_master_taskloop:
3456 case OMPD_master_taskloop_simd: {
3474 std::make_pair(
".global_tid.", KmpInt32Ty),
3475 std::make_pair(
".part_id.", KmpInt32PtrTy),
3476 std::make_pair(
".privates.", VoidPtrTy),
3481 std::make_pair(
".lb.", KmpUInt64Ty),
3482 std::make_pair(
".ub.", KmpUInt64Ty),
3483 std::make_pair(
".st.", KmpInt64Ty),
3484 std::make_pair(
".liter.", KmpInt32Ty),
3485 std::make_pair(
".reductions.", VoidPtrTy),
3486 std::make_pair(StringRef(),
QualType())
3492 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3493 AlwaysInlineAttr::CreateImplicit(
3495 AlwaysInlineAttr::Keyword_forceinline));
3498 case OMPD_parallel_master_taskloop:
3499 case OMPD_parallel_master_taskloop_simd: {
3513 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3514 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3515 std::make_pair(StringRef(),
QualType())
3525 std::make_pair(
".global_tid.", KmpInt32Ty),
3526 std::make_pair(
".part_id.", KmpInt32PtrTy),
3527 std::make_pair(
".privates.", VoidPtrTy),
3532 std::make_pair(
".lb.", KmpUInt64Ty),
3533 std::make_pair(
".ub.", KmpUInt64Ty),
3534 std::make_pair(
".st.", KmpInt64Ty),
3535 std::make_pair(
".liter.", KmpInt32Ty),
3536 std::make_pair(
".reductions.", VoidPtrTy),
3537 std::make_pair(StringRef(),
QualType())
3543 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3544 AlwaysInlineAttr::CreateImplicit(
3546 AlwaysInlineAttr::Keyword_forceinline));
3549 case OMPD_distribute_parallel_for_simd:
3550 case OMPD_distribute_parallel_for: {
3555 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3556 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3559 std::make_pair(StringRef(),
QualType())
3565 case OMPD_target_teams_distribute_parallel_for:
3566 case OMPD_target_teams_distribute_parallel_for_simd: {
3577 std::make_pair(
".global_tid.", KmpInt32Ty),
3578 std::make_pair(
".part_id.", KmpInt32PtrTy),
3579 std::make_pair(
".privates.", VoidPtrTy),
3584 std::make_pair(StringRef(),
QualType())
3590 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3591 AlwaysInlineAttr::CreateImplicit(
3593 AlwaysInlineAttr::Keyword_forceinline));
3595 std::make_pair(StringRef(),
QualType())
3602 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3603 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3604 std::make_pair(StringRef(),
QualType())
3611 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3612 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3615 std::make_pair(StringRef(),
QualType())
3624 case OMPD_teams_distribute_parallel_for:
3625 case OMPD_teams_distribute_parallel_for_simd: {
3631 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3632 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3633 std::make_pair(StringRef(),
QualType())
3640 std::make_pair(
".global_tid.", KmpInt32PtrTy),
3641 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
3644 std::make_pair(StringRef(),
QualType())
3652 case OMPD_target_update:
3653 case OMPD_target_enter_data:
3654 case OMPD_target_exit_data: {
3664 std::make_pair(
".global_tid.", KmpInt32Ty),
3665 std::make_pair(
".part_id.", KmpInt32PtrTy),
3666 std::make_pair(
".privates.", VoidPtrTy),
3671 std::make_pair(StringRef(),
QualType())
3677 getCurCapturedRegion()->TheCapturedDecl->addAttr(
3678 AlwaysInlineAttr::CreateImplicit(
3680 AlwaysInlineAttr::Keyword_forceinline));
3683 case OMPD_threadprivate:
3685 case OMPD_taskyield:
3688 case OMPD_cancellation_point:
3691 case OMPD_declare_reduction:
3692 case OMPD_declare_mapper:
3693 case OMPD_declare_simd:
3694 case OMPD_declare_target:
3695 case OMPD_end_declare_target:
3697 case OMPD_declare_variant:
3698 llvm_unreachable(
"OpenMP Directive is not allowed");
3700 llvm_unreachable(
"Unknown OpenMP directive");
3704 int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
3705 return getOpenMPCaptureLevels(
DSAStack->getDirective(Level));
3711 return CaptureRegions.size();
3715 Expr *CaptureExpr,
bool WithInit,
3716 bool AsExpression) {
3717 assert(CaptureExpr);
3737 CED->
addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3747 CD = cast<OMPCapturedExprDecl>(VD);
3769 if (!Res.isUsable())
3784 class CaptureRegionUnwinderRAII {
3791 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
3793 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3794 ~CaptureRegionUnwinderRAII() {
3797 while (--ThisCaptureLevel >= 0)
3807 if (!CurContext->isDependentContext() &&
3810 DSAStack->getCurrentDirective()))) {
3815 bool SavedForceCaptureByReferenceInTargetExecutable =
3816 DSAStack->isForceCaptureByReferenceInTargetExecutable();
3817 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3819 if (RD->isLambda()) {
3820 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3822 RD->getCaptureFields(Captures, ThisCapture);
3825 VarDecl *VD = LC.getCapturedVar();
3829 MarkVariableReferenced(LC.getLocation(), VD);
3830 }
else if (LC.getCaptureKind() ==
LCK_This) {
3831 QualType ThisTy = getCurrentThisType();
3834 CheckCXXThisCapture(LC.getLocation());
3838 DSAStack->setForceCaptureByReferenceInTargetExecutable(
3839 SavedForceCaptureByReferenceInTargetExecutable);
3846 bool ErrorFound =
false;
3847 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3848 *
this, ErrorFound,
DSAStack->getCurrentDirective());
3866 auto *IRC = cast<OMPInReductionClause>(Clause);
3867 for (
Expr *E : IRC->taskgroup_descriptors())
3869 MarkDeclarationsReferencedInExpr(E);
3873 (getLangOpts().OpenMPUseTLS &&
3874 getASTContext().getTargetInfo().isTLSSupported() &&
3879 if (
auto *E = cast_or_null<Expr>(VarRef)) {
3880 MarkDeclarationsReferencedInExpr(E);
3883 DSAStack->setForceVarCapturing(
false);
3884 }
else if (CaptureRegions.size() > 1 ||
3885 CaptureRegions.back() != OMPD_unknown) {
3889 if (
Expr *E =
C->getPostUpdateExpr())
3890 MarkDeclarationsReferencedInExpr(E);
3894 SC = cast<OMPScheduleClause>(Clause);
3896 OC = cast<OMPOrderedClause>(Clause);
3898 LCs.push_back(cast<OMPLinearClause>(Clause));
3906 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3911 diag::err_omp_schedule_nonmonotonic_ordered)
3912 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3915 if (!LCs.empty() && OC && OC->getNumForLoops()) {
3917 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
3918 <<
SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3924 OC->getNumForLoops()) {
3925 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3926 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
3933 unsigned CompletedRegions = 0;
3938 if (ThisCaptureRegion != OMPD_unknown) {
3946 if (CaptureRegion == ThisCaptureRegion ||
3947 CaptureRegion == OMPD_unknown) {
3948 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
3949 for (
Decl *D : DS->decls())
3950 MarkVariableReferenced(D->
getLocation(), cast<VarDecl>(D));
3955 if (++CompletedRegions == CaptureRegions.size())
3957 SR = ActOnCapturedRegionEnd(SR.
get());
3966 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3969 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3970 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3973 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3974 << getOpenMPDirectiveName(CancelRegion);
3983 if (Stack->getCurScope()) {
3986 bool NestingProhibited =
false;
3987 bool CloseNesting =
true;
3988 bool OrphanSeen =
false;
3991 ShouldBeInParallelRegion,
3992 ShouldBeInOrderedRegion,
3993 ShouldBeInTargetRegion,
3994 ShouldBeInTeamsRegion
3995 } Recommend = NoRecommend;
3997 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
3998 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
3999 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) {
4012 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
4013 ? diag::err_omp_prohibited_region_simd
4014 : diag::warn_omp_nesting_simd)
4015 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
4016 return CurrentRegion != OMPD_simd;
4018 if (ParentRegion == OMPD_atomic) {
4021 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4024 if (CurrentRegion == OMPD_section) {
4029 if (ParentRegion != OMPD_sections &&
4030 ParentRegion != OMPD_parallel_sections) {
4031 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4032 << (ParentRegion != OMPD_unknown)
4033 << getOpenMPDirectiveName(ParentRegion);
4041 if (ParentRegion == OMPD_unknown &&
4043 CurrentRegion != OMPD_cancellation_point &&
4044 CurrentRegion != OMPD_cancel)
4046 if (CurrentRegion == OMPD_cancellation_point ||
4047 CurrentRegion == OMPD_cancel) {
4060 !((CancelRegion == OMPD_parallel &&
4061 (ParentRegion == OMPD_parallel ||
4062 ParentRegion == OMPD_target_parallel)) ||
4063 (CancelRegion == OMPD_for &&
4064 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4065 ParentRegion == OMPD_target_parallel_for ||
4066 ParentRegion == OMPD_distribute_parallel_for ||
4067 ParentRegion == OMPD_teams_distribute_parallel_for ||
4068 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4069 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
4070 (CancelRegion == OMPD_sections &&
4071 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4072 ParentRegion == OMPD_parallel_sections)));
4073 OrphanSeen = ParentRegion == OMPD_unknown;
4074 }
else if (CurrentRegion == OMPD_master) {
4080 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
4086 bool DeadLock = Stack->hasDirective(
4090 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
4091 PreviousCriticalLoc = Loc;
4098 SemaRef.
Diag(StartLoc,
4099 diag::err_omp_prohibited_region_critical_same_name)
4101 if (PreviousCriticalLoc.
isValid())
4102 SemaRef.
Diag(PreviousCriticalLoc,
4103 diag::note_omp_previous_critical_region);
4106 }
else if (CurrentRegion == OMPD_barrier) {
4112 ParentRegion == OMPD_master ||
4113 ParentRegion == OMPD_parallel_master ||
4114 ParentRegion == OMPD_critical ||
4115 ParentRegion == OMPD_ordered;
4124 ParentRegion == OMPD_master ||
4125 ParentRegion == OMPD_parallel_master ||
4126 ParentRegion == OMPD_critical ||
4127 ParentRegion == OMPD_ordered;
4128 Recommend = ShouldBeInParallelRegion;
4129 }
else if (CurrentRegion == OMPD_ordered) {
4138 NestingProhibited = ParentRegion == OMPD_critical ||
4141 Stack->isParentOrderedRegion());
4142 Recommend = ShouldBeInOrderedRegion;
4148 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4149 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4150 ParentRegion != OMPD_target);
4151 OrphanSeen = ParentRegion == OMPD_unknown;
4152 Recommend = ShouldBeInTargetRegion;
4154 if (!NestingProhibited &&
4157 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4164 Recommend = ShouldBeInParallelRegion;
4166 if (!NestingProhibited &&
4172 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4173 Recommend = ShouldBeInTeamsRegion;
4175 if (!NestingProhibited &&
4182 NestingProhibited = Stack->hasDirective(
4186 OffendingRegion = K;
4192 CloseNesting =
false;
4194 if (NestingProhibited) {
4196 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4197 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4199 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
4200 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4201 << Recommend << getOpenMPDirectiveName(CurrentRegion);
4214 ArrayRef<OMPClause *> Clauses,
4215 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4216 bool ErrorFound =
false;
4217 unsigned NamedModifiersNumber = 0;
4218 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4219 FoundNameModifiers.resize(
unsigned(OMPD_unknown) + 1);
4222 if (
const auto *IC = dyn_cast_or_null<OMPIfClause>(
C)) {
4226 if (FoundNameModifiers[CurNM]) {
4227 S.
Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
4229 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4231 }
else if (CurNM != OMPD_unknown) {
4232 NameModifierLoc.push_back(IC->getNameModifierLoc());
4233 ++NamedModifiersNumber;
4235 FoundNameModifiers[CurNM] = IC;
4236 if (CurNM == OMPD_unknown)
4242 bool MatchFound =
false;
4243 for (
auto NM : AllowedNameModifiers) {
4250 S.
Diag(IC->getNameModifierLoc(),
4251 diag::err_omp_wrong_if_directive_name_modifier)
4252 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4259 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4260 if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4261 S.
Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4262 diag::err_omp_no_more_if_clause);
4265 std::string Sep(
", ");
4266 unsigned AllowedCnt = 0;
4267 unsigned TotalAllowedNum =
4268 AllowedNameModifiers.size() - NamedModifiersNumber;
4269 for (
unsigned Cnt = 0,
End = AllowedNameModifiers.size(); Cnt <
End;
4272 if (!FoundNameModifiers[NM]) {
4274 Values += getOpenMPDirectiveName(NM);
4276 if (AllowedCnt + 2 == TotalAllowedNum)
4278 else if (AllowedCnt + 1 != TotalAllowedNum)
4283 S.
Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4284 diag::err_omp_unnamed_if_clause)
4285 << (TotalAllowedNum > 1) << Values;
4288 S.
Diag(Loc, diag::note_omp_previous_named_if_clause);
4298 bool AllowArraySection) {
4301 return std::make_pair(
nullptr,
true);
4313 } IsArrayExpr = NoArrayExpr;
4314 if (AllowArraySection) {
4315 if (
auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4316 Expr *
Base = ASE->getBase()->IgnoreParenImpCasts();
4317 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4320 IsArrayExpr = ArraySubscript;
4321 }
else if (
auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4322 Expr *
Base = OASE->getBase()->IgnoreParenImpCasts();
4323 while (
auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4325 while (
auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4328 IsArrayExpr = OMPArraySection;
4334 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4335 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4336 if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4338 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4339 !isa<FieldDecl>(ME->getMemberDecl()))) {
4340 if (IsArrayExpr != NoArrayExpr) {
4341 S.
Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4346 ? diag::err_omp_expected_var_name_member_expr_or_array_item
4347 : diag::err_omp_expected_var_name_member_expr)
4350 return std::make_pair(
nullptr,
false);
4352 return std::make_pair(
4357 ArrayRef<OMPClause *> Clauses) {
4359 "Expected non-dependent context.");
4360 auto AllocateRange =
4364 auto PrivateRange = llvm::make_filter_range(Clauses, [](
const OMPClause *
C) {
4368 MutableArrayRef<Expr *>::iterator I, It, Et;
4369 if (
Cl->getClauseKind() == OMPC_private) {
4370 auto *PC = cast<OMPPrivateClause>(
Cl);
4371 I = PC->private_copies().begin();
4372 It = PC->varlist_begin();
4373 Et = PC->varlist_end();
4374 }
else if (
Cl->getClauseKind() == OMPC_firstprivate) {
4375 auto *PC = cast<OMPFirstprivateClause>(
Cl);
4376 I = PC->private_copies().begin();
4377 It = PC->varlist_begin();
4378 Et = PC->varlist_end();
4379 }
else if (
Cl->getClauseKind() == OMPC_lastprivate) {
4380 auto *PC = cast<OMPLastprivateClause>(
Cl);
4381 I = PC->private_copies().begin();
4382 It = PC->varlist_begin();
4383 Et = PC->varlist_end();
4384 }
else if (
Cl->getClauseKind() == OMPC_linear) {
4385 auto *PC = cast<OMPLinearClause>(
Cl);
4386 I = PC->privates().begin();
4387 It = PC->varlist_begin();
4388 Et = PC->varlist_end();
4389 }
else if (
Cl->getClauseKind() == OMPC_reduction) {
4390 auto *PC = cast<OMPReductionClause>(
Cl);
4391 I = PC->privates().begin();
4392 It = PC->varlist_begin();
4393 Et = PC->varlist_end();
4394 }
else if (
Cl->getClauseKind() == OMPC_task_reduction) {
4395 auto *PC = cast<OMPTaskReductionClause>(
Cl);
4396 I = PC->privates().begin();
4397 It = PC->varlist_begin();
4398 Et = PC->varlist_end();
4399 }
else if (
Cl->getClauseKind() == OMPC_in_reduction) {
4400 auto *PC = cast<OMPInReductionClause>(
Cl);
4401 I = PC->privates().begin();
4402 It = PC->varlist_begin();
4403 Et = PC->varlist_end();
4405 llvm_unreachable(
"Expected private clause.");
4407 for (
Expr *E : llvm::make_range(It, Et)) {
4414 Expr *SimpleRefExpr = E;
4417 DeclToCopy.try_emplace(Res.first,
4418 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4423 auto *AC = cast<OMPAllocateClause>(
C);
4424 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4430 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4433 S.
Diag(AC->getAllocator()->getExprLoc(),
4434 diag::warn_omp_allocate_thread_on_task_target_directive)
4435 << getOpenMPDirectiveName(Stack->getCurrentDirective());
4437 for (
Expr *E : AC->varlists()) {
4440 Expr *SimpleRefExpr = E;
4443 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD,
false);
4446 diag::err_omp_expected_private_copy_for_allocate);
4449 VarDecl *PrivateVD = DeclToCopy[VD];
4451 AllocatorKind, AC->getAllocator()))
4472 bool ErrorFound =
false;
4473 ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4474 if (AStmt && !CurContext->isDependentContext()) {
4475 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
4478 DSAAttrChecker DSAChecker(
DSAStack, *
this, cast<CapturedStmt>(AStmt));
4479 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4481 while (--ThisCaptureLevel >= 0)
4482 S = cast<CapturedStmt>(S)->getCapturedStmt();
4483 DSAChecker.Visit(S);
4487 auto *CS = cast<CapturedStmt>(AStmt);
4491 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4493 DSAChecker.visitSubCaptures(CS);
4495 if (DSAChecker.isErrorFound())
4498 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4501 DSAChecker.getImplicitFirstprivate().begin(),
4502 DSAChecker.getImplicitFirstprivate().end());
4504 for (
unsigned I = 0; I < OMPC_MAP_delete; ++I) {
4506 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
4507 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
4511 if (
auto *IRC = dyn_cast<OMPInReductionClause>(
C)) {
4512 for (
Expr *E : IRC->taskgroup_descriptors())
4514 ImplicitFirstprivates.emplace_back(E);
4517 if (!ImplicitFirstprivates.empty()) {
4518 if (
OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4521 ClausesWithImplicit.push_back(Implicit);
4522 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4523 ImplicitFirstprivates.size();
4528 int ClauseKindCnt = -1;
4531 if (ImplicitMap.empty())
4536 if (
OMPClause *Implicit = ActOnOpenMPMapClause(
4540 ClausesWithImplicit.emplace_back(Implicit);
4542 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
4552 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4554 AllowedNameModifiers.push_back(OMPD_parallel);
4557 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4558 VarsWithInheritedDSA);
4559 if (LangOpts.OpenMP >= 50)
4560 AllowedNameModifiers.push_back(OMPD_simd);
4563 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4564 VarsWithInheritedDSA);
4567 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4568 EndLoc, VarsWithInheritedDSA);
4569 if (LangOpts.OpenMP >= 50)
4570 AllowedNameModifiers.push_back(OMPD_simd);
4573 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4577 assert(ClausesWithImplicit.empty() &&
4578 "No clauses are allowed for 'omp section' directive");
4579 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4582 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4586 assert(ClausesWithImplicit.empty() &&
4587 "No clauses are allowed for 'omp master' directive");
4588 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4591 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4594 case OMPD_parallel_for:
4595 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4596 EndLoc, VarsWithInheritedDSA);
4597 AllowedNameModifiers.push_back(OMPD_parallel);
4599 case OMPD_parallel_for_simd:
4600 Res = ActOnOpenMPParallelForSimdDirective(
4601 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4602 AllowedNameModifiers.push_back(OMPD_parallel);
4603 if (LangOpts.OpenMP >= 50)
4604 AllowedNameModifiers.push_back(OMPD_simd);
4606 case OMPD_parallel_master:
4607 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
4609 AllowedNameModifiers.push_back(OMPD_parallel);
4611 case OMPD_parallel_sections:
4612 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4614 AllowedNameModifiers.push_back(OMPD_parallel);
4618 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4619 AllowedNameModifiers.push_back(OMPD_task);
4621 case OMPD_taskyield:
4622 assert(ClausesWithImplicit.empty() &&
4623 "No clauses are allowed for 'omp taskyield' directive");
4624 assert(AStmt ==
nullptr &&
4625 "No associated statement allowed for 'omp taskyield' directive");
4626 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4629 assert(ClausesWithImplicit.empty() &&
4630 "No clauses are allowed for 'omp barrier' directive");
4631 assert(AStmt ==
nullptr &&
4632 "No associated statement allowed for 'omp barrier' directive");
4633 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4636 assert(ClausesWithImplicit.empty() &&
4637 "No clauses are allowed for 'omp taskwait' directive");
4638 assert(AStmt ==
nullptr &&
4639 "No associated statement allowed for 'omp taskwait' directive");
4640 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4642 case OMPD_taskgroup:
4643 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4647 assert(AStmt ==
nullptr &&
4648 "No associated statement allowed for 'omp flush' directive");
4649 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4652 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4656 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4661 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4664 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4666 AllowedNameModifiers.push_back(OMPD_target);
4668 case OMPD_target_parallel:
4669 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4671 AllowedNameModifiers.push_back(OMPD_target);
4672 AllowedNameModifiers.push_back(OMPD_parallel);
4674 case OMPD_target_parallel_for:
4675 Res = ActOnOpenMPTargetParallelForDirective(
4676 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4677 AllowedNameModifiers.push_back(OMPD_target);
4678 AllowedNameModifiers.push_back(OMPD_parallel);
4680 case OMPD_cancellation_point:
4681 assert(ClausesWithImplicit.empty() &&
4682 "No clauses are allowed for 'omp cancellation point' directive");
4683 assert(AStmt ==
nullptr &&
"No associated statement allowed for 'omp " 4684 "cancellation point' directive");
4685 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4688 assert(AStmt ==
nullptr &&
4689 "No associated statement allowed for 'omp cancel' directive");
4690 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4692 AllowedNameModifiers.push_back(OMPD_cancel);
4694 case OMPD_target_data:
4695 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4697 AllowedNameModifiers.push_back(OMPD_target_data);
4699 case OMPD_target_enter_data:
4700 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4702 AllowedNameModifiers.push_back(OMPD_target_enter_data);
4704 case OMPD_target_exit_data:
4705 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4707 AllowedNameModifiers.push_back(OMPD_target_exit_data);
4710 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4711 EndLoc, VarsWithInheritedDSA);
4712 AllowedNameModifiers.push_back(OMPD_taskloop);
4714 case OMPD_taskloop_simd:
4715 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4716 EndLoc, VarsWithInheritedDSA);
4717 AllowedNameModifiers.push_back(OMPD_taskloop);
4718 if (LangOpts.OpenMP >= 50)
4719 AllowedNameModifiers.push_back(OMPD_simd);
4721 case OMPD_master_taskloop:
4722 Res = ActOnOpenMPMasterTaskLoopDirective(
4723 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4724 AllowedNameModifiers.push_back(OMPD_taskloop);
4726 case OMPD_master_taskloop_simd:
4727 Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4728 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4729 AllowedNameModifiers.push_back(OMPD_taskloop);
4730 if (LangOpts.OpenMP >= 50)
4731 AllowedNameModifiers.push_back(OMPD_simd);
4733 case OMPD_parallel_master_taskloop:
4734 Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4735 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4736 AllowedNameModifiers.push_back(OMPD_taskloop);
4737 AllowedNameModifiers.push_back(OMPD_parallel);
4739 case OMPD_parallel_master_taskloop_simd:
4740 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
4741 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4742 AllowedNameModifiers.push_back(OMPD_taskloop);
4743 AllowedNameModifiers.push_back(OMPD_parallel);
4744 if (LangOpts.OpenMP >= 50)
4745 AllowedNameModifiers.push_back(OMPD_simd);
4747 case OMPD_distribute:
4748 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4749 EndLoc, VarsWithInheritedDSA);
4751 case OMPD_target_update:
4752 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4754 AllowedNameModifiers.push_back(OMPD_target_update);
4756 case OMPD_distribute_parallel_for:
4757 Res = ActOnOpenMPDistributeParallelForDirective(
4758 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4759 AllowedNameModifiers.push_back(OMPD_parallel);
4761 case OMPD_distribute_parallel_for_simd:
4762 Res = ActOnOpenMPDistributeParallelForSimdDirective(
4763 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4764 AllowedNameModifiers.push_back(OMPD_parallel);
4765 if (LangOpts.OpenMP >= 50)
4766 AllowedNameModifiers.push_back(OMPD_simd);
4768 case OMPD_distribute_simd:
4769 Res = ActOnOpenMPDistributeSimdDirective(
4770 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4771 if (LangOpts.OpenMP >= 50)
4772 AllowedNameModifiers.push_back(OMPD_simd);
4774 case OMPD_target_parallel_for_simd:
4775 Res = ActOnOpenMPTargetParallelForSimdDirective(
4776 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4777 AllowedNameModifiers.push_back(OMPD_target);
4778 AllowedNameModifiers.push_back(OMPD_parallel);
4779 if (LangOpts.OpenMP >= 50)
4780 AllowedNameModifiers.push_back(OMPD_simd);
4782 case OMPD_target_simd:
4783 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4784 EndLoc, VarsWithInheritedDSA);
4785 AllowedNameModifiers.push_back(OMPD_target);
4786 if (LangOpts.OpenMP >= 50)
4787 AllowedNameModifiers.push_back(OMPD_simd);
4789 case OMPD_teams_distribute:
4790 Res = ActOnOpenMPTeamsDistributeDirective(
4791 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4793 case OMPD_teams_distribute_simd:
4794 Res = ActOnOpenMPTeamsDistributeSimdDirective(
4795 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4796 if (LangOpts.OpenMP >= 50)
4797 AllowedNameModifiers.push_back(OMPD_simd);
4799 case OMPD_teams_distribute_parallel_for_simd:
4800 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4801 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4802 AllowedNameModifiers.push_back(OMPD_parallel);
4803 if (LangOpts.OpenMP >= 50)
4804 AllowedNameModifiers.push_back(OMPD_simd);
4806 case OMPD_teams_distribute_parallel_for:
4807 Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4808 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4809 AllowedNameModifiers.push_back(OMPD_parallel);
4811 case OMPD_target_teams:
4812 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4814 AllowedNameModifiers.push_back(OMPD_target);
4816 case OMPD_target_teams_distribute:
4817 Res = ActOnOpenMPTargetTeamsDistributeDirective(
4818 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4819 AllowedNameModifiers.push_back(OMPD_target);
4821 case OMPD_target_teams_distribute_parallel_for:
4822 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4823 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4824 AllowedNameModifiers.push_back(OMPD_target);
4825 AllowedNameModifiers.push_back(OMPD_parallel);
4827 case OMPD_target_teams_distribute_parallel_for_simd:
4828 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4829 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4830 AllowedNameModifiers.push_back(OMPD_target);
4831 AllowedNameModifiers.push_back(OMPD_parallel);
4832 if (LangOpts.OpenMP >= 50)
4833 AllowedNameModifiers.push_back(OMPD_simd);
4835 case OMPD_target_teams_distribute_simd:
4836 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4837 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4838 AllowedNameModifiers.push_back(OMPD_target);
4839 if (LangOpts.OpenMP >= 50)
4840 AllowedNameModifiers.push_back(OMPD_simd);
4842 case OMPD_declare_target:
4843 case OMPD_end_declare_target:
4844 case OMPD_threadprivate:
4846 case OMPD_declare_reduction:
4847 case OMPD_declare_mapper:
4848 case OMPD_declare_simd:
4850 case OMPD_declare_variant:
4851 llvm_unreachable(
"OpenMP Directive is not allowed");
4853 llvm_unreachable(
"Unknown OpenMP directive");
4856 ErrorFound = Res.
isInvalid() || ErrorFound;
4859 if (
DSAStack->getDefaultDSA() == DSA_none) {
4860 DSAAttrChecker DSAChecker(
DSAStack, *
this,
nullptr);
4862 switch (
C->getClauseKind()) {
4863 case OMPC_num_threads:
4864 case OMPC_dist_schedule:
4871 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_target)
4875 cast<OMPIfClause>(
C)->getNameModifier() != OMPD_parallel)
4880 case OMPC_grainsize:
4881 case OMPC_num_tasks:
4890 case OMPC_num_teams:
4891 case OMPC_thread_limit:
4897 case OMPC_proc_bind:
4899 case OMPC_firstprivate:
4900 case OMPC_lastprivate:
4902 case OMPC_reduction:
4903 case OMPC_task_reduction:
4904 case OMPC_in_reduction:
4908 case OMPC_copyprivate:
4911 case OMPC_mergeable:
4923 case OMPC_defaultmap:
4926 case OMPC_use_device_ptr:
4927 case OMPC_is_device_ptr:
4928 case OMPC_nontemporal:
4930 case OMPC_allocator:
4935 case OMPC_unified_address:
4936 case OMPC_unified_shared_memory:
4937 case OMPC_reverse_offload:
4938 case OMPC_dynamic_allocators:
4939 case OMPC_atomic_default_mem_order:
4942 llvm_unreachable(
"Unexpected clause");
4944 for (
Stmt *CC :
C->children()) {
4946 DSAChecker.Visit(CC);
4949 for (
auto &
P : DSAChecker.getVarsWithInheritedDSA())
4950 VarsWithInheritedDSA[
P.getFirst()] =
P.getSecond();
4952 for (
const auto &
P : VarsWithInheritedDSA) {
4953 if (
P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(
P.getFirst()))
4956 if (
DSAStack->getDefaultDSA() == DSA_none) {
4957 Diag(
P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4958 <<
P.first <<
P.second->getSourceRange();
4959 Diag(
DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
4960 }
else if (getLangOpts().OpenMP >= 50) {
4961 Diag(
P.second->getExprLoc(),
4962 diag::err_omp_defaultmap_no_attr_for_variable)
4963 <<
P.first <<
P.second->getSourceRange();
4965 diag::note_omp_defaultmap_attr_none);
4969 if (!AllowedNameModifiers.empty())
4970 ErrorFound =
checkIfClauses(*
this, Kind, Clauses, AllowedNameModifiers) ||
4978 ->getStructuredBlock()
4982 if (!CurContext->isDependentContext() &&
4989 DSAStack->addTargetDirLocation(StartLoc);
5000 assert(Aligneds.size() == Alignments.size());
5001 assert(Linears.size() == LinModifiers.size());
5002 assert(Linears.size() == Steps.size());
5003 if (!DG || DG.
get().isNull())
5006 const int SimdId = 0;
5007 if (!DG.
get().isSingleDecl()) {
5008 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5012 Decl *ADecl = DG.
get().getSingleDecl();
5013 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5014 ADecl = FTD->getTemplatedDecl();
5018 Diag(ADecl->
getLocation(), diag::err_omp_function_expected) << SimdId;
5027 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5034 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5035 const Expr *UniformedLinearThis =
nullptr;
5036 for (
const Expr *E : Uniforms) {
5038 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
5039 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5040 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5041 FD->getParamDecl(PVD->getFunctionScopeIndex())
5043 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5046 if (isa<CXXThisExpr>(E)) {
5047 UniformedLinearThis = E;
5051 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5061 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5062 const Expr *AlignedThis =
nullptr;
5063 for (
const Expr *E : Aligneds) {
5065 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
5066 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5068 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5069 FD->getParamDecl(PVD->getFunctionScopeIndex())
5073 if (AlignedArgs.count(CanonPVD) > 0) {
5077 Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5078 diag::note_omp_explicit_dsa)
5082 AlignedArgs[CanonPVD] = E;
5084 .getNonReferenceType()
5085 .getUnqualifiedType()
5086 .getCanonicalType();
5089 Diag(E->
getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5091 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5096 if (isa<CXXThisExpr>(E)) {
5107 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5114 for (
Expr *E : Alignments) {
5117 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5118 NewAligns.push_back(Align.
get());
5129 llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5130 const bool IsUniformedThis = UniformedLinearThis !=
nullptr;
5131 auto MI = LinModifiers.begin();
5132 for (
const Expr *E : Linears) {
5136 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E))
5137 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5139 if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5140 FD->getParamDecl(PVD->getFunctionScopeIndex())
5144 if (LinearArgs.count(CanonPVD) > 0) {
5148 Diag(LinearArgs[CanonPVD]->getExprLoc(),
5149 diag::note_omp_explicit_dsa)
5154 if (UniformedArgs.count(CanonPVD) > 0) {
5158 Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5159 diag::note_omp_explicit_dsa)
5163 LinearArgs[CanonPVD] = E;
5168 (void)CheckOpenMPLinearDecl(CanonPVD, E->
getExprLoc(), LinKind,
5169 PVD->getOriginalType());
5173 if (isa<CXXThisExpr>(E)) {
5174 if (UniformedLinearThis) {
5179 Diag(UniformedLinearThis->
getExprLoc(), diag::note_omp_explicit_dsa)
5184 UniformedLinearThis = E;
5188 (void)CheckOpenMPLinearDecl(
nullptr, E->
getExprLoc(), LinKind,
5193 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5196 Expr *NewStep =
nullptr;
5198 for (
Expr *E : Steps) {
5200 if (Step == E || !E) {
5201 NewSteps.push_back(E ? NewStep :
nullptr);
5205 if (
const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5206 if (
const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5208 if (UniformedArgs.count(CanonPVD) == 0) {
5215 NewSteps.push_back(Step);
5226 NewStep = PerformOpenMPImplicitIntegerConversion(Step->
getExprLoc(),
Step)
5229 NewStep = VerifyIntegerConstantExpression(NewStep).get();
5231 NewSteps.push_back(NewStep);
5233 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5234 Context, BS, SL.
get(),
const_cast<Expr **
>(Uniforms.data()),
5235 Uniforms.size(),
const_cast<Expr **
>(Aligneds.data()), Aligneds.size(),
5236 const_cast<Expr **
>(NewAligns.data()), NewAligns.size(),
5237 const_cast<Expr **
>(Linears.data()), Linears.size(),
5238 const_cast<unsigned *
>(LinModifiers.data()), LinModifiers.size(),
5239 NewSteps.data(), NewSteps.size(), SR);
5247 "Expected function type with prototype.");
5249 "Expected function with type with no prototype.");
5251 "Expected function with prototype.");
5260 Param->setImplicit();
5261 Params.push_back(Param);
5264 FD->setParams(Params);
5270 if (!DG || DG.
get().isNull())
5273 const int VariantId = 1;
5275 if (!DG.
get().isSingleDecl()) {
5276 Diag(SR.
getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5280 Decl *ADecl = DG.
get().getSingleDecl();
5281 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5282 ADecl = FTD->getTemplatedDecl();
5292 auto &&HasMultiVersionAttributes = [](
const FunctionDecl *FD) {
5293 return FD->hasAttrs() &&
5294 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5295 FD->hasAttr<TargetAttr>());
5298 if (HasMultiVersionAttributes(FD)) {
5299 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
5305 if (FD->isUsed(
false))
5306 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_used)
5307 << FD->getLocation();
5311 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5313 Diag(SR.
getBegin(), diag::warn_omp_declare_variant_after_emitted)
5314 << FD->getLocation();
5318 Diag(SR.
getBegin(), diag::err_omp_function_expected) << VariantId;
5326 return std::make_pair(FD, VariantRef);
5331 if (LangOpts.CPlusPlus) {
5334 if (Method && !Method->isStatic()) {
5335 const Type *ClassType =
5343 ER = CreateBuiltinUnaryOp(VariantRef->
getBeginLoc(), UO_AddrOf,
5351 VariantRef = ER.
get();
5364 diag::err_omp_declare_variant_incompat_types)
5366 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
5370 VariantRefCast = PerformImplicitConversion(
5375 if (Method && !Method->isStatic()) {
5376 Expr *PossibleAddrOfVariantRef = VariantRefCast.
get();
5377 if (
auto *UO = dyn_cast<UnaryOperator>(
5379 VariantRefCast = UO->getSubExpr();
5382 VariantRefCast = VariantRef;
5387 !ER.
get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5394 auto *DRE = dyn_cast<
DeclRefExpr>(ER.
get()->IgnoreParenImpCasts());
5400 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5408 if (!LangOpts.CPlusPlus) {
5413 diag::err_omp_declare_variant_incompat_types)
5414 << NewFD->getType() << FD->getType() << VariantRef->
getSourceRange();
5418 if (FD->getType()->isFunctionNoProtoType())
5420 else if (NewFD->getType()->isFunctionNoProtoType())
5426 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5428 diag::warn_omp_declare_variant_marked_as_declare_variant)
5431 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5432 Diag(SR.
getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
5436 enum DoesntSupport {
5445 if (
const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5446 if (CXXFD->isVirtual()) {
5447 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5452 if (isa<CXXConstructorDecl>(FD)) {
5453 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5458 if (isa<CXXDestructorDecl>(FD)) {
5459 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5465 if (FD->isDeleted()) {
5466 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5471 if (FD->isDefaulted()) {
5472 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5477 if (FD->isConstexpr()) {
5478 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5479 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
5484 if (areMultiversionVariantFunctionsCompatible(
5490 PDiag(diag::err_omp_declare_variant_doesnt_support)),
5492 PDiag(diag::err_omp_declare_variant_diff)
5493 << FD->getLocation()),
5497 return std::make_pair(FD, cast<Expr>(DRE));
5509 bool IsError =
false;
5515 Expr *Score =
nullptr;
5516 if (D.Score.isUsable()) {
5517 Score = D.Score.get();
5522 PerformOpenMPImplicitIntegerConversion(Score->
getExprLoc(), Score)
5525 Score = VerifyIntegerConstantExpression(Score).get();
5537 if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind)
5543 case OMP_CTX_vendor:
5544 assert(CtxSet == OMP_CTX_SET_implementation &&
5545 "Expected implementation context selector set.");
5546 ImplVendors.append(D.Names.begin(), D.Names.end());
5549 assert(CtxSet == OMP_CTX_SET_device &&
5550 "Expected device context selector set.");
5551 DeviceKinds.append(D.Names.begin(), D.Names.end());
5554 llvm_unreachable(
"Unknown context selector kind.");
5556 IsError = IsError || !Score;
5557 CtxSets.push_back(CtxSet);
5558 Ctxs.push_back(Ctx);
5559 CtxScores.push_back(Score);
5562 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
5563 Context, VariantRef, CtxScores.begin(), CtxScores.size(),
5564 CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(),
5565 ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(),
5566 DeviceKinds.size(), SR);
5571 void Sema::markOpenMPDeclareVariantFuncsReferenced(
SourceLocation Loc,
5573 bool MightBeOdrUse) {
5574 assert(LangOpts.OpenMP &&
"Expected OpenMP mode.");
5577 for (OMPDeclareVariantAttr *A :
5580 Expr *VariantRef = A->getVariantFuncRef();
5582 auto *F = cast<FunctionDecl>(DRE->getDecl());
5583 if (!F->isDefined() && F->isTemplateInstantiation())
5584 InstantiateFunctionDefinition(Loc, F->getFirstDecl());
5585 MarkFunctionReferenced(Loc, F, MightBeOdrUse);
5597 auto *CS = cast<CapturedStmt>(AStmt);
5605 setFunctionHasBranchProtectedScope();
5613 struct LoopIterationSpace final {
5616 bool IsStrictCompare =
false;
5618 Expr *PreCond =
nullptr;
5621 Expr *NumIterations =
nullptr;
5623 Expr *CounterVar =
nullptr;
5625 Expr *PrivateCounterVar =
nullptr;
5627 Expr *CounterInit =
nullptr;
5630 Expr *CounterStep =
nullptr;
5632 bool Subtract =
false;
5642 Expr *MinValue =
nullptr;
5646 Expr *MaxValue =
nullptr;
5648 bool IsNonRectangularLB =
false;
5650 bool IsNonRectangularUB =
false;
5653 unsigned LoopDependentIdx = 0;
5657 Expr *FinalCondition =
nullptr;
5663 class OpenMPIterationSpaceChecker {
5681 Expr *LCRef =
nullptr;
5696 bool TestIsStrictOp =
false;
5698 bool SubtractStep =
false;
5711 Expr *Condition =
nullptr;
5714 OpenMPIterationSpaceChecker(
Sema &SemaRef, DSAStackTy &Stack,
5716 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
5717 ConditionLoc(DefaultLoc) {}
5720 bool checkAndSetInit(
Stmt *S,
bool EmitDiags =
true);
5723 bool checkAndSetCond(
Expr *S);
5726 bool checkAndSetInc(
Expr *S);
5728 ValueDecl *getLoopDecl()
const {
return LCDecl; }
5730 Expr *getLoopDeclRefExpr()
const {
return LCRef; }
5732 SourceRange getInitSrcRange()
const {
return InitSrcRange; }
5734 SourceRange getConditionSrcRange()
const {
return ConditionSrcRange; }
5736 SourceRange getIncrementSrcRange()
const {
return IncrementSrcRange; }
5738 bool shouldSubtractStep()
const {
return SubtractStep; }
5740 bool isStrictTestOp()
const {
return TestIsStrictOp; }
5742 Expr *buildNumIterations(
5744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
5748 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
5751 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5752 DSAStackTy &DSA)
const;
5755 Expr *buildPrivateCounterVar()
const;
5759 Expr *buildCounterStep()
const;
5763 buildOrderedLoopData(
Scope *S,
Expr *Counter,
5764 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5768 std::pair<Expr *, Expr *> buildMinMaxValues(
5769 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const;
5771 Expr *buildFinalCondition(
Scope *S)
const;
5773 bool dependent()
const;
5775 bool doesInitDependOnLC()
const {
return InitDependOnLC.hasValue(); }
5777 bool doesCondDependOnLC()
const {
return CondDependOnLC.hasValue(); }
5779 unsigned getLoopDependentIdx()
const {
5780 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
5786 bool checkAndSetIncRHS(
Expr *RHS);
5797 bool OpenMPIterationSpaceChecker::dependent()
const {
5799 assert(!LB && !UB && !
Step);
5802 return LCDecl->getType()->isDependentType() ||
5803 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
5804 (
Step &&
Step->isValueDependent());
5807 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(
ValueDecl *NewLCDecl,
5809 Expr *NewLB,
bool EmitDiags) {
5811 assert(LCDecl ==
nullptr && LB ==
nullptr && LCRef ==
nullptr &&
5812 UB ==
nullptr &&
Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
5813 if (!NewLCDecl || !NewLB)
5816 LCRef = NewLCRefExpr;
5817 if (
auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
5819 if ((Ctor->isCopyOrMoveConstructor() ||
5820 Ctor->isConvertingConstructor(
false)) &&
5821 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
5825 InitDependOnLC = doesDependOnLoopCounter(LB,
true);
5829 bool OpenMPIterationSpaceChecker::setUB(
Expr *NewUB,
5834 assert(LCDecl !=
nullptr && LB !=
nullptr && UB ==
nullptr &&
5835 Step ==
nullptr && !TestIsLessOp && !TestIsStrictOp);
5840 TestIsLessOp = LessOp;
5841 TestIsStrictOp = StrictOp;
5842 ConditionSrcRange = SR;
5844 CondDependOnLC = doesDependOnLoopCounter(UB,
false);
5850 assert(LCDecl !=
nullptr && LB !=
nullptr &&
Step ==
nullptr);
5860 NewStep = Val.
get();
5877 IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
5879 IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
5880 bool IsConstZero = IsConstant && !Result.getBoolValue();
5883 if (!TestIsLessOp.hasValue())
5884 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
5885 if (UB && (IsConstZero ||
5886 (TestIsLessOp.getValue() ?
5887 (IsConstNeg || (IsUnsigned && Subtract)) :
5888 (IsConstPos || (IsUnsigned && !Subtract))))) {
5890 diag::err_omp_loop_incr_not_compatible)
5891 << LCDecl << TestIsLessOp.getValue() << NewStep->
getSourceRange();
5892 SemaRef.
Diag(ConditionLoc,
5893 diag::note_omp_loop_cond_requres_compatible_incr)
5894 << TestIsLessOp.getValue() << ConditionSrcRange;
5897 if (TestIsLessOp.getValue() == Subtract) {
5901 Subtract = !Subtract;
5906 SubtractStep = Subtract;
5913 class LoopCounterRefChecker final
5920 bool IsInitializer =
true;
5921 unsigned BaseLoopId = 0;
5924 SemaRef.Diag(E->
getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
5925 << (IsInitializer ? 0 : 1);
5928 const auto &&Data = Stack.isLoopControlVariable(VD);
5934 llvm::raw_svector_ostream OS(Name);
5938 diag::err_omp_wrong_dependency_iterator_type)
5940 SemaRef.Diag(VD->
getLocation(), diag::note_previous_decl) << VD;
5944 (DepDecl || (PrevDepDecl &&
5946 if (!DepDecl && PrevDepDecl)
5947 DepDecl = PrevDepDecl;
5949 llvm::raw_svector_ostream OS(Name);
5953 diag::err_omp_invariant_or_linear_dependency)
5959 BaseLoopId = Data.first;
5967 if (isa<VarDecl>(VD))
5968 return checkDecl(E, VD);
5974 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
5975 return checkDecl(E, VD);
5979 bool VisitStmt(
const Stmt *S) {
5982 Res = (Child && Visit(Child)) || Res;
5985 explicit LoopCounterRefChecker(
Sema &SemaRef, DSAStackTy &Stack,
5986 const ValueDecl *CurLCDecl,
bool IsInitializer,
5988 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
5989 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
5990 unsigned getBaseLoopId()
const {
5991 assert(CurLCDecl &&
"Expected loop dependency.");
5995 assert(CurLCDecl &&
"Expected loop dependency.");
6002 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(
const Stmt *S,
6003 bool IsInitializer) {
6005 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6007 if (LoopStmtChecker.Visit(S)) {
6008 DepDecl = LoopStmtChecker.getDepDecl();
6009 return LoopStmtChecker.getBaseLoopId();
6014 bool OpenMPIterationSpaceChecker::checkAndSetInit(
Stmt *S,
bool EmitDiags) {
6025 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6029 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6030 if (!ExprTemp->cleanupsHaveSideEffects())
6031 S = ExprTemp->getSubExpr();
6034 if (
Expr *E = dyn_cast<Expr>(S))
6036 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
6037 if (BO->getOpcode() == BO_Assign) {
6039 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6040 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6042 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6044 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6046 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
6047 if (ME->isArrow() &&
6048 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6049 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6053 }
else if (
auto *DS = dyn_cast<DeclStmt>(S)) {
6054 if (DS->isSingleDecl()) {
6055 if (
auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6056 if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6060 diag::ext_omp_loop_not_canonical_init)
6062 return setLCDeclAndLB(
6065 Var->getType().getNonReferenceType(),
6067 Var->getInit(), EmitDiags);
6071 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6072 if (CE->getOperator() == OO_Equal) {
6073 Expr *LHS = CE->getArg(0);
6074 if (
auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6075 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6077 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6079 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6081 if (
auto *ME = dyn_cast<MemberExpr>(LHS)) {
6082 if (ME->isArrow() &&
6083 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6084 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6105 if (
const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6107 if ((Ctor->isCopyOrMoveConstructor() ||
6108 Ctor->isConvertingConstructor(
false)) &&
6109 CE->getNumArgs() > 0 && CE->getArg(0) !=
nullptr)
6111 if (
const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6112 if (
const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6115 if (
const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6116 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6121 bool OpenMPIterationSpaceChecker::checkAndSetCond(
Expr *S) {
6128 bool IneqCondIsCanonical = SemaRef.
getLangOpts().OpenMP >= 50;
6130 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6131 << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6137 if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
6138 if (BO->isRelationalOp()) {
6139 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6140 return setUB(BO->getRHS(),
6141 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6142 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6143 BO->getSourceRange(), BO->getOperatorLoc());
6144 if (getInitLCDecl(BO->getRHS()) == LCDecl)
6145 return setUB(BO->getLHS(),
6146 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6147 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6148 BO->getSourceRange(), BO->getOperatorLoc());
6149 }
else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6151 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6153 true, BO->getSourceRange(), BO->getOperatorLoc());
6154 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6155 if (CE->getNumArgs() == 2) {
6156 auto Op = CE->getOperator();
6159 case OO_GreaterEqual:
6162 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6163 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6164 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6165 CE->getOperatorLoc());
6166 if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6167 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6168 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6169 CE->getOperatorLoc());
6171 case OO_ExclaimEqual:
6172 if (IneqCondIsCanonical)
6173 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6176 true, CE->getSourceRange(),
6177 CE->getOperatorLoc());
6186 SemaRef.
Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6187 << (IneqCondIsCanonical ? 1 : 0) << S->
getSourceRange() << LCDecl;
6191 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(
Expr *RHS) {
6198 if (
auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6199 if (BO->isAdditiveOp()) {
6200 bool IsAdd = BO->getOpcode() == BO_Add;
6201 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6202 return setStep(BO->getRHS(), !IsAdd);
6203 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6204 return setStep(BO->getLHS(),
false);
6206 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6207 bool IsAdd = CE->getOperator() == OO_Plus;
6208 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6209 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6210 return setStep(CE->getArg(1), !IsAdd);
6211 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6212 return setStep(CE->getArg(0),
false);
6217 SemaRef.
Diag(RHS->
getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6222 bool OpenMPIterationSpaceChecker::checkAndSetInc(
Expr *S) {
6237 SemaRef.
Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6240 if (
auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6241 if (!ExprTemp->cleanupsHaveSideEffects())
6242 S = ExprTemp->getSubExpr();
6246 if (
auto *UO = dyn_cast<UnaryOperator>(S)) {
6247 if (UO->isIncrementDecrementOp() &&
6248 getInitLCDecl(UO->getSubExpr()) == LCDecl)
6250 .ActOnIntegerConstant(UO->getBeginLoc(),
6251 (UO->isDecrementOp() ? -1 : 1))
6254 }
else if (
auto *BO = dyn_cast<BinaryOperator>(S)) {
6255 switch (BO->getOpcode()) {
6258 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6259 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6262 if (getInitLCDecl(BO->getLHS()) == LCDecl)
6263 return checkAndSetIncRHS(BO->getRHS());
6268 }
else if (
auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6269 switch (CE->getOperator()) {
6272 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6274 .ActOnIntegerConstant(
6276 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6282 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6283 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6286 if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6287 return checkAndSetIncRHS(CE->getArg(1));
6301 tryBuildCapture(
Sema &SemaRef,
Expr *Capture,
6302 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6309 auto I = Captures.find(Capture);
6310 if (I != Captures.end())
6314 Captures[Capture] = Ref;
6319 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
6321 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
6323 QualType VarType = LCDecl->getType().getNonReferenceType();
6330 if (InitDependOnLC) {
6331 const LoopIterationSpace &IS =
6332 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6333 InitDependOnLC.getValueOr(
6334 CondDependOnLC.getValueOr(0))];
6335 if (!IS.MinValue || !IS.MaxValue)
6344 IS.CounterVar, MinValue.
get());
6349 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.
get(), LBVal);
6364 IS.CounterVar, MaxValue.
get());
6369 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.
get(), LBVal);
6377 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.
get(), Captures).
get();
6378 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.
get(), Captures).
get();
6379 if (!LBMin || !LBMax)
6383 SemaRef.
BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
6387 tryBuildCapture(SemaRef, MinLessMaxRes.
get(), Captures).
get();
6390 if (TestIsLessOp.getValue()) {
6394 MinLessMax, LBMin, LBMax);
6397 LBVal = MinLB.
get();
6402 MinLessMax, LBMax, LBMin);
6405 LBVal = MaxLB.
get();
6410 if (CondDependOnLC) {
6411 const LoopIterationSpace &IS =
6412 ResultIterSpaces[ResultIterSpaces.size() - 1 -
6413 InitDependOnLC.getValueOr(
6414 CondDependOnLC.getValueOr(0))];
6415 if (!IS.MinValue || !IS.MaxValue)
6424 IS.CounterVar, MinValue.
get());
6429 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.
get(), UBVal);
6444 IS.CounterVar, MaxValue.
get());
6449 SemaRef.
BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.
get(), UBVal);
6457 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.
get(), Captures).
get();
6458 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.
get(), Captures).
get();
6459 if (!UBMin || !UBMax)
6463 SemaRef.
BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
6466 Expr *MinGreaterMax =
6467 tryBuildCapture(SemaRef, MinGreaterMaxRes.
get(), Captures).
get();
6470 if (TestIsLessOp.getValue()) {
6474 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
6477 UBVal = MaxUB.
get();
6482 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
6485 UBVal = MinUB.
get();
6489 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
6490 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
6491 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
6492 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
6493 if (!Upper || !Lower)
6496 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6513 S, DefaultLoc, BO_Sub, Diff.
get(),
6522 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Diff.
get(), NewStep.
get());
6532 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
6555 unsigned NewSize = (C.
getTypeSize(Type) > 32) ? 64 : 32;
6558 assert(NewSize == 64 &&
"incorrect loop var size");
6559 SemaRef.
Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
6560 << InitSrcRange << ConditionSrcRange;
6577 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
6578 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
6581 if (LCDecl->getType()->isRecordType())
6582 return std::make_pair(
nullptr,
nullptr);
6585 Expr *MinExpr =
nullptr;
6586 Expr *MaxExpr =
nullptr;
6587 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
6588 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
6589 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
6590 : CondDependOnLC.hasValue();
6591 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
6592 : InitDependOnLC.hasValue();
6594 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
6596 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
6597 if (!Upper || !Lower)
6598 return std::make_pair(
nullptr,
nullptr);
6600 if (TestIsLessOp.getValue())
6607 QualType VarType = LCDecl->getType().getNonReferenceType();
6609 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6611 return std::make_pair(
nullptr,
nullptr);
6616 S, DefaultLoc, BO_Sub, Diff.
get(),
6619 return std::make_pair(
nullptr,
nullptr);
6624 return std::make_pair(
nullptr,
nullptr);
6629 return std::make_pair(
nullptr,
nullptr);
6632 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
6634 return std::make_pair(
nullptr,
nullptr);
6640 return std::make_pair(
nullptr,
nullptr);
6642 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Mul, Diff.
get(), NewStep.
get());
6644 return std::make_pair(
nullptr,
nullptr);
6653 Diff.
get()->getType(),
6660 return std::make_pair(
nullptr,
nullptr);
6665 return std::make_pair(
nullptr,
nullptr);
6667 if (TestIsLessOp.getValue()) {
6670 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.
get());
6672 return std::make_pair(
nullptr,
nullptr);
6675 return std::make_pair(
nullptr,
nullptr);
6676 MaxExpr = Diff.
get();
6680 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.
get());
6682 return std::make_pair(
nullptr,
nullptr);
6685 return std::make_pair(
nullptr,
nullptr);
6686 MinExpr = Diff.
get();
6689 return std::make_pair(MinExpr, MaxExpr);
6692 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(
Scope *S)
const {
6693 if (InitDependOnLC || CondDependOnLC)
6698 Expr *OpenMPIterationSpaceChecker::buildPreCond(
6700 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures)
const {
6705 if (CondDependOnLC || InitDependOnLC)
6714 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
6715 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
6721 TestIsLessOp.getValue() ?
6722 (TestIsStrictOp ? BO_LT : BO_LE) :
6723 (TestIsStrictOp ? BO_GT : BO_GE),
6724 NewLB.
get(), NewUB.
get());
6734 return CondExpr.
isUsable() ? CondExpr.
get() : Cond;
6738 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
6739 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6740 DSAStackTy &DSA)
const {
6741 auto *VD = dyn_cast<
VarDecl>(LCDecl);
6745 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
6746 const DSAStackTy::DSAVarData Data =
6747 DSA.getTopDSA(LCDecl,
false);
6751 Captures.insert(std::make_pair(LCRef, Ref));
6754 return cast<DeclRefExpr>(LCRef);
6757 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar()
const {
6758 if (LCDecl && !LCDecl->isInvalidDecl()) {
6759 QualType Type = LCDecl->getType().getNonReferenceType();
6761 SemaRef, DefaultLoc, Type, LCDecl->getName(),
6762 LCDecl->hasAttrs() ? &LCDecl->getAttrs() :
nullptr,
6763 isa<VarDecl>(LCDecl)
6777 Expr *OpenMPIterationSpaceChecker::buildCounterStep()
const {
return Step; }
6779 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
6781 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
SourceLocation Loc,
6787 assert((OOK == OO_Plus || OOK == OO_Minus) &&
6788 "Expected only + or - operations for depend clauses.");
6795 QualType VarType = LCDecl->getType().getNonReferenceType();
6799 Expr *Upper = TestIsLessOp.getValue()
6801 : tryBuildCapture(SemaRef, UB, Captures).get();
6802 Expr *Lower = TestIsLessOp.getValue()
6803 ? tryBuildCapture(SemaRef, LB, Captures).get()
6805 if (!Upper || !Lower)
6808 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6831 Diff = SemaRef.
BuildBinOp(S, DefaultLoc, BO_Div, Diff.
get(), NewStep.
get());
6840 assert(getLangOpts().OpenMP &&
"OpenMP is not active.");
6841 assert(Init &&
"Expected loop in canonical form.");
6842 unsigned AssociatedLoops =
DSAStack->getAssociatedLoops();
6843 if (AssociatedLoops > 0 &&
6846 OpenMPIterationSpaceChecker ISC(*
this, *
DSAStack, ForLoc);
6847 if (!ISC.checkAndSetInit(Init,
false)) {
6849 auto *VD = dyn_cast<
VarDecl>(D);
6852 if (
VarDecl *Private = isOpenMPCapturedDecl(D)) {
6855 PrivateRef =
buildCapture(*
this, D, ISC.getLoopDeclRefExpr(),
6857 VD = cast<VarDecl>(PrivateRef->getDecl());
6860 DSAStack->addLoopControlVariable(D, VD);
6863 DSAStack->resetPossibleLoopCounter();
6864 if (
auto *Var = dyn_cast_or_null<VarDecl>(LD))
6865 MarkDeclarationsReferencedInExpr(
6867 Var->getType().getNonLValueExprType(Context),
6878 DSAStackTy::DSAVarData DVar =
6882 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
6885 ? (
DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
6888 DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
6889 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
6890 DVar.CKind != OMPC_private))) ||
6892 DKind == OMPD_master_taskloop ||
6893 DKind == OMPD_parallel_master_taskloop ||
6896 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
6897 (DVar.CKind != OMPC_private || DVar.RefExpr)) {
6900 << getOpenMPDirectiveName(DKind)
6902 if (DVar.RefExpr ==
nullptr)
6903 DVar.CKind = PredeterminedCKind;
6906 }
else if (LoopDeclRefExpr) {
6912 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
6917 DSAStack->setAssociatedLoops(AssociatedLoops - 1);
6925 unsigned CurrentNestedLoopCount,
unsigned NestedLoopCount,
6926 unsigned TotalNestedLoopCount,
Expr *CollapseLoopCountExpr,
6927 Expr *OrderedLoopCountExpr,
6930 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6934 auto *For = dyn_cast_or_null<ForStmt>(S);
6935 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
6937 if (!For && (SemaRef.
LangOpts.OpenMP <= 45 || !CXXFor)) {
6939 << (CollapseLoopCountExpr !=
nullptr || OrderedLoopCountExpr !=
nullptr)
6940 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
6941 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
6942 if (TotalNestedLoopCount > 1) {
6943 if (CollapseLoopCountExpr && OrderedLoopCountExpr)
6944 SemaRef.
Diag(DSA.getConstructLoc(),
6945 diag::note_omp_collapse_ordered_expr)
6948 else if (CollapseLoopCountExpr)
6950 diag::note_omp_collapse_ordered_expr)
6954 diag::note_omp_collapse_ordered_expr)
6959 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
6962 OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
6963 For ? For->getForLoc() : CXXFor->getForLoc());
6966 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
6967 if (ISC.checkAndSetInit(Init))
6970 bool HasErrors =
false;
6973 if (
ValueDecl *LCDecl = ISC.getLoopDecl()) {
6979 QualType VarType = LCDecl->getType().getNonReferenceType();
6983 SemaRef.
Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
6997 VarsWithImplicitDSA.erase(LCDecl);
7002 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7005 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7012 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7013 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7014 ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7015 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7020 ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7021 ISC.buildCounterVar(Captures, DSA);
7022 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7023 ISC.buildPrivateCounterVar();
7024 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7025 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7026 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7027 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7028 ISC.getConditionSrcRange();
7029 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7030 ISC.getIncrementSrcRange();
7031 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7032 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7033 ISC.isStrictTestOp();
7034 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7035 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7036 ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7037 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7038 ISC.buildFinalCondition(DSA.getCurScope());
7039 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7040 ISC.doesInitDependOnLC();
7041 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7042 ISC.doesCondDependOnLC();
7043 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7044 ISC.getLoopDependentIdx();
7047 (ResultIterSpaces[CurrentNestedLoopCount].PreCond ==
nullptr ||
7048 ResultIterSpaces[CurrentNestedLoopCount].NumIterations ==
nullptr ||
7049 ResultIterSpaces[CurrentNestedLoopCount].CounterVar ==
nullptr ||
7050 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar ==
nullptr ||
7051 ResultIterSpaces[CurrentNestedLoopCount].CounterInit ==
nullptr ||
7052 ResultIterSpaces[CurrentNestedLoopCount].CounterStep ==
nullptr);
7053 if (!HasErrors && DSA.isOrderedRegion()) {
7054 if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7055 if (CurrentNestedLoopCount <
7056 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7057 DSA.getOrderedRegionParam().second->setLoopNumIterations(
7058 CurrentNestedLoopCount,
7059 ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7060 DSA.getOrderedRegionParam().second->setLoopCounter(
7061 CurrentNestedLoopCount,
7062 ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7065 for (
auto &Pair : DSA.getDoacrossDependClauses()) {
7066 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7070 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7071 Pair.second.size() <= CurrentNestedLoopCount) {
7073 Pair.first->setLoopData(CurrentNestedLoopCount,
nullptr);
7077 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7078 CntValue = ISC.buildOrderedLoopData(
7080 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7081 Pair.first->getDependencyLoc());
7083 CntValue = ISC.buildOrderedLoopData(
7085 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7086 Pair.first->getDependencyLoc(),
7087 Pair.second[CurrentNestedLoopCount].first,
7088 Pair.second[CurrentNestedLoopCount].second);
7089 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7100 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7104 : tryBuildCapture(SemaRef, Start.
get(), Captures);
7108 VarRef.
get()->getType())) {
7125 bool IsNonRectangularLB,
7126 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures =
nullptr) {
7135 NewStep = tryBuildCapture(SemaRef, Step.
get(), *Captures);
7150 if (Captures && !IsNonRectangularLB)
7151 NewStart = tryBuildCapture(SemaRef, Start.
get(), *Captures);
7158 if (VarRef.
get()->getType()->isOverloadableType() ||
7159 NewStart.
get()->getType()->isOverloadableType() ||
7160 Update.
get()->getType()->isOverloadableType()) {
7167 SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7168 VarRef.
get(), SavedUpdate.
get());
7178 Update = SemaRef.
BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7179 NewStart.
get(), SavedUpdate.
get());
7184 VarRef.
get()->getType())) {
7191 Update = SemaRef.
BuildBinOp(S, Loc, BO_Assign, VarRef.
get(), Update.
get());
7204 if (HasBits >= Bits)
7219 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
7225 MutableArrayRef<Decl *> PreInits) {
7226 if (!PreInits.empty()) {
7237 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7238 if (!Captures.empty()) {
7240 for (
const auto &Pair : Captures)
7241 PreInits.push_back(Pair.second->getDecl());
7249 Expr *PostUpdate =
nullptr;
7250 if (!PostUpdates.empty()) {
7251 for (
Expr *E : PostUpdates) {
7257 PostUpdate = PostUpdate
7272 Expr *OrderedLoopCountExpr,
Stmt *AStmt,
Sema &SemaRef,
7276 unsigned NestedLoopCount = 1;
7277 if (CollapseLoopCountExpr) {
7282 NestedLoopCount = Result.
Val.
getInt().getLimitedValue();
7288 unsigned OrderedLoopCount = 1;
7289 if (OrderedLoopCountExpr) {
7296 if (Result.getLimitedValue() < NestedLoopCount) {
7298 diag::err_omp_wrong_ordered_loop_count)
7301 diag::note_collapse_loop_count)
7304 OrderedLoopCount = Result.getLimitedValue();
7312 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
7314 std::max(OrderedLoopCount, NestedLoopCount));
7316 for (
unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7318 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7319 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7320 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7327 if (
auto *For = dyn_cast<ForStmt>(CurStmt)) {
7328 CurStmt = For->getBody();
7330 assert(isa<CXXForRangeStmt>(CurStmt) &&
7331 "Expected canonical for or range-based for loops.");
7332 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7335 CurStmt, SemaRef.
LangOpts.OpenMP >= 50);
7337 for (
unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
7339 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7340 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7341 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7343 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
7345 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
7346 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
7347 Captures[DRE] = DRE;
7355 if (
auto *For = dyn_cast<ForStmt>(CurStmt)) {
7356 CurStmt = For->getBody();
7358 assert(isa<CXXForRangeStmt>(CurStmt) &&
7359 "Expected canonical for or range-based for loops.");
7360 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7363 CurStmt, SemaRef.
LangOpts.OpenMP >= 50);
7366 Built.
clear( NestedLoopCount);
7369 return NestedLoopCount;
7402 auto PreCond =
ExprResult(IterSpaces[0].PreCond);
7403 Expr *N0 = IterSpaces[0].NumIterations;
7407 .PerformImplicitConversion(
7421 if (!LastIteration32.
isUsable() || !LastIteration64.isUsable())
7422 return NestedLoopCount;
7427 Scope *CurScope = DSA.getCurScope();
7428 for (
unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
7429 if (PreCond.isUsable()) {
7431 SemaRef.
BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
7432 PreCond.get(), IterSpaces[Cnt].PreCond);
7434 Expr *N = IterSpaces[Cnt].NumIterations;
7439 CurScope, Loc, BO_Mul, LastIteration32.
get(),
7445 if (LastIteration64.isUsable())
7447 CurScope, Loc, BO_Mul, LastIteration64.get(),
7457 if (SemaRef.
getLangOpts().OpenMPOptimisticCollapse ||
7460 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
7463 LastIteration32.
get()->getType()->hasSignedIntegerRepresentation(),
7464 LastIteration64.get(), SemaRef))))
7465 LastIteration = LastIteration32;
7483 CurScope, LastIteration.
get()->getExprLoc(), BO_Sub,
7484 LastIteration.
get(),
7494 LastIteration.
get()->isIntegerConstantExpr(Result, SemaRef.
Context);
7498 tryBuildCapture(SemaRef, LastIteration.
get(), Captures);
7499 LastIteration = SaveRef;
7503 CurScope, SaveRef.
get()->getExprLoc(), BO_Add, SaveRef.
get(),
7512 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
7539 buildVarDecl(SemaRef, InitLoc, StrideVType,
".omp.stride");
7548 UB.
get(), LastIteration.
get());
7550 LastIteration.
get()->getExprLoc(), InitLoc, IsUBGreater.
get(),
7551 LastIteration.
get(), UB.
get());
7552 EUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, UB.
get(),
7577 CurScope, InitLoc, BO_GT, CombUB.
get(), LastIteration.
get());
7580 LastIteration.
get(), CombUB.
get());
7581 CombEUB = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.
get(),
7586 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
7590 "Unexpected number of parameters in loop combined directive");
7617 Init = SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
7628 SemaRef.
BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
7634 bool UseStrictCompare =
7636 llvm::all_of(IterSpaces, [](
const LoopIterationSpace &LIS) {
7637 return LIS.IsStrictCompare;
7643 if (UseStrictCompare) {
7646 .
BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
7656 UseStrictCompare ? BO_LT : BO_LE, IV.get(),
7658 : SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7659 NumIterations.
get());
7662 CombDistCond = SemaRef.
BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7663 NumIterations.
get());
7668 Expr *BoundCombUB = CombUB.
get();
7669 if (UseStrictCompare) {
7673 CurScope, CondLoc, BO_Add, BoundCombUB,
7681 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7682 IV.get(), BoundCombUB);
7687 SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
7691 Inc = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.
get());
7700 ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
7731 CombNextLB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.
get(),
7743 CombNextUB = SemaRef.
BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.
get(),
7757 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
7760 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
7761 assert(DistCond.
isUsable() &&
"distribute cond expr was not built");
7764 SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.
get());
7765 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
7766 DistInc = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
7770 assert(DistInc.isUsable() &&
"distribute inc expr was not built");
7778 DistEUBLoc, DistEUBLoc, IsUBGreater.
get(), PrevUB.
get(), UB.
get());
7779 PrevEUB = SemaRef.
BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.
get(),
7787 Expr *BoundPrevUB = PrevUB.
get();
7788 if (UseStrictCompare) {
7792 CurScope, CondLoc, BO_Add, BoundPrevUB,
7800 SemaRef.
BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7801 IV.get(), BoundPrevUB);
7805 bool HasErrors =
false;
7806 Built.
Counters.resize(NestedLoopCount);
7807 Built.
Inits.resize(NestedLoopCount);
7808 Built.
Updates.resize(NestedLoopCount);
7809 Built.
Finals.resize(NestedLoopCount);
7830 for (
unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7831 LoopIterationSpace &IS = IterSpaces[Cnt];
7838 for (
unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
7839 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.
get(),
7840 IterSpaces[K].NumIterations);
7845 if (Cnt + 1 < NestedLoopCount)
7846 Iter = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Div,
7859 if (Cnt + 1 < NestedLoopCount)
7860 Prod = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Mul,
7864 Acc = SemaRef.
BuildBinOp(CurScope, UpdLoc, BO_Sub,
7868 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
7870 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
7874 IS.CounterInit, IS.IsNonRectangularLB, Captures);
7875 if (!Init.isUsable()) {
7880 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
7881 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
7890 IS.CounterInit, IS.NumIterations, IS.CounterStep,
7891 IS.Subtract, IS.IsNonRectangularLB, &Captures);
7902 Built.
Counters[Cnt] = IS.CounterVar;
7904 Built.
Inits[Cnt] = Init.get();
7910 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
7912 Built.
Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
7914 Built.
Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
7931 Built.
PreCond = PreCond.get();
7936 Built.
LB = LB.
get();
7937 Built.
UB = UB.
get();
7938 Built.
IL = IL.
get();
7939 Built.
ST = ST.
get();
7941 Built.
NLB = NextLB.
get();
7942 Built.
NUB = NextUB.
get();
7957 return NestedLoopCount;
7961 auto CollapseClauses =
7962 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
7963 if (CollapseClauses.begin() != CollapseClauses.end())
7964 return (*CollapseClauses.begin())->getNumForLoops();
7969 auto OrderedClauses =
7970 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
7971 if (OrderedClauses.begin() != OrderedClauses.end())
7972 return (*OrderedClauses.begin())->getNumForLoops();
7977 const ArrayRef<OMPClause *> Clauses) {
7981 for (
const OMPClause *Clause : Clauses) {
7983 Safelen = cast<OMPSafelenClause>(Clause);
7985 Simdlen = cast<OMPSimdlenClause>(Clause);
7986 if (Safelen && Simdlen)
7990 if (Simdlen && Safelen) {
8010 if (SimdlenRes > SafelenRes) {
8012 diag::err_omp_wrong_simdlen_safelen_values)
8027 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8033 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
8034 if (NestedLoopCount == 0)
8037 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8038 "omp simd loop exprs were not built");
8040 if (!CurContext->isDependentContext()) {
8043 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8054 setFunctionHasBranchProtectedScope();
8066 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8072 AStmt, *
this, *
DSAStack, VarsWithImplicitDSA, B);
8073 if (NestedLoopCount == 0)
8076 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8077 "omp for loop exprs were not built");
8079 if (!CurContext->isDependentContext()) {
8082 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8090 setFunctionHasBranchProtectedScope();
8092 Clauses, AStmt, B,
DSAStack->isCancelRegion());
8101 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8105 unsigned NestedLoopCount =
8108 VarsWithImplicitDSA, B);
8109 if (NestedLoopCount == 0)
8112 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8113 "omp for simd loop exprs were not built");
8115 if (!CurContext->isDependentContext()) {
8118 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8129 setFunctionHasBranchProtectedScope();
8141 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8142 auto BaseStmt = AStmt;
8143 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8145 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8146 auto S =
C->children();
8147 if (S.begin() == S.end())
8151 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8152 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8154 Diag(SectionStmt->getBeginLoc(),
8155 diag::err_omp_sections_substmt_not_section);
8158 cast<OMPSectionDirective>(SectionStmt)
8159 ->setHasCancel(
DSAStack->isCancelRegion());
8166 setFunctionHasBranchProtectedScope();
8178 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8180 setFunctionHasBranchProtectedScope();
8194 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8196 setFunctionHasBranchProtectedScope();
8202 for (
const OMPClause *Clause : Clauses) {
8206 Copyprivate = Clause;
8207 if (Copyprivate && Nowait) {
8209 diag::err_omp_single_copyprivate_with_nowait);
8224 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8226 setFunctionHasBranchProtectedScope();
8237 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8239 bool ErrorFound =
false;
8242 bool DependentHint =
false;
8244 if (
C->getClauseKind() == OMPC_hint) {
8246 Diag(
C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
8249 Expr *E = cast<OMPHintClause>(
C)->getHint();
8252 DependentHint =
true;
8255 HintLoc =
C->getBeginLoc();
8261 const auto Pair =
DSAStack->getCriticalWithHint(DirName);
8262 if (Pair.first && DirName.
getName() && !DependentHint) {
8263 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
8264 Diag(StartLoc, diag::err_omp_critical_with_hint);
8266 Diag(HintLoc, diag::note_omp_critical_hint_here)
8267 << 0 << Hint.toString(10,
false);
8269 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
8270 if (
const auto *
C = Pair.first->getSingleClause<
OMPHintClause>()) {
8271 Diag(
C->getBeginLoc(), diag::note_omp_critical_hint_here)
8273 <<
C->getHint()->EvaluateKnownConstInt(Context).toString(
8276 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
8281 setFunctionHasBranchProtectedScope();
8285 if (!Pair.first && DirName.
getName() && !DependentHint)
8286 DSAStack->addCriticalWithHint(Dir, Hint);
8296 auto *CS = cast<CapturedStmt>(AStmt);
8307 unsigned NestedLoopCount =
8310 VarsWithImplicitDSA, B);
8311 if (NestedLoopCount == 0)
8314 assert((CurContext->isDependentContext() || B.
builtAll()) &&
8315 "omp parallel for loop exprs were not built");
8317 if (!CurContext->isDependentContext()) {
8320 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8328 setFunctionHasBranchProtectedScope();
8330 NestedLoopCount, Clauses, AStmt, B,
8340 auto *CS = cast<CapturedStmt>(AStmt);
8351 unsigned NestedLoopCount =
8354 VarsWithImplicitDSA, B);
8355 if (NestedLoopCount == 0)
8358 if (!CurContext->isDependentContext()) {
8361 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
8372 setFunctionHasBranchProtectedScope();
8374 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8384 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8385 auto *CS = cast<CapturedStmt>(AStmt);
8393 setFunctionHasBranchProtectedScope();
8406 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8407 auto BaseStmt = AStmt;
8408 while (
auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8410 if (
auto *
C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8411 auto S =
C->children();
8412 if (S.begin() == S.end())
8416 for (
Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8417 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8419 Diag(SectionStmt->getBeginLoc(),
8420 diag::err_omp_parallel_sections_substmt_not_section);
8423 cast<OMPSectionDirective>(SectionStmt)
8424 ->setHasCancel(
DSAStack->isCancelRegion());
8428 diag::err_omp_parallel_sections_not_compound_stmt);
8432 setFunctionHasBranchProtectedScope();
8435 Context, StartLoc, EndLoc, Clauses, AStmt,
DSAStack->isCancelRegion());
8444 auto *CS = cast<CapturedStmt>(AStmt);
8452 setFunctionHasBranchProtectedScope();
8480 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8482 setFunctionHasBranchProtectedScope();
8486 DSAStack->getTaskgroupReductionRef());
8492 assert(Clauses.size() <= 1 &&
"Extra clauses in flush directive");
8501 const OMPClause *DependSourceClause =
nullptr;
8502 const OMPClause *DependSinkClause =
nullptr;
8503 bool ErrorFound =
false;
8507 if (
auto *DC = dyn_cast<OMPDependClause>(
C)) {
8509 if (DC->getDependencyKind() == OMPC_DEPEND_source) {
8510 if (DependSourceClause) {
8511 Diag(
C->getBeginLoc(), diag::err_omp_more_one_clause)
8512 << getOpenMPDirectiveName(OMPD_ordered)
8516 DependSourceClause =
C;
8518 if (DependSinkClause) {
8519 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8523 }
else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
8524 if (DependSourceClause) {
8525 Diag(
C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8529 DependSinkClause =
C;
8531 }
else if (
C->getClauseKind() == OMPC_threads) {
8532 TC = cast<OMPThreadsClause>(
C);
8533 }
else if (
C->getClauseKind() == OMPC_simd) {
8534 SC = cast<OMPSIMDClause>(
C);
8537 if (!ErrorFound && !SC &&
8542 Diag(StartLoc, diag::err_omp_prohibited_region_simd)
8543 << (LangOpts.OpenMP >= 50 ? 1 : 0);
8545 }
else if (DependFound && (TC || SC)) {
8546 Diag(DependFound->
getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
8549 }
else if (DependFound && !
DSAStack->getParentOrderedRegionParam().first) {
8551 diag::err_omp_ordered_directive_without_param);
8553 }
else if (TC || Clauses.empty()) {
8554 if (
const Expr *Param =
DSAStack->getParentOrderedRegionParam().first) {
8556 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
8558 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
8562 if ((!AStmt && !DependFound) || ErrorFound)
8566 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
8568 setFunctionHasBranchProtectedScope();
8577 class OpenMPAtomicUpdateChecker {
8579 enum ExprAnalysisErrorCode {
8583 NotABinaryOrUnaryExpression,
8585 NotAnUnaryIncDecExpression,
8591 NotABinaryExpression,
8597 NotAnUpdateExpression,
8615 bool IsXLHSInRHSPart;
8620 bool IsPostfixUpdate;
8623 OpenMPAtomicUpdateChecker(
Sema &SemaRef)
8624 : SemaRef(SemaRef),
X(
nullptr), E(
nullptr), UpdateExpr(
nullptr),
8625 IsXLHSInRHSPart(
false), Op(BO_PtrMemD), IsPostfixUpdate(
false) {}
8633 bool checkStatement(
Stmt *S,
unsigned DiagId = 0,
unsigned NoteId = 0);
8635 Expr *getX()
const {
return X; }
8637 Expr *getExpr()
const {
return E; }
8641 Expr *getUpdateExpr()
const {
return UpdateExpr; }
8644 bool isXLHSInRHSPart()
const {
return IsXLHSInRHSPart; }
8648 bool isPostfixUpdate()
const {
return IsPostfixUpdate; }
8651 bool checkBinaryOperation(
BinaryOperator *AtomicBinOp,
unsigned DiagId = 0,
8652 unsigned NoteId = 0);
8656 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
8658 ExprAnalysisErrorCode ErrorFound = NoError;
8664 if (AtomicBinOp->
getOpcode() == BO_Assign) {
8666 if (
const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
8668 if (AtomicInnerBinOp->isMultiplicativeOp() ||
8669 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
8670 AtomicInnerBinOp->isBitwiseOp()) {
8671 Op = AtomicInnerBinOp->getOpcode();
8672 OpLoc = AtomicInnerBinOp->getOperatorLoc();
8673 Expr *LHS = AtomicInnerBinOp->getLHS();
8674 Expr *RHS = AtomicInnerBinOp->getRHS();
8675 llvm::FoldingSetNodeID XId, LHSId, RHSId;
8684 IsXLHSInRHSPart =
true;
8685 }
else if (XId == RHSId) {
8687 IsXLHSInRHSPart =
false;
8689 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8690 ErrorRange = AtomicInnerBinOp->getSourceRange();
8691 NoteLoc =
X->getExprLoc();
8692 NoteRange =
X->getSourceRange();
8693 ErrorFound = NotAnUpdateExpression;
8696 ErrorLoc = AtomicInnerBinOp->getExprLoc();
8697 ErrorRange = AtomicInnerBinOp->getSourceRange();
8698 NoteLoc = AtomicInnerBinOp->getOperatorLoc();
8700 ErrorFound = NotABinaryOperator;
8705 ErrorFound = NotABinaryExpression;
8712 ErrorFound = NotAnAssignmentOp;
8714 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8715 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
8716 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8720 E =
X = UpdateExpr =
nullptr;
8721 return ErrorFound != NoError;
8724 bool OpenMPAtomicUpdateChecker::checkStatement(
Stmt *S,
unsigned DiagId,
8726 ExprAnalysisErrorCode ErrorFound = NoError;
8737 if (
auto *AtomicBody = dyn_cast<Expr>(S)) {
8738 AtomicBody = AtomicBody->IgnoreParenImpCasts();
8739 if (AtomicBody->getType()->isScalarType() ||
8740 AtomicBody->isInstantiationDependent()) {
8741 if (
const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
8742 AtomicBody->IgnoreParenImpCasts())) {
8745 AtomicCompAssignOp->getOpcode());
8746 OpLoc = AtomicCompAssignOp->getOperatorLoc();
8747 E = AtomicCompAssignOp->getRHS();
8748 X = AtomicCompAssignOp->getLHS()->IgnoreParens();
8749 IsXLHSInRHSPart =
true;
8750 }
else if (
auto *AtomicBinOp = dyn_cast<BinaryOperator>(
8751 AtomicBody->IgnoreParenImpCasts())) {
8753 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
8755 }
else if (
const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
8756 AtomicBody->IgnoreParenImpCasts())) {
8758 if (AtomicUnaryOp->isIncrementDecrementOp()) {
8759 IsPostfixUpdate = AtomicUnaryOp->isPostfix();
8760 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
8761 OpLoc = AtomicUnaryOp->getOperatorLoc();
8762 X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
8764 IsXLHSInRHSPart =
true;
8766 ErrorFound = NotAnUnaryIncDecExpression;
8767 ErrorLoc = AtomicUnaryOp->getExprLoc();
8768 ErrorRange = AtomicUnaryOp->getSourceRange();
8769 NoteLoc = AtomicUnaryOp->getOperatorLoc();
8772 }
else if (!AtomicBody->isInstantiationDependent()) {
8773 ErrorFound = NotABinaryOrUnaryExpression;
8774 NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
8775 NoteRange = ErrorRange = AtomicBody->getSourceRange();
8778 ErrorFound = NotAScalarType;
8779 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
8780 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
8783 ErrorFound = NotAnExpression;
8785 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
8787 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8788 SemaRef.
Diag(ErrorLoc, DiagId) << ErrorRange;
8789 SemaRef.
Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8793 E =
X = UpdateExpr =
nullptr;
8794 if (ErrorFound == NoError && E &&
X) {
8804 IsXLHSInRHSPart ? OVEExpr : OVEX);
8811 UpdateExpr = Update.
get();
8813 return ErrorFound != NoError;
8823 auto *CS = cast<CapturedStmt>(AStmt);
8832 if (
C->getClauseKind() == OMPC_read ||
C->getClauseKind() == OMPC_write ||
8833 C->getClauseKind() == OMPC_update ||
8834 C->getClauseKind() == OMPC_capture) {
8836 Diag(
C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
8838 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
8841 AtomicKind =
C->getClauseKind();
8842 AtomicKindLoc =
C->getBeginLoc();
8848 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Body))
8849 Body = EWC->getSubExpr();
8855 bool IsXLHSInRHSPart =
false;
8856 bool IsPostfixUpdate =
false;
8879 if (AtomicKind == OMPC_read) {
8886 } ErrorFound = NoError;
8891 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8892 const auto *AtomicBinOp =
8894 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
8901 ErrorFound = NotAnLValue;
8909 const Expr *NotScalarExpr =
8913 ErrorFound = NotAScalarType;
8919 }
else if (!AtomicBody->isInstantiationDependent()) {
8920 ErrorFound = NotAnAssignmentOp;
8921 ErrorLoc = AtomicBody->getExprLoc();
8922 ErrorRange = AtomicBody->getSourceRange();
8924 : AtomicBody->getExprLoc();
8926 : AtomicBody->getSourceRange();
8929 ErrorFound = NotAnExpression;
8931 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
8933 if (ErrorFound != NoError) {
8934 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
8936 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8940 if (CurContext->isDependentContext())
8942 }
else if (AtomicKind == OMPC_write) {
8949 } ErrorFound = NoError;
8954 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8955 const auto *AtomicBinOp =
8957 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
8958 X = AtomicBinOp->
getLHS();
8959 E = AtomicBinOp->
getRHS();
8963 ErrorFound = NotAnLValue;
8971 const Expr *NotScalarExpr =
8975 ErrorFound = NotAScalarType;
8981 }
else if (!AtomicBody->isInstantiationDependent()) {
8982 ErrorFound = NotAnAssignmentOp;
8983 ErrorLoc = AtomicBody->getExprLoc();
8984 ErrorRange = AtomicBody->getSourceRange();
8986 : AtomicBody->getExprLoc();
8988 : AtomicBody->getSourceRange();
8991 ErrorFound = NotAnExpression;
8993 NoteRange = ErrorRange =
SourceRange(NoteLoc, NoteLoc);
8995 if (ErrorFound != NoError) {
8996 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
8998 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
9002 if (CurContext->isDependentContext())
9004 }
else if (AtomicKind == OMPC_update || AtomicKind ==
OMPC_unknown) {
9013 OpenMPAtomicUpdateChecker Checker(*
this);
9014 if (Checker.checkStatement(
9015 Body, (AtomicKind == OMPC_update)
9016 ? diag::err_omp_atomic_update_not_expression_statement
9017 : diag::err_omp_atomic_not_expression_statement,
9018 diag::note_omp_atomic_update))
9020 if (!CurContext->isDependentContext()) {
9021 E = Checker.getExpr();
9023 UE = Checker.getUpdateExpr();
9024 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9026 }
else if (AtomicKind == OMPC_capture) {
9029 NotACompoundStatement,
9030 NotTwoSubstatements,
9031 NotASpecificExpression,
9033 } ErrorFound = NoError;
9036 if (
const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9045 const auto *AtomicBinOp =
9047 if (AtomicBinOp && AtomicBinOp->
getOpcode() == BO_Assign) {
9048 V = AtomicBinOp->
getLHS();
9050 OpenMPAtomicUpdateChecker Checker(*
this);
9051 if (Checker.checkStatement(
9052 Body, diag::err_omp_atomic_capture_not_expression_statement,
9053 diag::note_omp_atomic_update))
9055 E = Checker.getExpr();
9057 UE = Checker.getUpdateExpr();
9058 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9059 IsPostfixUpdate = Checker.isPostfixUpdate();
9060 }
else if (!AtomicBody->isInstantiationDependent()) {
9061 ErrorLoc = AtomicBody->getExprLoc();
9062 ErrorRange = AtomicBody->getSourceRange();
9064 : AtomicBody->getExprLoc();
9066 : AtomicBody->getSourceRange();
9067 ErrorFound = NotAnAssignmentOp;
9069 if (ErrorFound != NoError) {
9070 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
9072 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9075 if (CurContext->isDependentContext())
9076 UE = V = E = X =
nullptr;
9094 if (
auto *CS = dyn_cast<CompoundStmt>(Body)) {
9096 if (CS->size() == 2) {
9098 Stmt *Second = CS->body_back();
9099 if (
auto *EWC = dyn_cast<ExprWithCleanups>(First))
9100 First = EWC->getSubExpr()->IgnoreParenImpCasts();
9101 if (
auto *EWC = dyn_cast<ExprWithCleanups>(Second))
9102 Second = EWC->getSubExpr()->IgnoreParenImpCasts();
9104 OpenMPAtomicUpdateChecker Checker(*
this);
9105 bool IsUpdateExprFound = !Checker.checkStatement(Second);
9107 if (IsUpdateExprFound) {
9109 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
9111 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9121 llvm::FoldingSetNodeID XId, PossibleXId;
9122 Checker.getX()->Profile(XId, Context,
true);
9123 PossibleX->
Profile(PossibleXId, Context,
true);
9124 IsUpdateExprFound = XId == PossibleXId;
9125 if (IsUpdateExprFound) {
9128 E = Checker.getExpr();
9129 UE = Checker.getUpdateExpr();
9130 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9131 IsPostfixUpdate =
true;
9134 if (!IsUpdateExprFound) {
9135 IsUpdateExprFound = !Checker.checkStatement(First);
9137 if (IsUpdateExprFound) {
9139 IsUpdateExprFound = BinOp && BinOp->
getOpcode() == BO_Assign;
9141 if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9151 llvm::FoldingSetNodeID XId, PossibleXId;
9152 Checker.getX()->Profile(XId, Context,
true);
9153 PossibleX->
Profile(PossibleXId, Context,
true);
9154 IsUpdateExprFound = XId == PossibleXId;
9155 if (IsUpdateExprFound) {
9158 E = Checker.getExpr();
9159 UE = Checker.getUpdateExpr();
9160 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9161 IsPostfixUpdate =
false;
9165 if (!IsUpdateExprFound) {
9167 auto *FirstExpr = dyn_cast<
Expr>(
First);
9168 auto *SecondExpr = dyn_cast<
Expr>(Second);
9169 if (!FirstExpr || !SecondExpr ||
9170 !(FirstExpr->isInstantiationDependent() ||
9171 SecondExpr->isInstantiationDependent())) {
9173 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
9174 ErrorFound = NotAnAssignmentOp;
9175 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
9177 NoteRange = ErrorRange = FirstBinOp
9178 ? FirstBinOp->getSourceRange()
9182 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
9183 ErrorFound = NotAnAssignmentOp;
9184 NoteLoc = ErrorLoc = SecondBinOp
9185 ? SecondBinOp->getOperatorLoc()
9187 NoteRange = ErrorRange =
9188 SecondBinOp ? SecondBinOp->getSourceRange()
9191 Expr *PossibleXRHSInFirst =
9193 Expr *PossibleXLHSInSecond =
9195 llvm::FoldingSetNodeID X1Id, X2Id;
9196 PossibleXRHSInFirst->
Profile(X1Id, Context,
9198 PossibleXLHSInSecond->
Profile(X2Id, Context,
9200 IsUpdateExprFound = X1Id == X2Id;
9201 if (IsUpdateExprFound) {
9202 V = FirstBinOp->getLHS();
9203 X = SecondBinOp->getLHS();
9204 E = SecondBinOp->getRHS();
9206 IsXLHSInRHSPart =
false;
9207 IsPostfixUpdate =
true;
9209 ErrorFound = NotASpecificExpression;
9210 ErrorLoc = FirstBinOp->getExprLoc();
9211 ErrorRange = FirstBinOp->getSourceRange();
9212 NoteLoc = SecondBinOp->getLHS()->getExprLoc();
9213 NoteRange = SecondBinOp->getRHS()->getSourceRange();
9221 NoteRange = ErrorRange =
9223 ErrorFound = NotTwoSubstatements;
9227 NoteRange = ErrorRange =
9229 ErrorFound = NotACompoundStatement;
9231 if (ErrorFound != NoError) {
9232 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
9234 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9237 if (CurContext->isDependentContext())
9238 UE = V = E = X =
nullptr;
9242 setFunctionHasBranchProtectedScope();
9245 X, V, E, UE, IsXLHSInRHSPart,
9256 auto *CS = cast<CapturedStmt>(AStmt);
9263 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
9264 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9278 if (
DSAStack->hasInnerTeamsRegion()) {
9280 bool OMPTeamsFound =
true;
9281 if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
9282 auto I = CS->body_begin();
9283 while (I != CS->body_end()) {
9288 OMPTeamsFound =
false;
9293 assert(I != CS->body_end() &&
"Not found statement");
9299 if (!OMPTeamsFound) {
9300 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
9302 diag::note_omp_nested_teams_construct_here);
9304 << isa<OMPExecutableDirective>(S);
9309 setFunctionHasBranchProtectedScope();
9321 auto *CS = cast<CapturedStmt>(AStmt);
9328 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
9329 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9339 setFunctionHasBranchProtectedScope();
9351 auto *CS = cast<CapturedStmt>(AStmt);
9358 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
9359 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9372 unsigned NestedLoopCount =
9375 VarsWithImplicitDSA, B);
9376 if (NestedLoopCount == 0)
9379 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9380 "omp target parallel for loop exprs were not built");
9382 if (!CurContext->isDependentContext()) {
9385 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9393 setFunctionHasBranchProtectedScope();
9395 NestedLoopCount, Clauses, AStmt,
9402 return llvm::any_of(
9406 template <
typename... Params>
9408 const Params... ClauseTypes) {
9419 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9423 if (!
hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
9424 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9425 <<
"'map' or 'use_device_ptr'" 9426 << getOpenMPDirectiveName(OMPD_target_data);
9430 setFunctionHasBranchProtectedScope();
9443 auto *CS = cast<CapturedStmt>(AStmt);
9450 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
9451 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9464 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9465 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
9480 auto *CS = cast<CapturedStmt>(AStmt);
9487 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
9488 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9501 Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9502 <<
"'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
9517 auto *CS = cast<CapturedStmt>(AStmt);
9524 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
9525 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9535 if (!
hasClauses(Clauses, OMPC_to, OMPC_from)) {
9536 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
9549 auto *CS = cast<CapturedStmt>(AStmt);
9557 setFunctionHasBranchProtectedScope();
9559 DSAStack->setParentTeamsRegionLoc(StartLoc);
9568 if (
DSAStack->isParentNowaitRegion()) {
9569 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
9572 if (
DSAStack->isParentOrderedRegion()) {
9573 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
9584 if (
DSAStack->isParentNowaitRegion()) {
9585 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
9588 if (
DSAStack->isParentOrderedRegion()) {
9589 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
9592 DSAStack->setParentCancelRegion(
true);
9598 ArrayRef<OMPClause *> Clauses) {
9600 bool ErrorFound =
false;
9602 if (
C->getClauseKind() == OMPC_grainsize ||
9603 C->getClauseKind() == OMPC_num_tasks) {
9607 S.
Diag(
C->getBeginLoc(),
9608 diag::err_omp_grainsize_num_tasks_mutually_exclusive)
9612 diag::note_omp_previous_grainsize_num_tasks)
9622 ArrayRef<OMPClause *> Clauses) {
9623 const OMPClause *ReductionClause =
nullptr;
9624 const OMPClause *NogroupClause =
nullptr;
9626 if (
C->getClauseKind() == OMPC_reduction) {
9627 ReductionClause =
C;
9632 if (
C->getClauseKind() == OMPC_nogroup) {
9634 if (ReductionClause)
9639 if (ReductionClause && NogroupClause) {
9640 S.
Diag(ReductionClause->
getBeginLoc(), diag::err_omp_reduction_with_nogroup)
9654 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9658 unsigned NestedLoopCount =
9661 VarsWithImplicitDSA, B);
9662 if (NestedLoopCount == 0)
9665 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9666 "omp for loop exprs were not built");
9679 setFunctionHasBranchProtectedScope();
9681 NestedLoopCount, Clauses, AStmt, B);
9690 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9694 unsigned NestedLoopCount =
9697 VarsWithImplicitDSA, B);
9698 if (NestedLoopCount == 0)
9701 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9702 "omp for loop exprs were not built");
9704 if (!CurContext->isDependentContext()) {
9707 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9728 setFunctionHasBranchProtectedScope();
9730 NestedLoopCount, Clauses, AStmt, B);
9739 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9743 unsigned NestedLoopCount =
9746 VarsWithImplicitDSA, B);
9747 if (NestedLoopCount == 0)
9750 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9751 "omp for loop exprs were not built");
9764 setFunctionHasBranchProtectedScope();
9766 NestedLoopCount, Clauses, AStmt, B);
9775 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9779 unsigned NestedLoopCount =
9782 VarsWithImplicitDSA, B);
9783 if (NestedLoopCount == 0)
9786 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9787 "omp for loop exprs were not built");
9789 if (!CurContext->isDependentContext()) {
9792 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9813 setFunctionHasBranchProtectedScope();
9815 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9824 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9825 auto *CS = cast<CapturedStmt>(AStmt);
9832 for (
int ThisCaptureLevel =
9833 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
9834 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9850 VarsWithImplicitDSA, B);
9851 if (NestedLoopCount == 0)
9854 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9855 "omp for loop exprs were not built");
9868 setFunctionHasBranchProtectedScope();
9870 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9879 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9880 auto *CS = cast<CapturedStmt>(AStmt);
9887 for (
int ThisCaptureLevel =
9888 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
9889 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9905 VarsWithImplicitDSA, B);
9906 if (NestedLoopCount == 0)
9909 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9910 "omp for loop exprs were not built");
9912 if (!CurContext->isDependentContext()) {
9915 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
9936 setFunctionHasBranchProtectedScope();
9938 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9947 assert(isa<CapturedStmt>(AStmt) &&
"Captured statement expected");
9951 unsigned NestedLoopCount =
9954 *
this, *
DSAStack, VarsWithImplicitDSA, B);
9955 if (NestedLoopCount == 0)
9958 assert((CurContext->isDependentContext() || B.
builtAll()) &&
9959 "omp for loop exprs were not built");
9961 setFunctionHasBranchProtectedScope();
9963 NestedLoopCount, Clauses, AStmt, B);
9972 auto *CS = cast<CapturedStmt>(AStmt);
9979 for (
int ThisCaptureLevel =
9980 getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
9981 ThisCaptureLevel > 1; --ThisCaptureLevel) {
9997 VarsWithImplicitDSA, B);
9998 if (NestedLoopCount == 0)
10001 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10002 "omp for loop exprs were not built");
10004 setFunctionHasBranchProtectedScope();
10006 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10016 auto *CS = cast<CapturedStmt>(AStmt);
10023 for (
int ThisCaptureLevel =
10024 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10025 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10041 VarsWithImplicitDSA, B);
10042 if (NestedLoopCount == 0)
10045 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10046 "omp for loop exprs were not built");
10048 if (!CurContext->isDependentContext()) {
10051 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10062 setFunctionHasBranchProtectedScope();
10064 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10073 auto *CS = cast<CapturedStmt>(AStmt);
10080 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
10081 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10094 unsigned NestedLoopCount =
10096 nullptr , CS, *
this,
10097 *
DSAStack, VarsWithImplicitDSA, B);
10098 if (NestedLoopCount == 0)
10101 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10102 "omp for loop exprs were not built");
10104 if (!CurContext->isDependentContext()) {
10107 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10118 setFunctionHasBranchProtectedScope();
10120 NestedLoopCount, Clauses, AStmt, B);
10129 auto *CS = cast<CapturedStmt>(AStmt);
10136 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10137 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10153 VarsWithImplicitDSA, B);
10154 if (NestedLoopCount == 0)
10157 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10158 "omp target parallel for simd loop exprs were not built");
10160 if (!CurContext->isDependentContext()) {
10163 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10173 setFunctionHasBranchProtectedScope();
10175 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10184 auto *CS = cast<CapturedStmt>(AStmt);
10191 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
10192 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10205 unsigned NestedLoopCount =
10208 VarsWithImplicitDSA, B);
10209 if (NestedLoopCount == 0)
10212 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10213 "omp target simd loop exprs were not built");
10215 if (!CurContext->isDependentContext()) {
10218 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10229 setFunctionHasBranchProtectedScope();
10231 NestedLoopCount, Clauses, AStmt, B);
10240 auto *CS = cast<CapturedStmt>(AStmt);
10247 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
10248 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10261 unsigned NestedLoopCount =
10263 nullptr , CS, *
this,
10264 *
DSAStack, VarsWithImplicitDSA, B);
10265 if (NestedLoopCount == 0)
10268 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10269 "omp teams distribute loop exprs were not built");
10271 setFunctionHasBranchProtectedScope();
10273 DSAStack->setParentTeamsRegionLoc(StartLoc);
10276 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10285 auto *CS = cast<CapturedStmt>(AStmt);
10292 for (
int ThisCaptureLevel =
10293 getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
10294 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10311 VarsWithImplicitDSA, B);
10313 if (NestedLoopCount == 0)
10316 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10317 "omp teams distribute simd loop exprs were not built");
10319 if (!CurContext->isDependentContext()) {
10322 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10333 setFunctionHasBranchProtectedScope();
10335 DSAStack->setParentTeamsRegionLoc(StartLoc);
10338 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10347 auto *CS = cast<CapturedStmt>(AStmt);
10355 for (
int ThisCaptureLevel =
10356 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
10357 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10373 VarsWithImplicitDSA, B);
10375 if (NestedLoopCount == 0)
10378 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10379 "omp for loop exprs were not built");
10381 if (!CurContext->isDependentContext()) {
10384 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10395 setFunctionHasBranchProtectedScope();
10397 DSAStack->setParentTeamsRegionLoc(StartLoc);
10400 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10409 auto *CS = cast<CapturedStmt>(AStmt);
10417 for (
int ThisCaptureLevel =
10418 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
10419 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10435 VarsWithImplicitDSA, B);
10437 if (NestedLoopCount == 0)
10440 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10441 "omp for loop exprs were not built");
10443 setFunctionHasBranchProtectedScope();
10445 DSAStack->setParentTeamsRegionLoc(StartLoc);
10448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10459 auto *CS = cast<CapturedStmt>(AStmt);
10467 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
10468 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10477 setFunctionHasBranchProtectedScope();
10489 auto *CS = cast<CapturedStmt>(AStmt);
10496 for (
int ThisCaptureLevel =
10497 getOpenMPCaptureLevels(OMPD_target_teams_distribute);
10498 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10514 VarsWithImplicitDSA, B);
10515 if (NestedLoopCount == 0)
10518 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10519 "omp target teams distribute loop exprs were not built");
10521 setFunctionHasBranchProtectedScope();
10523 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10532 auto *CS = cast<CapturedStmt>(AStmt);
10539 for (
int ThisCaptureLevel =
10540 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
10541 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10557 VarsWithImplicitDSA, B);
10558 if (NestedLoopCount == 0)
10561 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10562 "omp target teams distribute parallel for loop exprs were not built");
10564 if (!CurContext->isDependentContext()) {
10567 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10575 setFunctionHasBranchProtectedScope();
10577 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10587 auto *CS = cast<CapturedStmt>(AStmt);
10594 for (
int ThisCaptureLevel = getOpenMPCaptureLevels(
10595 OMPD_target_teams_distribute_parallel_for_simd);
10596 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10609 unsigned NestedLoopCount =
10612 nullptr , CS, *
this,
10613 *
DSAStack, VarsWithImplicitDSA, B);
10614 if (NestedLoopCount == 0)
10617 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10618 "omp target teams distribute parallel for simd loop exprs were not " 10621 if (!CurContext->isDependentContext()) {
10624 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10635 setFunctionHasBranchProtectedScope();
10637 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10646 auto *CS = cast<CapturedStmt>(AStmt);
10653 for (
int ThisCaptureLevel =
10654 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
10655 ThisCaptureLevel > 1; --ThisCaptureLevel) {
10671 VarsWithImplicitDSA, B);
10672 if (NestedLoopCount == 0)
10675 assert((CurContext->isDependentContext() || B.
builtAll()) &&
10676 "omp target teams distribute simd loop exprs were not built");
10678 if (!CurContext->isDependentContext()) {
10681 if (
auto *LC = dyn_cast<OMPLinearClause>(
C))
10692 setFunctionHasBranchProtectedScope();
10694 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10704 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
10706 case OMPC_num_threads:
10707 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
10710 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
10713 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
10715 case OMPC_allocator:
10716 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
10718 case OMPC_collapse:
10719 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
10722 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
10725 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
10727 case OMPC_num_teams:
10728 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
10730 case OMPC_thread_limit:
10731 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
10733 case OMPC_priority:
10734 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
10736 case OMPC_grainsize:
10737 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
10739 case OMPC_num_tasks:
10740 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
10743 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
10747 case OMPC_proc_bind:
10748 case OMPC_schedule:
10750 case OMPC_firstprivate:
10751 case OMPC_lastprivate:
10753 case OMPC_reduction:
10754 case OMPC_task_reduction:
10755 case OMPC_in_reduction:
10759 case OMPC_copyprivate:
10762 case OMPC_mergeable:
10764 case OMPC_allocate:
10776 case OMPC_dist_schedule:
10777 case OMPC_defaultmap:
10782 case OMPC_use_device_ptr:
10783 case OMPC_is_device_ptr:
10784 case OMPC_unified_address:
10785 case OMPC_unified_shared_memory:
10786 case OMPC_reverse_offload:
10787 case OMPC_dynamic_allocators:
10788 case OMPC_atomic_default_mem_order:
10791 case OMPC_nontemporal:
10792 llvm_unreachable(
"Clause is not allowed.");
10809 case OMPD_target_parallel_for_simd:
10810 if (OpenMPVersion >= 50 &&
10811 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10812 CaptureRegion = OMPD_parallel;
10816 case OMPD_target_parallel:
10817 case OMPD_target_parallel_for:
10820 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10821 CaptureRegion = OMPD_target;
10823 case OMPD_target_teams_distribute_parallel_for_simd:
10824 if (OpenMPVersion >= 50 &&
10825 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10826 CaptureRegion = OMPD_parallel;
10830 case OMPD_target_teams_distribute_parallel_for:
10833 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10834 CaptureRegion = OMPD_teams;
10836 case OMPD_teams_distribute_parallel_for_simd:
10837 if (OpenMPVersion >= 50 &&
10838 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10839 CaptureRegion = OMPD_parallel;
10843 case OMPD_teams_distribute_parallel_for:
10844 CaptureRegion = OMPD_teams;
10846 case OMPD_target_update:
10847 case OMPD_target_enter_data:
10848 case OMPD_target_exit_data:
10849 CaptureRegion = OMPD_task;
10851 case OMPD_parallel_master_taskloop:
10852 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
10853 CaptureRegion = OMPD_parallel;
10855 case OMPD_parallel_master_taskloop_simd:
10856 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
10857 NameModifier == OMPD_taskloop) {
10858 CaptureRegion = OMPD_parallel;
10861 if (OpenMPVersion <= 45)
10863 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10864 CaptureRegion = OMPD_taskloop;
10866 case OMPD_parallel_for_simd:
10867 if (OpenMPVersion <= 45)
10869 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10870 CaptureRegion = OMPD_parallel;
10872 case OMPD_taskloop_simd:
10873 case OMPD_master_taskloop_simd:
10874 if (OpenMPVersion <= 45)
10876 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10877 CaptureRegion = OMPD_taskloop;
10879 case OMPD_distribute_parallel_for_simd:
10880 if (OpenMPVersion <= 45)
10882 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10883 CaptureRegion = OMPD_parallel;
10885 case OMPD_target_simd:
10886 if (OpenMPVersion >= 50 &&
10887 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
10888 CaptureRegion = OMPD_target;
10890 case OMPD_teams_distribute_simd:
10891 case OMPD_target_teams_distribute_simd:
10892 if (OpenMPVersion >= 50 &&
10893 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
10894 CaptureRegion = OMPD_teams;
10897 case OMPD_parallel:
10898 case OMPD_parallel_master:
10899 case OMPD_parallel_sections:
10900 case OMPD_parallel_for:
10902 case OMPD_target_teams:
10903 case OMPD_target_teams_distribute:
10904 case OMPD_distribute_parallel_for:
10906 case OMPD_taskloop:
10907 case OMPD_master_taskloop:
10908 case OMPD_target_data:
10910 case OMPD_for_simd:
10911 case OMPD_distribute_simd:
10914 case OMPD_threadprivate:
10915 case OMPD_allocate:
10916 case OMPD_taskyield:
10918 case OMPD_taskwait:
10919 case OMPD_cancellation_point:
10921 case OMPD_declare_reduction:
10922 case OMPD_declare_mapper:
10923 case OMPD_declare_simd:
10924 case OMPD_declare_variant:
10925 case OMPD_declare_target:
10926 case OMPD_end_declare_target:
10929 case OMPD_sections:
10933 case OMPD_critical:
10934 case OMPD_taskgroup:
10935 case OMPD_distribute:
10938 case OMPD_teams_distribute:
10939 case OMPD_requires:
10940 llvm_unreachable(
"Unexpected OpenMP directive with if-clause");
10942 llvm_unreachable(
"Unknown OpenMP directive");
10945 case OMPC_num_threads:
10947 case OMPD_target_parallel:
10948 case OMPD_target_parallel_for:
10949 case OMPD_target_parallel_for_simd:
10950 CaptureRegion = OMPD_target;
10952 case OMPD_teams_distribute_parallel_for:
10953 case OMPD_teams_distribute_parallel_for_simd:
10954 case OMPD_target_teams_distribute_parallel_for:
10955 case OMPD_target_teams_distribute_parallel_for_simd:
10956 CaptureRegion = OMPD_teams;
10958 case OMPD_parallel:
10959 case OMPD_parallel_master:
10960 case OMPD_parallel_sections:
10961 case OMPD_parallel_for:
10962 case OMPD_parallel_for_simd:
10963 case OMPD_distribute_parallel_for:
10964 case OMPD_distribute_parallel_for_simd:
10965 case OMPD_parallel_master_taskloop:
10966 case OMPD_parallel_master_taskloop_simd:
10969 case OMPD_target_data:
10970 case OMPD_target_enter_data:
10971 case OMPD_target_exit_data:
10972 case OMPD_target_update:
10974 case OMPD_target_simd:
10975 case OMPD_target_teams:
10976 case OMPD_target_teams_distribute:
10977 case OMPD_target_teams_distribute_simd:
10980 case OMPD_taskloop:
10981 case OMPD_taskloop_simd:
10982 case OMPD_master_taskloop:
10983 case OMPD_master_taskloop_simd:
10984 case OMPD_threadprivate:
10985 case OMPD_allocate:
10986 case OMPD_taskyield:
10988 case OMPD_taskwait:
10989 case OMPD_cancellation_point:
10991 case OMPD_declare_reduction:
10992 case OMPD_declare_mapper:
10993 case OMPD_declare_simd:
10994 case OMPD_declare_variant:
10995 case OMPD_declare_target:
10996 case OMPD_end_declare_target:
11000 case OMPD_for_simd:
11001 case OMPD_sections:
11005 case OMPD_critical:
11006 case OMPD_taskgroup:
11007 case OMPD_distribute:
11010 case OMPD_distribute_simd:
11011 case OMPD_teams_distribute:
11012 case OMPD_teams_distribute_simd:
11013 case OMPD_requires:
11014 llvm_unreachable(
"Unexpected OpenMP directive with num_threads-clause");
11016 llvm_unreachable(
"Unknown OpenMP directive");
11019 case OMPC_num_teams:
11021 case OMPD_target_teams:
11022 case OMPD_target_teams_distribute:
11023 case OMPD_target_teams_distribute_simd:
11024 case OMPD_target_teams_distribute_parallel_for:
11025 case OMPD_target_teams_distribute_parallel_for_simd:
11026 CaptureRegion = OMPD_target;
11028 case OMPD_teams_distribute_parallel_for:
11029 case OMPD_teams_distribute_parallel_for_simd:
11031 case OMPD_teams_distribute:
11032 case OMPD_teams_distribute_simd:
11035 case OMPD_distribute_parallel_for:
11036 case OMPD_distribute_parallel_for_simd:
11038 case OMPD_taskloop:
11039 case OMPD_taskloop_simd:
11040 case OMPD_master_taskloop:
11041 case OMPD_master_taskloop_simd:
11042 case OMPD_parallel_master_taskloop:
11043 case OMPD_parallel_master_taskloop_simd:
11044 case OMPD_target_data:
11045 case OMPD_target_enter_data:
11046 case OMPD_target_exit_data:
11047 case OMPD_target_update:
11049 case OMPD_parallel:
11050 case OMPD_parallel_master:
11051 case OMPD_parallel_sections:
11052 case OMPD_parallel_for:
11053 case OMPD_parallel_for_simd:
11055 case OMPD_target_simd:
11056 case OMPD_target_parallel:
11057 case OMPD_target_parallel_for:
11058 case OMPD_target_parallel_for_simd:
11059 case OMPD_threadprivate:
11060 case OMPD_allocate:
11061 case OMPD_taskyield:
11063 case OMPD_taskwait:
11064 case OMPD_cancellation_point:
11066 case OMPD_declare_reduction:
11067 case OMPD_declare_mapper:
11068 case OMPD_declare_simd:
11069 case OMPD_declare_variant:
11070 case OMPD_declare_target:
11071 case OMPD_end_declare_target:
11074 case OMPD_for_simd:
11075 case OMPD_sections:
11079 case OMPD_critical:
11080 case OMPD_taskgroup:
11081 case OMPD_distribute:
11084 case OMPD_distribute_simd:
11085 case OMPD_requires:
11086 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
11088 llvm_unreachable(
"Unknown OpenMP directive");
11091 case OMPC_thread_limit:
11093 case OMPD_target_teams:
11094 case OMPD_target_teams_distribute:
11095 case OMPD_target_teams_distribute_simd:
11096 case OMPD_target_teams_distribute_parallel_for:
11097 case OMPD_target_teams_distribute_parallel_for_simd:
11098 CaptureRegion = OMPD_target;
11100 case OMPD_teams_distribute_parallel_for:
11101 case OMPD_teams_distribute_parallel_for_simd:
11103 case OMPD_teams_distribute:
11104 case OMPD_teams_distribute_simd:
11107 case OMPD_distribute_parallel_for:
11108 case OMPD_distribute_parallel_for_simd:
11110 case OMPD_taskloop:
11111 case OMPD_taskloop_simd:
11112 case OMPD_master_taskloop:
11113 case OMPD_master_taskloop_simd:
11114 case OMPD_parallel_master_taskloop:
11115 case OMPD_parallel_master_taskloop_simd:
11116 case OMPD_target_data:
11117 case OMPD_target_enter_data:
11118 case OMPD_target_exit_data:
11119 case OMPD_target_update:
11121 case OMPD_parallel:
11122 case OMPD_parallel_master:
11123 case OMPD_parallel_sections:
11124 case OMPD_parallel_for:
11125 case OMPD_parallel_for_simd:
11127 case OMPD_target_simd:
11128 case OMPD_target_parallel:
11129 case OMPD_target_parallel_for:
11130 case OMPD_target_parallel_for_simd:
11131 case OMPD_threadprivate:
11132 case OMPD_allocate:
11133 case OMPD_taskyield:
11135 case OMPD_taskwait:
11136 case OMPD_cancellation_point:
11138 case OMPD_declare_reduction:
11139 case OMPD_declare_mapper:
11140 case OMPD_declare_simd:
11141 case OMPD_declare_variant:
11142 case OMPD_declare_target:
11143 case OMPD_end_declare_target:
11146 case OMPD_for_simd:
11147 case OMPD_sections:
11151 case OMPD_critical:
11152 case OMPD_taskgroup:
11153 case OMPD_distribute:
11156 case OMPD_distribute_simd:
11157 case OMPD_requires:
11158 llvm_unreachable(
"Unexpected OpenMP directive with thread_limit-clause");
11160 llvm_unreachable(
"Unknown OpenMP directive");
11163 case OMPC_schedule:
11165 case OMPD_parallel_for:
11166 case OMPD_parallel_for_simd:
11167 case OMPD_distribute_parallel_for:
11168 case OMPD_distribute_parallel_for_simd:
11169 case OMPD_teams_distribute_parallel_for:
11170 case OMPD_teams_distribute_parallel_for_simd:
11171 case OMPD_target_parallel_for:
11172 case OMPD_target_parallel_for_simd:
11173 case OMPD_target_teams_distribute_parallel_for:
11174 case OMPD_target_teams_distribute_parallel_for_simd:
11175 CaptureRegion = OMPD_parallel;
11178 case OMPD_for_simd:
11182 case OMPD_taskloop:
11183 case OMPD_taskloop_simd:
11184 case OMPD_master_taskloop:
11185 case OMPD_master_taskloop_simd:
11186 case OMPD_parallel_master_taskloop:
11187 case OMPD_parallel_master_taskloop_simd:
11188 case OMPD_target_data:
11189 case OMPD_target_enter_data:
11190 case OMPD_target_exit_data:
11191 case OMPD_target_update:
11193 case OMPD_teams_distribute:
11194 case OMPD_teams_distribute_simd:
11195 case OMPD_target_teams_distribute:
11196 case OMPD_target_teams_distribute_simd:
11198 case OMPD_target_simd:
11199 case OMPD_target_parallel:
11201 case OMPD_parallel:
11202 case OMPD_parallel_master:
11203 case OMPD_parallel_sections:
11204 case OMPD_threadprivate:
11205 case OMPD_allocate:
11206 case OMPD_taskyield:
11208 case OMPD_taskwait:
11209 case OMPD_cancellation_point:
11211 case OMPD_declare_reduction:
11212 case OMPD_declare_mapper:
11213 case OMPD_declare_simd:
11214 case OMPD_declare_variant:
11215 case OMPD_declare_target:
11216 case OMPD_end_declare_target:
11218 case OMPD_sections:
11222 case OMPD_critical:
11223 case OMPD_taskgroup:
11224 case OMPD_distribute:
11227 case OMPD_distribute_simd:
11228 case OMPD_target_teams:
11229 case OMPD_requires:
11230 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
11232 llvm_unreachable(
"Unknown OpenMP directive");
11235 case OMPC_dist_schedule:
11237 case OMPD_teams_distribute_parallel_for:
11238 case OMPD_teams_distribute_parallel_for_simd:
11239 case OMPD_teams_distribute:
11240 case OMPD_teams_distribute_simd:
11241 case OMPD_target_teams_distribute_parallel_for:
11242 case OMPD_target_teams_distribute_parallel_for_simd:
11243 case OMPD_target_teams_distribute:
11244 case OMPD_target_teams_distribute_simd:
11245 CaptureRegion = OMPD_teams;
11247 case OMPD_distribute_parallel_for:
11248 case OMPD_distribute_parallel_for_simd:
11249 case OMPD_distribute:
11250 case OMPD_distribute_simd:
11253 case OMPD_parallel_for:
11254 case OMPD_parallel_for_simd:
11255 case OMPD_target_parallel_for_simd:
11256 case OMPD_target_parallel_for:
11258 case OMPD_taskloop:
11259 case OMPD_taskloop_simd:
11260 case OMPD_master_taskloop:
11261 case OMPD_master_taskloop_simd:
11262 case OMPD_parallel_master_taskloop:
11263 case OMPD_parallel_master_taskloop_simd:
11264 case OMPD_target_data:
11265 case OMPD_target_enter_data:
11266 case OMPD_target_exit_data:
11267 case OMPD_target_update:
11270 case OMPD_target_simd:
11271 case OMPD_target_parallel:
11273 case OMPD_parallel:
11274 case OMPD_parallel_master:
11275 case OMPD_parallel_sections:
11276 case OMPD_threadprivate:
11277 case OMPD_allocate:
11278 case OMPD_taskyield:
11280 case OMPD_taskwait:
11281 case OMPD_cancellation_point:
11283 case OMPD_declare_reduction:
11284 case OMPD_declare_mapper:
11285 case OMPD_declare_simd:
11286 case OMPD_declare_variant:
11287 case OMPD_declare_target:
11288 case OMPD_end_declare_target:
11291 case OMPD_for_simd:
11292 case OMPD_sections:
11296 case OMPD_critical:
11297 case OMPD_taskgroup:
11300 case OMPD_target_teams:
11301 case OMPD_requires:
11302 llvm_unreachable(
"Unexpected OpenMP directive with schedule clause");
11304 llvm_unreachable(
"Unknown OpenMP directive");
11309 case OMPD_target_update:
11310 case OMPD_target_enter_data:
11311 case OMPD_target_exit_data:
11313 case OMPD_target_simd:
11314 case OMPD_target_teams:
11315 case OMPD_target_parallel:
11316 case OMPD_target_teams_distribute:
11317 case OMPD_target_teams_distribute_simd:
11318 case OMPD_target_parallel_for:
11319 case OMPD_target_parallel_for_simd:
11320 case OMPD_target_teams_distribute_parallel_for:
11321 case OMPD_target_teams_distribute_parallel_for_simd:
11322 CaptureRegion = OMPD_task;
11324 case OMPD_target_data:
11327 case OMPD_teams_distribute_parallel_for:
11328 case OMPD_teams_distribute_parallel_for_simd:
11330 case OMPD_teams_distribute:
11331 case OMPD_teams_distribute_simd:
11332 case OMPD_distribute_parallel_for:
11333 case OMPD_distribute_parallel_for_simd:
11335 case OMPD_taskloop:
11336 case OMPD_taskloop_simd:
11337 case OMPD_master_taskloop:
11338 case OMPD_master_taskloop_simd:
11339 case OMPD_parallel_master_taskloop:
11340 case OMPD_parallel_master_taskloop_simd:
11342 case OMPD_parallel:
11343 case OMPD_parallel_master:
11344 case OMPD_parallel_sections:
11345 case OMPD_parallel_for:
11346 case OMPD_parallel_for_simd:
11347 case OMPD_threadprivate:
11348 case OMPD_allocate:
11349 case OMPD_taskyield:
11351 case OMPD_taskwait:
11352 case OMPD_cancellation_point:
11354 case OMPD_declare_reduction:
11355 case OMPD_declare_mapper:
11356 case OMPD_declare_simd:
11357 case OMPD_declare_variant:
11358 case OMPD_declare_target:
11359 case OMPD_end_declare_target:
11362 case OMPD_for_simd:
11363 case OMPD_sections:
11367 case OMPD_critical:
11368 case OMPD_taskgroup:
11369 case OMPD_distribute:
11372 case OMPD_distribute_simd:
11373 case OMPD_requires:
11374 llvm_unreachable(
"Unexpected OpenMP directive with num_teams-clause");
11376 llvm_unreachable(
"Unknown OpenMP directive");
11379 case OMPC_grainsize:
11380 case OMPC_num_tasks:
11382 case OMPC_priority:
11385 case OMPD_taskloop:
11386 case OMPD_taskloop_simd:
11387 case OMPD_master_taskloop:
11388 case OMPD_master_taskloop_simd:
11390 case OMPD_parallel_master_taskloop:
11391 case OMPD_parallel_master_taskloop_simd:
11392 CaptureRegion = OMPD_parallel;
11394 case OMPD_target_update:
11395 case OMPD_target_enter_data:
11396 case OMPD_target_exit_data:
11398 case OMPD_target_simd:
11399 case OMPD_target_teams:
11400 case OMPD_target_parallel:
11401 case OMPD_target_teams_distribute:
11402 case OMPD_target_teams_distribute_simd:
11403 case OMPD_target_parallel_for:
11404 case OMPD_target_parallel_for_simd:
11405 case OMPD_target_teams_distribute_parallel_for:
11406 case OMPD_target_teams_distribute_parallel_for_simd:
11407 case OMPD_target_data:
11408 case OMPD_teams_distribute_parallel_for:
11409 case OMPD_teams_distribute_parallel_for_simd:
11411 case OMPD_teams_distribute:
11412 case OMPD_teams_distribute_simd:
11413 case OMPD_distribute_parallel_for:
11414 case OMPD_distribute_parallel_for_simd:
11416 case OMPD_parallel:
11417 case OMPD_parallel_master:
11418 case OMPD_parallel_sections:
11419 case OMPD_parallel_for:
11420 case OMPD_parallel_for_simd:
11421 case OMPD_threadprivate:
11422 case OMPD_allocate:
11423 case OMPD_taskyield:
11425 case OMPD_taskwait:
11426 case OMPD_cancellation_point:
11428 case OMPD_declare_reduction:
11429 case OMPD_declare_mapper:
11430 case OMPD_declare_simd:
11431 case OMPD_declare_variant:
11432 case OMPD_declare_target:
11433 case OMPD_end_declare_target:
11436 case OMPD_for_simd:
11437 case OMPD_sections:
11441 case OMPD_critical:
11442 case OMPD_taskgroup:
11443 case OMPD_distribute:
11446 case OMPD_distribute_simd:
11447 case OMPD_requires:
11448 llvm_unreachable(
"Unexpected OpenMP directive with grainsize-clause");
11450 llvm_unreachable(
"Unknown OpenMP directive");
11453 case OMPC_firstprivate:
11454 case OMPC_lastprivate:
11455 case OMPC_reduction:
11456 case OMPC_task_reduction:
11457 case OMPC_in_reduction:
11460 case OMPC_proc_bind:
11463 case OMPC_allocator:
11464 case OMPC_collapse:
11469 case OMPC_copyprivate:
11473 case OMPC_mergeable:
11475 case OMPC_allocate:
11488 case OMPC_defaultmap:
11493 case OMPC_use_device_ptr:
11494 case OMPC_is_device_ptr:
11495 case OMPC_unified_address:
11496 case OMPC_unified_shared_memory:
11497 case OMPC_reverse_offload:
11498 case OMPC_dynamic_allocators:
11499 case OMPC_atomic_default_mem_order:
11502 case OMPC_nontemporal:
11503 llvm_unreachable(
"Unexpected OpenMP clause.");
11505 return CaptureRegion;
11514 Expr *ValExpr = Condition;
11515 Stmt *HelperValStmt =
nullptr;
11520 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11524 ValExpr = Val.
get();
11528 DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
11529 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11530 ValExpr = MakeFullExpr(ValExpr).get();
11531 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11532 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11537 return new (Context)
11538 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
11539 LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
11546 Expr *ValExpr = Condition;
11547 Stmt *HelperValStmt =
nullptr;
11552 ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11556 ValExpr = MakeFullExpr(Val.
get()).
get();
11561 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11562 ValExpr = MakeFullExpr(ValExpr).get();
11563 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11564 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11569 return new (Context)
OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
11570 StartLoc, LParenLoc, EndLoc);
11580 IntConvertDiagnoser()
11584 return S.
Diag(Loc, diag::err_omp_not_integral) << T;
11588 return S.
Diag(Loc, diag::err_omp_incomplete_type) << T;
11593 return S.
Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
11602 return S.
Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
11611 llvm_unreachable(
"conversion functions are permitted");
11613 } ConvertDiagnoser;
11614 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
11619 bool StrictlyPositive,
bool BuildCapture =
false,
11622 Stmt **HelperValStmt =
nullptr) {
11631 ValExpr = Value.
get();
11635 Result.isSigned() &&
11636 !((!StrictlyPositive && Result.isNonNegative()) ||
11637 (StrictlyPositive && Result.isStrictlyPositive()))) {
11638 SemaRef.
Diag(Loc, diag::err_omp_negative_expression_in_clause)
11647 if (*CaptureRegion != OMPD_unknown &&
11650 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11651 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
11662 Expr *ValExpr = NumThreads;
11663 Stmt *HelperValStmt =
nullptr;
11674 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11675 ValExpr = MakeFullExpr(ValExpr).get();
11676 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11677 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
11682 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
11687 bool StrictlyPositive) {
11694 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
11697 if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
11698 (!StrictlyPositive && !Result.isNonNegative())) {
11699 Diag(E->
getExprLoc(), diag::err_omp_negative_expression_in_clause)
11704 if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
11705 Diag(E->
getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
11709 if (CKind == OMPC_collapse &&
DSAStack->getAssociatedLoops() == 1)
11710 DSAStack->setAssociatedLoops(Result.getExtValue());
11711 else if (CKind == OMPC_ordered)
11712 DSAStack->setAssociatedLoops(Result.getExtValue());
11722 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
11725 return new (Context)
11735 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
11738 return new (Context)
11744 DSAStackTy *Stack) {
11745 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
11746 if (!OMPAllocatorHandleT.
isNull())
11749 bool ErrorFound =
false;
11750 for (
int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
11751 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
11752 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
11753 StringRef Allocator =
11754 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
11756 auto *VD = dyn_cast_or_null<ValueDecl>(
11769 if (OMPAllocatorHandleT.
isNull())
11770 OMPAllocatorHandleT = AllocatorType;
11775 Stack->setAllocator(AllocatorKind, Res.
get());
11778 S.
Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
11782 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
11794 ExprResult Allocator = DefaultLvalueConversion(A);
11797 Allocator = PerformImplicitConversion(Allocator.
get(),
11798 DSAStack->getOMPAllocatorHandleT(),
11803 return new (Context)
11817 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
11820 return new (Context)
11827 Expr *NumForLoops) {
11833 if (NumForLoops && LParenLoc.
isValid()) {
11835 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
11838 NumForLoops = NumForLoopsResult.
get();
11840 NumForLoops =
nullptr;
11843 Context, NumForLoops, NumForLoops ?
DSAStack->getAssociatedLoops() : 0,
11844 StartLoc, LParenLoc, EndLoc);
11845 DSAStack->setOrderedRegion(
true, NumForLoops, Clause);
11856 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
11857 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11859 case OMPC_proc_bind:
11860 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
11861 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11863 case OMPC_atomic_default_mem_order:
11864 Res = ActOnOpenMPAtomicDefaultMemOrderClause(
11865 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
11866 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11870 case OMPC_num_threads:
11873 case OMPC_allocator:
11874 case OMPC_collapse:
11875 case OMPC_schedule:
11877 case OMPC_firstprivate:
11878 case OMPC_lastprivate:
11880 case OMPC_reduction:
11881 case OMPC_task_reduction:
11882 case OMPC_in_reduction:
11886 case OMPC_copyprivate:
11890 case OMPC_mergeable:
11892 case OMPC_allocate:
11904 case OMPC_num_teams:
11905 case OMPC_thread_limit:
11906 case OMPC_priority:
11907 case OMPC_grainsize:
11909 case OMPC_num_tasks:
11911 case OMPC_dist_schedule:
11912 case OMPC_defaultmap:
11917 case OMPC_use_device_ptr:
11918 case OMPC_is_device_ptr:
11919 case OMPC_unified_address:
11920 case OMPC_unified_shared_memory:
11921 case OMPC_reverse_offload:
11922 case OMPC_dynamic_allocators:
11925 case OMPC_nontemporal:
11926 llvm_unreachable(
"Clause is not allowed.");
11935 llvm::raw_svector_ostream Out(Buffer);
11936 unsigned Skipped = Exclude.size();
11937 auto S = Exclude.begin(), E = Exclude.end();
11938 for (
unsigned I = First; I <
Last; ++I) {
11939 if (std::find(S, E, I) != E) {
11944 if (I + Skipped + 2 == Last)
11946 else if (I + Skipped + 1 != Last)
11959 "OMPC_DEFAULT_unknown not greater than 0");
11960 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11967 case OMPC_DEFAULT_none:
11968 DSAStack->setDefaultDSANone(KindKwLoc);
11970 case OMPC_DEFAULT_shared:
11971 DSAStack->setDefaultDSAShared(KindKwLoc);
11974 llvm_unreachable(
"Clause kind is not allowed.");
11977 return new (Context)
11986 if (Kind == OMP_PROC_BIND_unknown) {
11987 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11989 unsigned(OMP_PROC_BIND_master),
11994 return new (Context)
12002 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12004 OMPC_atomic_default_mem_order, 0,
12010 LParenLoc, EndLoc);
12020 case OMPC_schedule:
12021 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
12022 assert(Argument.size() == NumberOfElements &&
12023 ArgumentLoc.size() == NumberOfElements);
12024 Res = ActOnOpenMPScheduleClause(
12025 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
12026 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
12027 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
12028 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
12029 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
12032 assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
12033 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
12034 Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
12037 case OMPC_dist_schedule:
12038 Res = ActOnOpenMPDistScheduleClause(
12039 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
12040 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
12042 case OMPC_defaultmap:
12043 enum {
Modifier, DefaultmapKind };
12044 Res = ActOnOpenMPDefaultmapClause(
12045 static_cast<OpenMPDefaultmapClauseModifier>(Argument[
Modifier]),
12046 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
12047 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
12051 case OMPC_num_threads:
12054 case OMPC_allocator:
12055 case OMPC_collapse:
12057 case OMPC_proc_bind:
12059 case OMPC_firstprivate:
12060 case OMPC_lastprivate:
12062 case OMPC_reduction:
12063 case OMPC_task_reduction:
12064 case OMPC_in_reduction:
12068 case OMPC_copyprivate:
12072 case OMPC_mergeable:
12074 case OMPC_allocate:
12086 case OMPC_num_teams:
12087 case OMPC_thread_limit:
12088 case OMPC_priority:
12089 case OMPC_grainsize:
12091 case OMPC_num_tasks:
12097 case OMPC_use_device_ptr:
12098 case OMPC_is_device_ptr:
12099 case OMPC_unified_address:
12100 case OMPC_unified_shared_memory:
12101 case OMPC_reverse_offload:
12102 case OMPC_dynamic_allocators:
12103 case OMPC_atomic_default_mem_order:
12106 case OMPC_nontemporal:
12107 llvm_unreachable(
"Clause is not allowed.");
12118 Excluded.push_back(M2);
12119 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
12120 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
12121 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
12122 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
12123 S.
Diag(M1Loc, diag::err_omp_unexpected_clause_value)
12146 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
12147 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
12148 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
12149 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
12150 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
12156 std::string Values;
12166 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12173 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
12174 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
12175 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
12176 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
12177 diag::err_omp_schedule_nonmonotonic_static);
12180 Expr *ValExpr = ChunkSize;
12181 Stmt *HelperValStmt =
nullptr;
12188 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12192 ValExpr = Val.
get();
12199 if (Result.isSigned() && !Result.isStrictlyPositive()) {
12200 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12205 DSAStack->getCurrentDirective(), OMPC_schedule,
12206 LangOpts.OpenMP) != OMPD_unknown &&
12207 !CurContext->isDependentContext()) {
12208 ValExpr = MakeFullExpr(ValExpr).get();
12209 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12210 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
12216 return new (Context)
12218 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
12227 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
12230 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
12233 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
12235 case OMPC_mergeable:
12236 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
12239 Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
12242 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
12245 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
12248 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
12251 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
12254 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
12257 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
12260 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
12262 case OMPC_unified_address:
12263 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
12265 case OMPC_unified_shared_memory:
12266 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
12268 case OMPC_reverse_offload:
12269 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
12271 case OMPC_dynamic_allocators:
12272 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
12276 case OMPC_num_threads:
12279 case OMPC_allocator:
12280 case OMPC_collapse:
12281 case OMPC_schedule:
12283 case OMPC_firstprivate:
12284 case OMPC_lastprivate:
12286 case OMPC_reduction:
12287 case OMPC_task_reduction:
12288 case OMPC_in_reduction:
12292 case OMPC_copyprivate:
12294 case OMPC_proc_bind:
12296 case OMPC_allocate:
12301 case OMPC_num_teams:
12302 case OMPC_thread_limit:
12303 case OMPC_priority:
12304 case OMPC_grainsize:
12305 case OMPC_num_tasks:
12307 case OMPC_dist_schedule:
12308 case OMPC_defaultmap:
12313 case OMPC_use_device_ptr:
12314 case OMPC_is_device_ptr:
12315 case OMPC_atomic_default_mem_order:
12318 case OMPC_nontemporal:
12319 llvm_unreachable(
"Clause is not allowed.");
12414 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12416 case OMPC_firstprivate:
12417 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12419 case OMPC_lastprivate:
12421 "Unexpected lastprivate modifier.");
12422 Res = ActOnOpenMPLastprivateClause(
12423 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
12424 DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
12427 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
12429 case OMPC_reduction:
12430 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12431 EndLoc, ReductionOrMapperIdScopeSpec,
12432 ReductionOrMapperId);
12434 case OMPC_task_reduction:
12435 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12436 EndLoc, ReductionOrMapperIdScopeSpec,
12437 ReductionOrMapperId);
12439 case OMPC_in_reduction:
12440 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12441 EndLoc, ReductionOrMapperIdScopeSpec,
12442 ReductionOrMapperId);
12446 "Unexpected linear modifier.");
12447 Res = ActOnOpenMPLinearClause(
12448 VarList, TailExpr, StartLoc, LParenLoc,
12449 static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc,
12453 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
12457 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
12459 case OMPC_copyprivate:
12460 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12463 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
12467 "Unexpected depend modifier.");
12468 Res = ActOnOpenMPDependClause(
12469 static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc,
12470 ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
12474 "Unexpected map modifier.");
12475 Res = ActOnOpenMPMapClause(
12476 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
12477 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
12478 IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs);
12481 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
12482 ReductionOrMapperId, Locs);
12485 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
12486 ReductionOrMapperId, Locs);
12488 case OMPC_use_device_ptr:
12489 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
12491 case OMPC_is_device_ptr:
12492 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
12494 case OMPC_allocate:
12495 Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
12498 case OMPC_nontemporal:
12499 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
12503 case OMPC_num_threads:
12506 case OMPC_allocator:
12507 case OMPC_collapse:
12509 case OMPC_proc_bind:
12510 case OMPC_schedule:
12514 case OMPC_mergeable:
12524 case OMPC_num_teams:
12525 case OMPC_thread_limit:
12526 case OMPC_priority:
12527 case OMPC_grainsize:
12529 case OMPC_num_tasks:
12531 case OMPC_dist_schedule:
12532 case OMPC_defaultmap:
12535 case OMPC_unified_address:
12536 case OMPC_unified_shared_memory:
12537 case OMPC_reverse_offload:
12538 case OMPC_dynamic_allocators:
12539 case OMPC_atomic_default_mem_order:
12542 llvm_unreachable(
"Clause is not allowed.");
12553 if (OK ==
OK_Ordinary && !getLangOpts().CPlusPlus) {
12554 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.
get());
12559 Res = DefaultLvalueConversion(Res.
get());
12572 for (
Expr *RefExpr : VarList) {
12573 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
12576 Expr *SimpleRefExpr = RefExpr;
12580 Vars.push_back(RefExpr);
12581 PrivateCopies.push_back(
nullptr);
12588 auto *VD = dyn_cast<
VarDecl>(D);
12593 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
12615 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
12616 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_private) {
12627 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12629 << getOpenMPDirectiveName(CurrDir);
12634 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12648 CurrDir == OMPD_target) {
12650 if (
DSAStack->checkMappableExprComponentListsForDecl(
12654 ConflictKind = WhereFoundClauseKind;
12657 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12660 << getOpenMPDirectiveName(CurrDir);
12679 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
12680 ActOnUninitializedDecl(VDPrivate);
12687 if (!VD && !CurContext->isDependentContext())
12690 Vars.push_back((VD || CurContext->isDependentContext())
12693 PrivateCopies.push_back(VDPrivateRefExpr);
12704 class DiagsUninitializedSeveretyRAII {
12708 bool IsIgnored =
false;
12713 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
12715 Diags.
setSeverity( diag::warn_uninit_self_reference_in_init,
12719 ~DiagsUninitializedSeveretyRAII() {
12734 bool IsImplicitClause =
12738 for (
Expr *RefExpr : VarList) {
12739 assert(RefExpr &&
"NULL expr in OpenMP firstprivate clause.");
12742 Expr *SimpleRefExpr = RefExpr;
12746 Vars.push_back(RefExpr);
12747 PrivateCopies.push_back(
nullptr);
12748 Inits.push_back(
nullptr);
12754 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
12756 auto *VD = dyn_cast<
VarDecl>(D);
12761 if (RequireCompleteType(ELoc, Type,
12762 diag::err_omp_firstprivate_incomplete_type))
12773 DSAStackTy::DSAVarData TopDVar;
12774 if (!IsImplicitClause) {
12775 DSAStackTy::DSAVarData DVar =
12779 bool IsConstant = ElemType.
isConstant(Context);
12787 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
12789 DVar.CKind != OMPC_lastprivate) &&
12791 Diag(ELoc, diag::err_omp_wrong_dsa)
12809 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
12810 DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared) {
12811 Diag(ELoc, diag::err_omp_wrong_dsa)
12837 DVar =
DSAStack->getImplicitDSA(D,
true);
12838 if (DVar.CKind != OMPC_shared &&
12841 DVar.DKind == OMPD_unknown)) {
12842 Diag(ELoc, diag::err_omp_required_access)
12869 if (DVar.CKind == OMPC_reduction &&
12873 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
12874 << getOpenMPDirectiveName(DVar.DKind);
12888 if ((LangOpts.OpenMP <= 45 &&
12890 CurrDir == OMPD_target) {
12892 if (
DSAStack->checkMappableExprComponentListsForDecl(
12897 ConflictKind = WhereFoundClauseKind;
12900 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12903 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
12913 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12915 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
12920 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12929 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
12935 Expr *VDInitRefExpr =
nullptr;
12942 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
12945 ".firstprivate.temp");
12960 ".firstprivate.temp");
12963 AddInitializerToDecl(VDPrivate,
12964 DefaultLvalueConversion(VDInitRefExpr).
get(),
12968 if (IsImplicitClause) {
12970 diag::note_omp_task_predetermined_firstprivate_here);
12974 CurContext->addDecl(VDPrivate);
12979 if (!VD && !CurContext->isDependentContext()) {
12980 if (TopDVar.CKind == OMPC_lastprivate) {
12981 Ref = TopDVar.PrivateCopy;
12984 if (!isOpenMPCapturedDecl(D))
12985 ExprCaptures.push_back(Ref->getDecl());
12989 Vars.push_back((VD || CurContext->isDependentContext())
12992 PrivateCopies.push_back(VDPrivateRefExpr);
12993 Inits.push_back(VDInitRefExpr);
13000 Vars, PrivateCopies, Inits,
13009 assert(ColonLoc.
isValid() &&
"Colon location must be valid.");
13010 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
13023 for (
Expr *RefExpr : VarList) {
13024 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
13027 Expr *SimpleRefExpr = RefExpr;
13031 Vars.push_back(RefExpr);
13032 SrcExprs.push_back(
nullptr);
13033 DstExprs.push_back(
nullptr);
13034 AssignmentOps.push_back(
nullptr);
13041 auto *VD = dyn_cast<
VarDecl>(D);
13046 if (RequireCompleteType(ELoc, Type,
13047 diag::err_omp_lastprivate_incomplete_type))
13065 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->
isScalarType()) {
13066 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
13067 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13070 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13084 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
13085 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
13087 DVar.CKind != OMPC_firstprivate) &&
13088 (DVar.CKind != OMPC_private || DVar.RefExpr !=
nullptr)) {
13089 Diag(ELoc, diag::err_omp_wrong_dsa)
13102 DSAStackTy::DSAVarData TopDVar = DVar;
13106 DVar =
DSAStack->getImplicitDSA(D,
true);
13107 if (DVar.CKind != OMPC_shared) {
13108 Diag(ELoc, diag::err_omp_required_access)
13136 ExprResult AssignmentOp = BuildBinOp(
nullptr, ELoc, BO_Assign,
13137 PseudoDstExpr, PseudoSrcExpr);
13141 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
13146 if (!VD && !CurContext->isDependentContext()) {
13147 if (TopDVar.CKind == OMPC_firstprivate) {
13148 Ref = TopDVar.PrivateCopy;
13151 if (!isOpenMPCapturedDecl(D))
13152 ExprCaptures.push_back(Ref->
getDecl());
13154 if (TopDVar.CKind == OMPC_firstprivate ||
13155 (!isOpenMPCapturedDecl(D) &&
13157 ExprResult RefRes = DefaultLvalueConversion(Ref);
13161 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
13165 ExprPostUpdates.push_back(
13166 IgnoredValueConversions(PostUpdateRes.
get()).
get());
13170 Vars.push_back((VD || CurContext->isDependentContext())
13173 SrcExprs.push_back(PseudoSrcExpr);
13174 DstExprs.push_back(PseudoDstExpr);
13175 AssignmentOps.push_back(AssignmentOp.
get());
13182 Vars, SrcExprs, DstExprs, AssignmentOps,
13183 LPKind, LPKindLoc, ColonLoc,
13193 for (
Expr *RefExpr : VarList) {
13194 assert(RefExpr &&
"NULL expr in OpenMP lastprivate clause.");
13197 Expr *SimpleRefExpr = RefExpr;
13201 Vars.push_back(RefExpr);
13207 auto *VD = dyn_cast<
VarDecl>(D);
13215 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
13216 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_shared &&
13225 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
13228 Vars.push_back((VD || !Ref || CurContext->isDependentContext())
13240 class DSARefChecker :
public StmtVisitor<DSARefChecker, bool> {
13245 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
13246 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
13247 if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
13251 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
13258 bool VisitStmt(
Stmt *S) {
13260 if (Child && Visit(Child))
13265 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
13272 class TransformExprToCaptures :
public TreeTransform<TransformExprToCaptures> {
13279 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(
nullptr) {}
13284 CapturedExpr =
buildCapture(SemaRef, Field, E,
false);
13285 return CapturedExpr;
13287 return BaseTransform::TransformMemberExpr(E);
13289 DeclRefExpr *getCapturedExpr() {
return CapturedExpr; }
13293 template <
typename T,
typename U>
13296 for (U &Set : Lookups) {
13297 for (
auto *D : Set) {
13298 if (T Res = Gen(cast<ValueDecl>(D)))
13308 for (
auto RD : D->
redecls()) {
13313 auto ND = cast<NamedDecl>(RD);
13331 AssociatedClasses);
13344 for (
auto *NS : AssociatedNamespaces) {
13357 for (
auto *D : R) {
13358 auto *Underlying = D;
13359 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
13360 Underlying = USD->getTargetDecl();
13362 if (!isa<OMPDeclareReductionDecl>(Underlying) &&
13363 !isa<OMPDeclareMapperDecl>(Underlying))
13370 if (
auto *USD = dyn_cast<UsingShadowDecl>(D))
13371 Underlying = USD->getTargetDecl();
13373 Lookups.emplace_back();
13374 Lookups.back().addDecl(Underlying);
13397 Lookups.emplace_back();
13398 Lookups.back().append(Lookup.
begin(), Lookup.
end());
13401 }
else if (
auto *ULE =
13402 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
13404 Decl *PrevD =
nullptr;
13408 else if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
13409 Lookups.back().addDecl(DRD);
13416 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
13426 ResSet.
append(Set.begin(), Set.end());
13428 ResSet.
addDecl(Set[Set.size() - 1]);
13433 true,
true, ResSet.
begin(), ResSet.
end());
13449 Lookup.suppressDiagnostics();
13453 if (SemaRef.
isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
13454 TyRec->getDecl()->getDefinition()) {
13457 if (Lookup.empty()) {
13458 Lookups.emplace_back();
13459 Lookups.back().append(Lookup.begin(), Lookup.end());
13466 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13476 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13486 if (SemaRef.
IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
13488 VD->getType().getUnqualifiedType()))) {
13490 Loc, VD->getType(), Ty, Paths.
front(),
13494 VD, VD->getType().getNonReferenceType(),
VK_LValue, Loc);
13500 if (ReductionIdScopeSpec.
isSet()) {
13501 SemaRef.
Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
13510 struct ReductionData {
13528 ReductionData() =
delete;
13530 ReductionData(
unsigned Size) {
13531 Vars.reserve(Size);
13532 Privates.reserve(Size);
13533 LHSs.reserve(Size);
13534 RHSs.reserve(Size);
13535 ReductionOps.reserve(Size);
13536 TaskgroupDescriptors.reserve(Size);
13537 ExprCaptures.reserve(Size);
13538 ExprPostUpdates.reserve(Size);
13542 void push(
Expr *Item,
Expr *ReductionOp) {
13543 Vars.emplace_back(Item);
13544 Privates.emplace_back(
nullptr);
13545 LHSs.emplace_back(
nullptr);
13546 RHSs.emplace_back(
nullptr);
13547 ReductionOps.emplace_back(ReductionOp);
13548 TaskgroupDescriptors.emplace_back(
nullptr);
13552 Expr *TaskgroupDescriptor) {
13553 Vars.emplace_back(Item);
13554 Privates.emplace_back(Private);
13555 LHSs.emplace_back(LHS);
13556 RHSs.emplace_back(RHS);
13557 ReductionOps.emplace_back(ReductionOp);
13558 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
13567 if (Length ==
nullptr) {
13574 SingleElement =
true;
13575 ArraySizes.push_back(llvm::APSInt::get(1));
13582 SingleElement = (ConstantLengthValue.getSExtValue() == 1);
13583 ArraySizes.push_back(ConstantLengthValue);
13591 while (
const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
13592 Length = TempOASE->getLength();
13593 if (Length ==
nullptr) {
13600 ArraySizes.push_back(llvm::APSInt::get(1));
13607 if (ConstantLengthValue.getSExtValue() != 1)
13610 ArraySizes.push_back(ConstantLengthValue);
13616 if (!SingleElement) {
13617 while (
const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
13619 ArraySizes.push_back(llvm::APSInt::get(1));
13634 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
13673 case OO_Array_Delete:
13682 case OO_GreaterEqual:
13684 case OO_MinusEqual:
13686 case OO_SlashEqual:
13687 case OO_PercentEqual:
13688 case OO_CaretEqual:
13692 case OO_GreaterGreater:
13693 case OO_LessLessEqual:
13694 case OO_GreaterGreaterEqual:
13695 case OO_EqualEqual:
13696 case OO_ExclaimEqual:
13699 case OO_MinusMinus:
13705 case OO_Conditional:
13708 llvm_unreachable(
"Unexpected reduction identifier");
13711 if (II->isStr(
"max"))
13713 else if (II->isStr(
"min"))
13719 if (ReductionIdScopeSpec.
isValid())
13725 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
13726 bool FirstIter =
true;
13727 for (
Expr *RefExpr : VarList) {
13728 assert(RefExpr &&
"nullptr expr in OpenMP reduction clause.");
13736 if (!FirstIter && IR != ER)
13741 Expr *SimpleRefExpr = RefExpr;
13750 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13751 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13752 Expr *ReductionOp =
nullptr;
13754 (DeclareReductionRef.
isUnset() ||
13755 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get())))
13756 ReductionOp = DeclareReductionRef.
get();
13758 RD.push(RefExpr, ReductionOp);
13764 Expr *TaskgroupDescriptor =
nullptr;
13769 Type = ASE->getType().getNonReferenceType();
13774 Type = ATy->getElementType();
13781 auto *VD = dyn_cast<
VarDecl>(D);
13787 diag::err_omp_reduction_incomplete_type))
13793 false, ASE || OASE))
13800 if (!ASE && !OASE) {
13803 if (VD->getType()->isReferenceType() && VDDef && VDDef->
hasInit()) {
13804 DSARefChecker Check(Stack);
13805 if (Check.Visit(VDDef->
getInit())) {
13806 S.
Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
13825 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D,
false);
13826 if (DVar.CKind == OMPC_reduction) {
13827 S.
Diag(ELoc, diag::err_omp_once_referenced)
13830 S.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
13834 S.
Diag(ELoc, diag::err_omp_wrong_dsa)
13848 DVar = Stack->getImplicitDSA(D,
true);
13849 if (DVar.CKind != OMPC_shared) {
13850 S.
Diag(ELoc, diag::err_omp_required_access)
13863 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13864 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13868 (DeclareReductionRef.
isUnset() ||
13869 isa<UnresolvedLookupExpr>(DeclareReductionRef.
get()))) {
13870 RD.push(RefExpr, DeclareReductionRef.
get());
13873 if (BOK == BO_Comma && DeclareReductionRef.
isUnset()) {
13875 S.
Diag(ReductionId.getBeginLoc(),
13876 diag::err_omp_unknown_reduction_identifier)
13877 << Type << ReductionIdRange;
13889 if (DeclareReductionRef.
isUnset()) {
13890 if ((BOK == BO_GT || BOK == BO_LT) &&
13891 !(Type->isScalarType() ||
13892 (S.
getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
13893 S.
Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
13895 if (!ASE && !OASE) {
13896 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13899 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13904 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
13905 !S.
getLangOpts().CPlusPlus && Type->isFloatingType()) {
13906 S.
Diag(ELoc, diag::err_omp_clause_floating_type_arg)
13908 if (!ASE && !OASE) {
13909 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13912 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13919 Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
13928 bool ConstantLengthOASE =
false;
13930 bool SingleElement;
13933 Context, OASE, SingleElement, ArraySizes);
13936 if (ConstantLengthOASE && !SingleElement) {
13944 if ((OASE && !ConstantLengthOASE) ||
13949 S.
Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13950 S.
Diag(ELoc, diag::note_vla_unsupported);
13952 S.
targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13953 S.
targetDiag(ELoc, diag::note_vla_unsupported);
13966 }
else if (!ASE && !OASE &&
13974 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
13976 Expr *Init =
nullptr;
13979 if (DeclareReductionRef.
isUsable()) {
13981 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
13982 if (DRD->getInitializer()) {
13984 RHSVD->setInit(DRDRef);
13994 if (Type->isScalarType() || Type->isAnyComplexType())
13999 if (Type->isScalarType() || Type->isAnyComplexType()) {
14008 Type = ComplexTy->getElementType();
14009 if (Type->isRealFloatingType()) {
14010 llvm::APFloat InitValue =
14011 llvm::APFloat::getAllOnesValue(Context.
getTypeSize(Type),
14015 }
else if (Type->isScalarType()) {
14018 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
14035 if (Type->isIntegerType() || Type->isPointerType()) {
14041 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
14042 : llvm::APInt::getMinValue(Size)
14043 : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
14044 : llvm::APInt::getMaxValue(Size);
14046 if (Type->isPointerType()) {
14052 Init = CastExpr.
get();
14054 }
else if (Type->isRealFloatingType()) {
14055 llvm::APFloat InitValue = llvm::APFloat::getLargest(
14086 llvm_unreachable(
"Unexpected reduction operation");
14089 if (Init && DeclareReductionRef.
isUnset())
14093 if (RHSVD->isInvalidDecl())
14095 if (!RHSVD->hasInit() &&
14097 S.
Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
14098 << Type << ReductionIdRange;
14099 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14102 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14108 PrivateVD->
setInit(RHSVD->getInit());
14112 if (DeclareReductionRef.
isUsable()) {
14113 QualType RedTy = DeclareReductionRef.
get()->getType();
14117 if (!BasePath.empty()) {
14121 CK_UncheckedDerivedToBase, LHS.
get(),
14122 &BasePath, LHS.
get()->getValueKind());
14124 CK_UncheckedDerivedToBase, RHS.get(),
14125 &BasePath, RHS.get()->getValueKind());
14128 QualType Params[] = {PtrRedTy, PtrRedTy};
14138 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
14140 if (BOK != BO_LT && BOK != BO_GT) {
14142 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14143 BO_Assign, LHSDRE, ReductionOp.
get());
14145 auto *ConditionalOp =
new (Context)
14149 S.
BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14150 BO_Assign, LHSDRE, ConditionalOp);
14167 if (ClauseKind == OMPC_in_reduction) {
14170 const Expr *ParentReductionOp;
14171 Expr *ParentBOKTD, *ParentReductionOpTD;
14172 DSAStackTy::DSAVarData ParentBOKDSA =
14173 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
14175 DSAStackTy::DSAVarData ParentReductionOpDSA =
14176 Stack->getTopMostTaskgroupReductionData(
14177 D, ParentSR, ParentReductionOp, ParentReductionOpTD);
14178 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
14179 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
14180 if (!IsParentBOK && !IsParentReductionOp) {
14181 S.
Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
14184 if ((DeclareReductionRef.
isUnset() && IsParentReductionOp) ||
14185 (DeclareReductionRef.
isUsable() && IsParentBOK) || BOK != ParentBOK ||
14186 IsParentReductionOp) {
14187 bool EmitError =
true;
14188 if (IsParentReductionOp && DeclareReductionRef.
isUsable()) {
14189 llvm::FoldingSetNodeID RedId, ParentRedId;
14190 ParentReductionOp->
Profile(ParentRedId, Context,
true);
14191 DeclareReductionRef.
get()->Profile(RedId, Context,
14193 EmitError = RedId != ParentRedId;
14196 S.
Diag(ReductionId.getBeginLoc(),
14197 diag::err_omp_reduction_identifier_mismatch)
14200 diag::note_omp_previous_reduction_identifier)
14202 << (IsParentBOK ? ParentBOKDSA.RefExpr
14203 : ParentReductionOpDSA.RefExpr)
14204 ->getSourceRange();
14208 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
14209 assert(TaskgroupDescriptor &&
"Taskgroup descriptor must be defined.");
14216 TransformExprToCaptures RebuildToCapture(S, D);
14218 RebuildToCapture.TransformExpr(RefExpr->
IgnoreParens()).
get();
14219 Ref = RebuildToCapture.getCapturedExpr();
14221 VarsExpr = Ref =
buildCapture(S, D, SimpleRefExpr,
false);
14224 RD.ExprCaptures.emplace_back(Ref->
getDecl());
14230 S.
BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14235 Stack->getCurrentDirective() == OMPD_taskgroup) {
14237 diag::err_omp_reduction_non_addressable_expression)
14241 RD.ExprPostUpdates.emplace_back(
14248 Stack->addDSA(D, RefExpr->
IgnoreParens(), OMPC_reduction, Ref);
14249 if (CurrDir == OMPD_taskgroup) {
14250 if (DeclareReductionRef.
isUsable())
14251 Stack->addTaskgroupReductionData(D, ReductionIdRange,
14252 DeclareReductionRef.
get());
14254 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
14256 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.
get(),
14257 TaskgroupDescriptor);
14259 return RD.Vars.empty();
14267 ReductionData RD(VarList.size());
14269 StartLoc, LParenLoc, ColonLoc, EndLoc,
14270 ReductionIdScopeSpec, ReductionId,
14271 UnresolvedReductions, RD))
14275 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14277 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14287 ReductionData RD(VarList.size());
14289 StartLoc, LParenLoc, ColonLoc, EndLoc,
14290 ReductionIdScopeSpec, ReductionId,
14291 UnresolvedReductions, RD))
14295 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14297 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14307 ReductionData RD(VarList.size());
14309 StartLoc, LParenLoc, ColonLoc, EndLoc,
14310 ReductionIdScopeSpec, ReductionId,
14311 UnresolvedReductions, RD))
14315 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14317 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
14324 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
14326 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
14335 const auto *VD = dyn_cast_or_null<VarDecl>(D);
14337 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
14339 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
14341 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
14357 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
14358 !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
14359 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
14365 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14382 if (CheckOpenMPLinearModifier(LinKind, LinLoc))
14383 LinKind = OMPC_LINEAR_val;
14384 for (
Expr *RefExpr : VarList) {
14385 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
14388 Expr *SimpleRefExpr = RefExpr;
14392 Vars.push_back(RefExpr);
14393 Privates.push_back(
nullptr);
14394 Inits.push_back(
nullptr);
14401 auto *VD = dyn_cast<
VarDecl>(D);
14407 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
14408 if (DVar.RefExpr) {
14415 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
14423 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
14429 if (!VD && !CurContext->isDependentContext()) {
14431 if (!isOpenMPCapturedDecl(D)) {
14432 ExprCaptures.push_back(Ref->
getDecl());
14434 ExprResult RefRes = DefaultLvalueConversion(Ref);
14438 BuildBinOp(
DSAStack->getCurScope(), ELoc, BO_Assign,
14439 SimpleRefExpr, RefRes.
get());
14442 ExprPostUpdates.push_back(
14443 IgnoredValueConversions(PostUpdateRes.
get()).
get());
14447 if (LinKind == OMPC_LINEAR_uval)
14448 InitExpr = VD ? VD->getInit() : SimpleRefExpr;
14450 InitExpr = VD ? SimpleRefExpr : Ref;
14451 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).
get(),
14456 Vars.push_back((VD || CurContext->isDependentContext())
14459 Privates.push_back(PrivateRef);
14460 Inits.push_back(InitRef);
14467 Expr *CalcStepExpr =
nullptr;
14472 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
14475 StepExpr = Val.
get();
14483 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
14484 CalcStep = ActOnFinishFullExpr(CalcStep.get(),
false);
14490 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
14491 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
14492 << (Vars.size() > 1);
14493 if (!IsConstant && CalcStep.isUsable()) {
14496 CalcStepExpr = CalcStep.get();
14501 ColonLoc, EndLoc, Vars, Privates, Inits,
14502 StepExpr, CalcStepExpr,
14508 Expr *NumIterations,
Sema &SemaRef,
14509 Scope *S, DSAStackTy *Stack) {
14521 Step = cast<BinaryOperator>(
CalcStep)->getLHS();
14522 bool HasErrors =
false;
14523 auto CurInit = Clause.inits().begin();
14524 auto CurPrivate = Clause.privates().begin();
14529 Expr *SimpleRefExpr = RefExpr;
14530 auto Res =
getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
14532 if (Res.second || !D) {
14533 Updates.push_back(
nullptr);
14534 Finals.push_back(
nullptr);
14538 auto &&Info = Stack->isLoopControlVariable(D);
14545 diag::err_omp_linear_distribute_var_non_loop_iteration);
14546 Updates.push_back(
nullptr);
14547 Finals.push_back(
nullptr);
14551 Expr *InitExpr = *CurInit;
14554 auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
14556 if (LinKind == OMPC_LINEAR_uval)
14557 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
14561 DE->getType().getUnqualifiedType(), DE->getExprLoc(),
14568 SemaRef, S, RefExpr->
getExprLoc(), *CurPrivate, InitExpr, IV,
Step,
14571 Update = *CurPrivate;
14580 InitExpr, NumIterations,
Step,
false,
14583 Final = *CurPrivate;
14587 if (!Update.isUsable() || !Final.isUsable()) {
14588 Updates.push_back(
nullptr);
14589 Finals.push_back(
nullptr);
14590 UsedExprs.push_back(
nullptr);
14593 Updates.push_back(Update.get());
14594 Finals.push_back(Final.get());
14596 UsedExprs.push_back(SimpleRefExpr);
14601 if (
Expr *S = Clause.getStep())
14602 UsedExprs.push_back(S);
14604 UsedExprs.append(Clause.
varlist_size() + 1 - UsedExprs.size(),
nullptr);
14605 Clause.setUpdates(Updates);
14606 Clause.setFinals(Finals);
14607 Clause.setUsedExprs(UsedExprs);
14615 for (
Expr *RefExpr : VarList) {
14616 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
14619 Expr *SimpleRefExpr = RefExpr;
14623 Vars.push_back(RefExpr);
14630 auto *VD = dyn_cast<
VarDecl>(D);
14636 const Type *Ty = QType.getTypePtrOrNull();
14638 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
14639 << QType << getLangOpts().CPlusPlus << ERange;
14644 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14651 if (
const Expr *PrevRef =
DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
14652 Diag(ELoc, diag::err_omp_used_in_clause_twice)
14654 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
14660 if (!VD && isOpenMPCapturedDecl(D))
14662 Vars.push_back(DefaultFunctionArrayConversion(
14672 if (Alignment !=
nullptr) {
14674 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
14677 Alignment = AlignResult.
get();
14683 EndLoc, Vars, Alignment);
14694 for (
Expr *RefExpr : VarList) {
14695 assert(RefExpr &&
"NULL expr in OpenMP copyin clause.");
14696 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14698 Vars.push_back(RefExpr);
14699 SrcExprs.push_back(
nullptr);
14700 DstExprs.push_back(
nullptr);
14701 AssignmentOps.push_back(
nullptr);
14711 if (!DE || !isa<VarDecl>(DE->getDecl())) {
14712 Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
14717 Decl *D = DE->getDecl();
14718 auto *VD = cast<VarDecl>(D);
14721 if (Type->isDependentType() || Type->isInstantiationDependentType()) {
14723 Vars.push_back(DE);
14724 SrcExprs.push_back(
nullptr);
14725 DstExprs.push_back(
nullptr);
14726 AssignmentOps.push_back(
nullptr);
14732 if (!
DSAStack->isThreadPrivate(VD)) {
14733 Diag(ELoc, diag::err_omp_required_access)
14735 << getOpenMPDirectiveName(OMPD_threadprivate);
14746 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
14750 buildVarDecl(*
this, DE->getBeginLoc(), ElemType,
".copyin.dst",
14751 VD->hasAttrs() ? &VD->getAttrs() :
nullptr);
14757 BuildBinOp(
nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
14759 if (AssignmentOp.isInvalid())
14761 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
14763 if (AssignmentOp.isInvalid())
14766 DSAStack->addDSA(VD, DE, OMPC_copyin);
14767 Vars.push_back(DE);
14768 SrcExprs.push_back(PseudoSrcExpr);
14769 DstExprs.push_back(PseudoDstExpr);
14770 AssignmentOps.push_back(AssignmentOp.get());
14777 SrcExprs, DstExprs, AssignmentOps);
14788 for (
Expr *RefExpr : VarList) {
14789 assert(RefExpr &&
"NULL expr in OpenMP linear clause.");
14792 Expr *SimpleRefExpr = RefExpr;
14796 Vars.push_back(RefExpr);
14797 SrcExprs.push_back(
nullptr);
14798 DstExprs.push_back(
nullptr);
14799 AssignmentOps.push_back(
nullptr);
14806 auto *VD = dyn_cast<
VarDecl>(D);
14811 if (!VD || !
DSAStack->isThreadPrivate(VD)) {
14812 DSAStackTy::DSAVarData DVar =
14814 if (DVar.CKind !=
OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
14816 Diag(ELoc, diag::err_omp_wrong_dsa)
14827 DVar =
DSAStack->getImplicitDSA(D,
false);
14828 if (DVar.CKind == OMPC_shared) {
14829 Diag(ELoc, diag::err_omp_required_access)
14831 <<
"threadprivate or private in the enclosing context";
14840 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14842 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
14847 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14857 .getUnqualifiedType();
14867 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
14871 ActOnFinishFullExpr(AssignmentOp.
get(), ELoc,
false);
14877 assert(VD || isOpenMPCapturedDecl(D));
14881 SrcExprs.push_back(PseudoSrcExpr);
14882 DstExprs.push_back(PseudoDstExpr);
14883 AssignmentOps.push_back(AssignmentOp.
get());
14890 Vars, SrcExprs, DstExprs, AssignmentOps);
14897 if (VarList.empty())
14908 if (
DSAStack->getCurrentDirective() == OMPD_ordered &&
14909 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
14910 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14914 if (
DSAStack->getCurrentDirective() != OMPD_ordered &&
14916 DepKind == OMPC_DEPEND_sink)) {
14917 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
14918 Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14928 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
14929 if (
const Expr *OrderedCountExpr =
14930 DSAStack->getParentOrderedRegionParam().first) {
14931 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
14932 TotalDepCount.setIsUnsigned(
true);
14935 for (
Expr *RefExpr : VarList) {
14936 assert(RefExpr &&
"NULL expr in OpenMP shared clause.");
14937 if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14939 Vars.push_back(RefExpr);
14945 if (DepKind == OMPC_DEPEND_sink) {
14946 if (
DSAStack->getParentOrderedRegionParam().first &&
14947 DepCounter >= TotalDepCount) {
14948 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
14960 if (CurContext->isDependentContext()) {
14962 Vars.push_back(RefExpr);
14968 Expr *LHS = SimpleExpr;
14969 Expr *RHS =
nullptr;
14970 if (
auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
14972 OOLoc = BO->getOperatorLoc();
14975 }
else if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
14976 OOK = OCE->getOperator();
14977 OOLoc = OCE->getOperatorLoc();
14980 }
else if (
auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
14981 OOK = MCE->getMethodDecl()
14984 .getCXXOverloadedOperator();
14985 OOLoc = MCE->getCallee()->getExprLoc();
14994 Vars.push_back(RefExpr);
15000 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK !=
OO_None)) {
15001 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
15005 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
15006 RHS, OMPC_depend,
false);
15010 if (!CurContext->isDependentContext() &&
15011 DSAStack->getParentOrderedRegionParam().first &&
15012 DepCounter !=
DSAStack->isParentLoopControlVariable(D).first) {
15014 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
15016 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
15019 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
15022 OpsOffs.emplace_back(RHS, OOK);
15028 const Expr *Length = OASE->getLength();
15034 diag::err_omp_depend_zero_length_array_section_not_allowed)
15043 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
15044 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
15045 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15053 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
15056 if (!Res.
isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
15057 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15065 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
15066 TotalDepCount > VarList.size() &&
15067 DSAStack->getParentOrderedRegionParam().first &&
15068 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
15069 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
15070 << 1 <<
DSAStack->getParentLoopControlVariable(VarList.size() + 1);
15072 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
15077 DepKind, DepLoc, ColonLoc, Vars,
15078 TotalDepCount.getZExtValue());
15079 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
15080 DSAStack->isParentOrderedRegion())
15081 DSAStack->addDoacrossDependClause(
C, OpsOffs);
15088 Expr *ValExpr = Device;
15089 Stmt *HelperValStmt =
nullptr;
15100 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15101 ValExpr = MakeFullExpr(ValExpr).get();
15102 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15103 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
15107 return new (Context)
OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
15108 StartLoc, LParenLoc, EndLoc);
15113 bool FullCheck =
true) {
15116 SemaRef.
Diag(SL, diag::err_incomplete_type) << QTy << SR;
15121 SemaRef.
Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
15136 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
15137 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
15138 return ATy->getSize().getSExtValue() != 1;
15143 assert(OASE &&
"Expecting array section if not an array subscript.");
15144 const Expr *LowerBound = OASE->getLowerBound();
15145 const Expr *Length = OASE->getLength();
15155 if (ConstLowerBound.getSExtValue())
15179 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
15192 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
15195 assert(OASE &&
"Expecting array section if not an array subscript.");
15196 const Expr *Length = OASE->getLength();
15202 if (
const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.
getTypePtr()))
15203 return ATy->getSize().getSExtValue() != 1;
15214 return ConstLength.getSExtValue() != 1;
15247 const Expr *RelevantExpr =
nullptr;
15266 bool AllowUnitySizeArraySection =
true;
15267 bool AllowWholeSizeArraySection =
true;
15269 while (!RelevantExpr) {
15272 if (
auto *CurE = dyn_cast<DeclRefExpr>(E)) {
15273 if (!isa<VarDecl>(CurE->getDecl()))
15276 RelevantExpr = CurE;
15280 AllowUnitySizeArraySection =
false;
15281 AllowWholeSizeArraySection =
false;
15284 CurComponents.emplace_back(CurE, CurE->getDecl());
15285 }
else if (
auto *CurE = dyn_cast<MemberExpr>(E)) {
15288 if (isa<CXXThisExpr>(BaseE))
15290 RelevantExpr = CurE;
15294 if (!isa<FieldDecl>(CurE->getMemberDecl())) {
15296 SemaRef.
Diag(ELoc, diag::err_omp_expected_access_to_data_field)
15297 << CurE->getSourceRange();
15305 auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
15310 if (FD->isBitField()) {
15312 SemaRef.
Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
15332 SemaRef.
Diag(ELoc, diag::err_omp_union_type_not_allowed)
15333 << CurE->getSourceRange();
15346 AllowUnitySizeArraySection =
false;
15347 AllowWholeSizeArraySection =
false;
15350 CurComponents.emplace_back(CurE, FD);
15351 }
else if (
auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
15356 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
15357 << 0 << CurE->getSourceRange();
15368 AllowWholeSizeArraySection =
false;
15370 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
15372 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.
getASTContext())) {
15373 if (!Result.
Val.
getInt().isNullValue()) {
15374 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
15375 diag::err_omp_invalid_map_this_expr);
15376 SemaRef.
Diag(CurE->getIdx()->getExprLoc(),
15377 diag::note_omp_invalid_subscript_on_this_ptr_map);
15384 CurComponents.emplace_back(CurE,
nullptr);
15385 }
else if (
auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
15386 assert(!NoDiagnose &&
"Array sections cannot be implicitly mapped.");
15401 SemaRef.
Diag(ELoc, diag::err_omp_expected_base_var_name)
15402 << 0 << CurE->getSourceRange();
15411 if (AllowWholeSizeArraySection) {
15418 if (NotWhole || IsPointer)
15419 AllowWholeSizeArraySection =
false;
15420 }
else if (AllowUnitySizeArraySection && NotUnity) {
15424 ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
15425 << CurE->getSourceRange();
15429 if (
const auto *TE = dyn_cast<CXXThisExpr>(E)) {
15432 if (CurE->getLength()->EvaluateAsInt(ResultR,
15434 if (!ResultR.
Val.
getInt().isOneValue()) {
15435 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
15436 diag::err_omp_invalid_map_this_expr);
15437 SemaRef.
Diag(CurE->getLength()->getExprLoc(),
15438 diag::note_omp_invalid_length_on_this_ptr_mapping);
15441 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
15443 if (!ResultL.
Val.
getInt().isNullValue()) {
15444 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
15445 diag::err_omp_invalid_map_this_expr);
15446 SemaRef.
Diag(CurE->getLowerBound()->getExprLoc(),
15447 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
15454 CurComponents.emplace_back(CurE,
nullptr);
15459 ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
15466 return RelevantExpr;
15473 bool CurrentRegionOnly,
15484 assert(!CurComponents.empty() &&
"Map clause expression with no components!");
15485 assert(CurComponents.back().getAssociatedDeclaration() == VD &&
15486 "Map clause expression with unexpected base!");
15489 bool IsEnclosedByDataEnvironmentExpr =
false;
15490 const Expr *EnclosingExpr =
nullptr;
15492 bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
15493 VD, CurrentRegionOnly,
15494 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
15495 ERange, CKind, &EnclosingExpr,
15499 assert(!StackComponents.empty() &&
15500 "Map clause expression with no components!");
15501 assert(StackComponents.back().getAssociatedDeclaration() == VD &&
15502 "Map clause expression with unexpected base!");
15506 const Expr *RE = StackComponents.front().getAssociatedExpression();
15512 auto CI = CurComponents.rbegin();
15513 auto CE = CurComponents.rend();
15514 auto SI = StackComponents.rbegin();
15515 auto SE = StackComponents.rend();
15516 for (; CI != CE && SI != SE; ++CI, ++SI) {
15521 if (CurrentRegionOnly &&
15522 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
15523 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
15524 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
15525 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
15526 SemaRef.
Diag(CI->getAssociatedExpression()->getExprLoc(),
15527 diag::err_omp_multiple_array_items_in_map_clause)
15528 << CI->getAssociatedExpression()->getSourceRange();
15529 SemaRef.
Diag(SI->getAssociatedExpression()->getExprLoc(),
15530 diag::note_used_here)
15531 << SI->getAssociatedExpression()->getSourceRange();
15536 if (CI->getAssociatedExpression()->getStmtClass() !=
15537 SI->getAssociatedExpression()->getStmtClass())
15541 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
15547 for (; SI != SE; ++SI) {
15549 if (
const auto *ASE =
15550 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
15551 Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
15552 }
else if (
const auto *OASE = dyn_cast<OMPArraySectionExpr>(
15553 SI->getAssociatedExpression())) {
15560 SemaRef, SI->getAssociatedExpression(), Type))
15570 if (CI == CE && SI == SE) {
15571 if (CurrentRegionOnly) {
15572 if (CKind == OMPC_map) {
15573 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
15575 assert(CKind == OMPC_to || CKind == OMPC_from);
15576 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15579 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
15580 << RE->getSourceRange();
15585 IsEnclosedByDataEnvironmentExpr =
true;
15590 std::prev(CI)->getAssociatedDeclaration()->getType();
15592 std::prev(CI)->getAssociatedExpression()->getExprLoc();
15611 if (CI == CE || SI == SE) {
15614 diag::err_omp_pointer_mapped_along_with_derived_section)
15616 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
15617 << RE->getSourceRange();
15620 if (CI->getAssociatedExpression()->getStmtClass() !=
15621 SI->getAssociatedExpression()->getStmtClass() ||
15622 CI->getAssociatedDeclaration()->getCanonicalDecl() ==
15623 SI->getAssociatedDeclaration()->getCanonicalDecl()) {
15624 assert(CI != CE && SI != SE);
15625 SemaRef.
Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
15627 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
15628 << RE->getSourceRange();
15638 if (CurrentRegionOnly && (CI == CE || SI == SE)) {
15639 if (CKind == OMPC_map) {
15640 if (CI != CE || SI != SE) {
15644 CI != CE ? CurComponents.begin() : StackComponents.begin();
15645 auto End = CI != CE ? CurComponents.end() : StackComponents.end();
15647 while (It !=
End && !It->getAssociatedDeclaration())
15648 std::advance(It, 1);
15649 assert(It !=
End &&
15650 "Expected at least one component with the declaration.");
15651 if (It !=
Begin && It->getAssociatedDeclaration()
15653 .getCanonicalType()
15654 ->isAnyPointerType()) {
15655 IsEnclosedByDataEnvironmentExpr =
false;
15656 EnclosingExpr =
nullptr;
15660 SemaRef.
Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
15662 assert(CKind == OMPC_to || CKind == OMPC_from);
15663 SemaRef.
Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15666 SemaRef.
Diag(RE->getExprLoc(), diag::note_used_here)
15667 << RE->getSourceRange();
15673 if (!CurrentRegionOnly && SI != SE)
15674 EnclosingExpr = RE;
15678 IsEnclosedByDataEnvironmentExpr |=
15679 (!CurrentRegionOnly && CI != CE && SI == SE);
15684 if (CurrentRegionOnly)
15698 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
15700 diag::err_omp_original_storage_is_shared_and_does_not_contain)
15716 Expr *UnresolvedMapper) {
15735 Lookups.emplace_back();
15736 Lookups.back().append(Lookup.
begin(), Lookup.
end());
15739 }
else if (
auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
15743 auto *DMD = cast<OMPDeclareMapperDecl>(D);
15744 assert(DMD &&
"Expect valid OMPDeclareMapperDecl during instantiation.");
15745 Lookups.back().addDecl(DMD);
15753 filterLookupForUDReductionAndMapper<bool>(Lookups, [](
ValueDecl *D) {
15763 URS.
append(Set.begin(), Set.end());
15768 false,
true, URS.
begin(), URS.
end());
15775 SemaRef.
Diag(Loc, diag::err_omp_mapper_wrong_type);
15782 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15792 if (
auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15802 if (SemaRef.
IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
15804 VD->getType().getUnqualifiedType()))) {
15806 Loc, VD->getType(), Type, Paths.
front(),
15815 SemaRef.
Diag(Loc, diag::err_omp_invalid_mapper)
15816 << Type << MapperId.
getName();
15825 struct MappableVarListInfo {
15827 ArrayRef<Expr *> VarList;
15837 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
15840 VarComponents.reserve(VarList.size());
15841 VarBaseDeclarations.reserve(VarList.size());
15856 ArrayRef<Expr *> UnresolvedMappers,
15858 bool IsMapTypeImplicit =
false) {
15860 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
15861 "Unexpected clause kind with mappable expressions!");
15869 MapperId.
setName(DeclNames.getIdentifier(
15874 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
15875 bool UpdateUMIt =
false;
15876 Expr *UnresolvedMapper =
nullptr;
15884 for (
Expr *RE : MVLI.VarList) {
15885 assert(RE &&
"Null expr in omp to/from/map clause");
15889 if (UpdateUMIt && UMIt != UMEnd) {
15893 "Expect the size of UnresolvedMappers to match with that of VarList");
15897 UnresolvedMapper = *UMIt;
15906 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15910 MVLI.UDMapperList.push_back(ER.
get());
15913 MVLI.ProcessedVarList.push_back(RE);
15921 diag::err_omp_expected_named_var_member_or_array_expression)
15932 SemaRef, SimpleExpr, CurComponents, CKind,
false);
15936 assert(!CurComponents.empty() &&
15937 "Invalid mappable expression information.");
15939 if (
const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
15941 DSAS->addMappedClassesQualTypes(TE->getType());
15944 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15948 MVLI.UDMapperList.push_back(ER.
get());
15950 MVLI.ProcessedVarList.push_back(RE);
15951 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15952 MVLI.VarComponents.back().append(CurComponents.begin(),
15953 CurComponents.end());
15954 MVLI.VarBaseDeclarations.push_back(
nullptr);
15961 CurDeclaration = CurComponents.back().getAssociatedDeclaration();
15962 assert(CurDeclaration &&
"Null decl on map clause.");
15965 "Expecting components to have associated only canonical declarations.");
15967 auto *VD = dyn_cast<
VarDecl>(CurDeclaration);
15968 const auto *FD = dyn_cast<
FieldDecl>(CurDeclaration);
15970 assert((VD || FD) &&
"Only variables or fields are expected here!");
15977 if (VD && DSAS->isThreadPrivate(VD)) {
15978 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
15979 SemaRef.
Diag(ELoc, diag::err_omp_threadprivate_in_clause)
15994 true, CurComponents, CKind))
15996 if (CKind == OMPC_map &&
15998 false, CurComponents, CKind))
16005 auto I = llvm::find_if(
16010 assert(I != CurComponents.end() &&
"Null decl on map clause.");
16020 Type = ATy->getElementType();
16036 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
16038 if (CKind == OMPC_map) {
16044 if (DKind == OMPD_target_enter_data &&
16045 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
16046 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16047 << (IsMapTypeImplicit ? 1 : 0)
16049 << getOpenMPDirectiveName(DKind);
16057 if (DKind == OMPD_target_exit_data &&
16058 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
16059 MapType == OMPC_MAP_delete)) {
16060 SemaRef.
Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16061 << (IsMapTypeImplicit ? 1 : 0)
16063 << getOpenMPDirectiveName(DKind);
16075 if (VD && ((SemaRef.
LangOpts.OpenMP <= 45 &&
16077 DKind == OMPD_target)) {
16078 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD,
false);
16080 SemaRef.
Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16083 << getOpenMPDirectiveName(DSAS->getCurrentDirective());
16092 SemaRef, DSAS->
getCurScope(), MapperIdScopeSpec, MapperId,
16093 Type.getCanonicalType(), UnresolvedMapper);
16096 MVLI.UDMapperList.push_back(ER.
get());
16099 MVLI.ProcessedVarList.push_back(RE);
16103 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
16109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16110 MVLI.VarComponents.back().append(CurComponents.begin(),
16111 CurComponents.end());
16112 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ?
nullptr 16126 OMPC_MAP_MODIFIER_unknown};
16130 unsigned Count = 0;
16131 for (
unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
16132 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
16133 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
16134 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
16138 "Modifiers exceed the allowed number of map type modifiers");
16139 Modifiers[Count] = MapTypeModifiers[I];
16140 ModifiersLoc[Count] = MapTypeModifiersLoc[I];
16144 MappableVarListInfo MVLI(VarList);
16146 MapperIdScopeSpec, MapperId, UnresolvedMappers,
16147 MapType, IsMapTypeImplicit);
16152 MVLI.VarBaseDeclarations, MVLI.VarComponents,
16153 MVLI.UDMapperList, Modifiers, ModifiersLoc,
16155 MapperId, MapType, IsMapTypeImplicit, MapLoc);
16162 QualType ReductionType = GetTypeFromParser(ParsedType.
get());
16163 if (ReductionType.isNull())
16170 if (ReductionType.hasQualifiers()) {
16171 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
16175 if (ReductionType->isFunctionType()) {
16176 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
16179 if (ReductionType->isReferenceType()) {
16180 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
16183 if (ReductionType->isArrayType()) {
16184 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
16187 return ReductionType;
16192 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
16195 Decls.reserve(ReductionTypes.size());
16198 forRedeclarationInCurContext());
16203 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16205 bool InCompoundScope =
true;
16206 if (S !=
nullptr) {
16212 LookupName(Lookup, S);
16213 FilterLookupForScope(Lookup, DC, S,
false,
16215 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
16218 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.
next());
16219 if (InCompoundScope) {
16220 auto I = UsedAsPrevious.find(PrevDecl);
16221 if (I == UsedAsPrevious.end())
16222 UsedAsPrevious[PrevDecl] =
false;
16224 UsedAsPrevious[D] =
true;
16226 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16227 PrevDecl->getLocation();
16230 if (InCompoundScope) {
16231 for (
const auto &PrevData : UsedAsPrevious) {
16232 if (!PrevData.second) {
16233 PrevDRD = PrevData.first;
16238 }
else if (PrevDeclInScope !=
nullptr) {
16239 auto *PrevDRDInScope = PrevDRD =
16240 cast<OMPDeclareReductionDecl>(PrevDeclInScope);
16242 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
16244 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
16245 }
while (PrevDRDInScope !=
nullptr);
16247 for (
const auto &TyData : ReductionTypes) {
16248 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
16249 bool Invalid =
false;
16250 if (I != PreviousRedeclTypes.end()) {
16251 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
16253 Diag(I->second, diag::note_previous_definition);
16256 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
16258 Name, TyData.first, PrevDRD);
16260 DRD->setAccess(AS);
16261 Decls.push_back(DRD);
16263 DRD->setInvalidDecl();
16268 return DeclGroupPtrTy::make(
16273 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16276 PushFunctionScope();
16277 setFunctionHasBranchProtectedScope();
16278 getCurFunction()->setHasOMPDeclareReductionCombiner();
16281 PushDeclContext(S, DRD);
16285 PushExpressionEvaluationContext(
16286 ExpressionEvaluationContext::PotentiallyEvaluated);
16288 QualType ReductionType = DRD->getType();
16305 if (S !=
nullptr) {
16306 PushOnScopeChains(OmpInParm, S);
16307 PushOnScopeChains(OmpOutParm, S);
16309 DRD->addDecl(OmpInParm);
16310 DRD->addDecl(OmpOutParm);
16316 DRD->setCombinerData(InE, OutE);
16320 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16321 DiscardCleanupsInEvaluationContext();
16322 PopExpressionEvaluationContext();
16325 PopFunctionScopeInfo();
16327 if (Combiner !=
nullptr)
16328 DRD->setCombiner(Combiner);
16330 DRD->setInvalidDecl();
16334 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16337 PushFunctionScope();
16338 setFunctionHasBranchProtectedScope();
16341 PushDeclContext(S, DRD);
16345 PushExpressionEvaluationContext(
16346 ExpressionEvaluationContext::PotentiallyEvaluated);
16348 QualType ReductionType = DRD->getType();
16365 if (S !=
nullptr) {
16366 PushOnScopeChains(OmpPrivParm, S);
16367 PushOnScopeChains(OmpOrigParm, S);
16369 DRD->addDecl(OmpPrivParm);
16370 DRD->addDecl(OmpOrigParm);
16376 DRD->setInitializerData(OrigE, PrivE);
16377 return OmpPrivParm;
16382 auto *DRD = cast<OMPDeclareReductionDecl>(D);
16383 DiscardCleanupsInEvaluationContext();
16384 PopExpressionEvaluationContext();
16387 PopFunctionScopeInfo();
16389 if (Initializer !=
nullptr) {
16391 }
else if (OmpPrivParm->
hasInit()) {
16392 DRD->setInitializer(OmpPrivParm->
getInit(),
16397 DRD->setInvalidDecl();
16403 for (
Decl *D : DeclReductions.
get()) {
16406 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
16412 return DeclReductions;
16421 if (getLangOpts().CPlusPlus) {
16423 CheckExtraCXXDefaultArguments(D);
16426 return CreateParsedType(T, TInfo);
16431 assert(ParsedType.
isUsable() &&
"Expect usable parsed mapper type");
16433 QualType MapperType = GetTypeFromParser(ParsedType.
get());
16434 assert(!MapperType.isNull() &&
"Expect valid mapper type");
16438 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
16439 Diag(TyLoc, diag::err_omp_mapper_wrong_type);
16448 Decl *PrevDeclInScope) {
16450 forRedeclarationInCurContext());
16455 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16457 bool InCompoundScope =
true;
16458 if (S !=
nullptr) {
16464 LookupName(Lookup, S);
16465 FilterLookupForScope(Lookup, DC, S,
false,
16467 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
16470 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.
next());
16471 if (InCompoundScope) {
16472 auto I = UsedAsPrevious.find(PrevDecl);
16473 if (I == UsedAsPrevious.end())
16474 UsedAsPrevious[PrevDecl] =
false;
16476 UsedAsPrevious[D] =
true;
16478 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16479 PrevDecl->getLocation();
16482 if (InCompoundScope) {
16483 for (
const auto &PrevData : UsedAsPrevious) {
16484 if (!PrevData.second) {
16485 PrevDMD = PrevData.first;
16490 }
else if (PrevDeclInScope) {
16491 auto *PrevDMDInScope = PrevDMD =
16492 cast<OMPDeclareMapperDecl>(PrevDeclInScope);
16494 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
16496 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
16497 }
while (PrevDMDInScope !=
nullptr);
16500 bool Invalid =
false;
16501 if (I != PreviousRedeclTypes.end()) {
16502 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
16503 << MapperType << Name;
16504 Diag(I->second, diag::note_previous_definition);
16508 MapperType, VN, PrevDMD);
16510 DMD->setAccess(AS);
16512 DMD->setInvalidDecl();
16515 PushFunctionScope();
16516 setFunctionHasBranchProtectedScope();
16530 PushOnScopeChains(VD, S);
16541 PopFunctionScopeInfo();
16545 PushOnScopeChains(D, S,
false);
16556 Expr *ValExpr = NumTeams;
16557 Stmt *HelperValStmt =
nullptr;
16568 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16569 ValExpr = MakeFullExpr(ValExpr).get();
16570 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16571 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16576 StartLoc, LParenLoc, EndLoc);
16583 Expr *ValExpr = ThreadLimit;
16584 Stmt *HelperValStmt =
nullptr;
16594 DKind, OMPC_thread_limit, LangOpts.OpenMP);
16595 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16596 ValExpr = MakeFullExpr(ValExpr).get();
16597 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16598 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16603 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16611 Stmt *HelperValStmt =
nullptr;
16617 ValExpr, *
this, OMPC_priority,
16619 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16623 StartLoc, LParenLoc, EndLoc);
16630 Expr *ValExpr = Grainsize;
16631 Stmt *HelperValStmt =
nullptr;
16638 ValExpr, *
this, OMPC_grainsize,
16640 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16644 StartLoc, LParenLoc, EndLoc);
16651 Expr *ValExpr = NumTasks;
16652 Stmt *HelperValStmt =
nullptr;
16659 ValExpr, *
this, OMPC_num_tasks,
16661 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16665 StartLoc, LParenLoc, EndLoc);
16674 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
16677 return new (Context)
16686 std::string Values;
16690 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16694 Expr *ValExpr = ChunkSize;
16695 Stmt *HelperValStmt =
nullptr;
16702 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16706 ValExpr = Val.
get();
16713 if (Result.isSigned() && !Result.isStrictlyPositive()) {
16714 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16719 DSAStack->getCurrentDirective(), OMPC_dist_schedule,
16720 LangOpts.OpenMP) != OMPD_unknown &&
16721 !CurContext->isDependentContext()) {
16722 ValExpr = MakeFullExpr(ValExpr).get();
16723 llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16724 ValExpr = tryBuildCapture(*
this, ValExpr, Captures).get();
16730 return new (Context)
16732 Kind, ValExpr, HelperValStmt);
16739 if (getLangOpts().OpenMP < 50) {
16740 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
16741 Kind != OMPC_DEFAULTMAP_scalar) {
16745 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
16747 OMPC_DEFAULTMAP_MODIFIER_tofrom);
16751 OMPC_DEFAULTMAP_scalar);
16755 Diag(Loc, diag::err_omp_unexpected_clause_value)
16762 if (!isDefaultmapKind || !isDefaultmapModifier) {
16763 std::string ModifierValue =
"'alloc', 'from', 'to', 'tofrom', " 16764 "'firstprivate', 'none', 'default'";
16765 std::string KindValue =
"'scalar', 'aggregate', 'pointer'";
16766 if (!isDefaultmapKind && isDefaultmapModifier) {
16767 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16769 }
else if (isDefaultmapKind && !isDefaultmapModifier) {
16770 Diag(MLoc, diag::err_omp_unexpected_clause_value)
16773 Diag(MLoc, diag::err_omp_unexpected_clause_value)
16775 Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16784 if (
DSAStack->checkDefaultmapCategory(Kind)) {
16785 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
16789 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
16791 return new (Context)
16796 DeclContext *CurLexicalContext = getCurLexicalContext();
16800 !isa<CXXRecordDecl>(CurLexicalContext) &&
16801 !isa<ClassTemplateDecl>(CurLexicalContext) &&
16802 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
16803 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
16804 Diag(Loc, diag::err_omp_region_not_file_context);
16807 ++DeclareTargetNestingLevel;
16812 assert(DeclareTargetNestingLevel > 0 &&
16813 "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
16814 --DeclareTargetNestingLevel;
16822 LookupParsedName(Lookup, CurScope, &ScopeSpec,
true);
16829 VarOrFuncDeclFilterCCC CCC(*
this);
16831 CorrectTypo(Id, LookupOrdinaryName, CurScope,
nullptr, CCC,
16832 CTK_ErrorRecovery)) {
16833 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
16835 checkDeclIsAllowedInOpenMPTarget(
nullptr, Corrected.getCorrectionDecl());
16844 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
16845 !isa<FunctionTemplateDecl>(ND)) {
16856 OMPDeclareTargetDeclAttr::DevTypeTy DT) {
16857 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
16858 isa<FunctionTemplateDecl>(ND)) &&
16859 "Expected variable, function or function template.");
16863 if (LangOpts.OpenMP >= 50 &&
16865 Diag(Loc, diag::warn_omp_declare_target_after_first_use);
16868 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
16869 if (DevTy.hasValue() && *DevTy != DT) {
16870 Diag(Loc, diag::err_omp_device_type_mismatch)
16871 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
16872 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
16876 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
16878 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
16882 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
16883 checkDeclIsAllowedInOpenMPTarget(
nullptr, ND, Loc);
16884 }
else if (*Res != MT) {
16885 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
16891 if (!D || !isa<VarDecl>(D))
16893 auto *VD = cast<VarDecl>(D);
16895 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16896 if (SemaRef.
LangOpts.OpenMP >= 50 &&
16899 VD->hasGlobalStorage()) {
16901 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16902 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
16908 SemaRef.
Diag(VD->getLocation(),
16909 diag::err_omp_lambda_capture_in_declare_target_not_to);
16910 SemaRef.
Diag(SL, diag::note_var_explicitly_captured_here)
16915 if (MapTy.hasValue())
16917 SemaRef.
Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
16918 SemaRef.
Diag(SL, diag::note_used_here) << SR;
16922 Sema &SemaRef, DSAStackTy *Stack,
16924 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
16935 if (
auto *VD = dyn_cast<VarDecl>(D)) {
16937 if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
16938 !VD->isStaticDataMember())
16942 if (
DSAStack->isThreadPrivate(VD)) {
16943 Diag(SL, diag::err_omp_threadprivate_in_target);
16948 if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
16949 D = FTD->getTemplatedDecl();
16950 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
16952 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
16953 if (IdLoc.
isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
16954 Diag(IdLoc, diag::err_omp_function_in_link_clause);
16955 Diag(FD->getLocation(), diag::note_defined_here) << FD;
16960 OMPDeclareTargetDeclAttr::getDeviceType(FD);
16961 if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.
isValid() &&
16962 *DevTy != OMPDeclareTargetDeclAttr::DT_Host)
16963 checkOpenMPDeviceFunction(IdLoc, FD,
false);
16964 if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.
isValid() &&
16965 *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost)
16966 checkOpenMPHostFunction(IdLoc, FD,
false);
16968 if (
auto *VD = dyn_cast<ValueDecl>(D)) {
16974 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
16976 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
16977 isa<FunctionTemplateDecl>(D)) {
16978 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
16979 Context, OMPDeclareTargetDeclAttr::MT_To,
16980 OMPDeclareTargetDeclAttr::DT_Any,
SourceRange(IdLoc, IdLoc));
16983 ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
16998 MappableVarListInfo MVLI(VarList);
17000 MapperIdScopeSpec, MapperId, UnresolvedMappers);
17001 if (MVLI.ProcessedVarList.empty())
17005 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17006 MVLI.VarComponents, MVLI.UDMapperList,
17015 MappableVarListInfo MVLI(VarList);
17017 MapperIdScopeSpec, MapperId, UnresolvedMappers);
17018 if (MVLI.ProcessedVarList.empty())
17022 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17023 MVLI.VarComponents, MVLI.UDMapperList,
17029 MappableVarListInfo MVLI(VarList);
17033 for (
Expr *RefExpr : VarList) {
17034 assert(RefExpr &&
"NULL expr in OpenMP use_device_ptr clause.");
17037 Expr *SimpleRefExpr = RefExpr;
17041 MVLI.ProcessedVarList.push_back(RefExpr);
17042 PrivateCopies.push_back(
nullptr);
17043 Inits.push_back(
nullptr);
17052 auto *VD = dyn_cast<
VarDecl>(D);
17056 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
17065 VD ? cast<DeclRefExpr>(SimpleRefExpr) :
nullptr);
17066 if (VDPrivate->isInvalidDecl())
17069 CurContext->addDecl(VDPrivate);
17078 AddInitializerToDecl(VDPrivate,
17079 DefaultLvalueConversion(VDInitRefExpr).
get(),
17087 MVLI.ProcessedVarList.push_back(VD ? RefExpr->
IgnoreParens() : Ref);
17088 PrivateCopies.push_back(VDPrivateRefExpr);
17089 Inits.push_back(VDInitRefExpr);
17098 MVLI.VarBaseDeclarations.push_back(D);
17099 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17100 MVLI.VarComponents.back().push_back(
17104 if (MVLI.ProcessedVarList.empty())
17108 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
17109 MVLI.VarBaseDeclarations, MVLI.VarComponents);
17114 MappableVarListInfo MVLI(VarList);
17115 for (
Expr *RefExpr : VarList) {
17116 assert(RefExpr &&
"NULL expr in OpenMP is_device_ptr clause.");
17119 Expr *SimpleRefExpr = RefExpr;
17123 MVLI.ProcessedVarList.push_back(RefExpr);
17133 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
17140 DSAStackTy::DSAVarData DVar =
DSAStack->getTopDSA(D,
false);
17142 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17145 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
17150 const Expr *ConflictExpr;
17151 if (
DSAStack->checkMappableExprComponentListsForDecl(
17156 ConflictExpr = R.front().getAssociatedExpression();
17168 DSAStack->addMappableExpressionComponents(
17169 D, MC, OMPC_is_device_ptr);
17172 MVLI.ProcessedVarList.push_back(SimpleRefExpr);
17177 assert((isa<DeclRefExpr>(SimpleRefExpr) ||
17178 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
17179 "Unexpected device pointer expression!");
17180 MVLI.VarBaseDeclarations.push_back(
17181 isa<DeclRefExpr>(SimpleRefExpr) ? D :
nullptr);
17182 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17183 MVLI.VarComponents.back().push_back(MC);
17186 if (MVLI.ProcessedVarList.empty())
17190 MVLI.VarBaseDeclarations,
17191 MVLI.VarComponents);
17203 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
17206 AllocatorRes = PerformImplicitConversion(AllocatorRes.
get(),
17207 DSAStack->getOMPAllocatorHandleT(),
17212 Allocator = AllocatorRes.
get();
17219 if (LangOpts.OpenMPIsDevice &&
17221 targetDiag(StartLoc, diag::err_expected_allocator_expression);
17225 for (
Expr *RefExpr : VarList) {
17226 assert(RefExpr &&
"NULL expr in OpenMP private clause.");
17229 Expr *SimpleRefExpr = RefExpr;
17233 Vars.push_back(RefExpr);
17239 auto *VD = dyn_cast<
VarDecl>(D);
17241 if (!VD && !CurContext->isDependentContext())
17243 Vars.push_back((VD || CurContext->isDependentContext())
17252 ColonLoc, EndLoc, Vars);
17260 for (
Expr *RefExpr : VarList) {
17261 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
17264 Expr *SimpleRefExpr = RefExpr;
17268 Vars.push_back(RefExpr);
17275 if (
const Expr *PrevRef =
17276 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
17277 Diag(ELoc, diag::err_omp_used_in_clause_twice)
17279 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17284 Vars.push_back(RefExpr);
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
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
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.
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()))
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false)
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. '#pragma omp declare target'.
Struct to store the context selectors info.
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...
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop simd' after parsing of the associated sta...
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)
static OMPParallelMasterTaskLoopDirective * 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.
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.
FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl)
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.
FullExprArg MakeFullExpr(Expr *Arg)
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.
Optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR)
Checks '#pragma omp declare variant' variant function and original functions after parsing of the ass...
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).
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop simd' after parsing of the associated statement...
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...
static OMPMasterTaskLoopDirective * 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.
A container of type source information.
This represents 'update' clause in the '#pragma omp atomic' directive.
Wrapper for void* pointer.
llvm::DenseMap< Stmt *, Stmt * > MapTy
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.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
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.
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)
QualType getElementType() const
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr *> Vars, Expr *TailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, bool IsMapTypeImplicit, SourceLocation DepLinMapLastLoc)
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...
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
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
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.
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
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)
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
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)
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)
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
bool hasDefinition() const
This represents 'reverse_offload' clause in the '#pragma omp requires' directive. ...
Represents a parameter to a function.
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.
static OMPMasterTaskLoopSimdDirective * 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 '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()
unsigned varlist_size() const
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.
DeviceDiagBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID)
Creates a DeviceDiagBuilder that emits the diagnostic if the current context is "used as host code"...
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.
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop, taksloop simd, master taskloop, parallel master taskloop, master taskloop simd, or parallel master taskloop simd.
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Represents a member of a struct/union/class.
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
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...
OpenMPContextSelectorKind
OpenMP context selectors.
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...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
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
ArrayRef< ParmVarDecl * > parameters() 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.
OpenMPContextSelectorSetKind
OpenMP context selector sets.
DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID)
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
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.
bool isReferenced() const
Whether any declaration of this entity was referenced.
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...
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
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.
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.
__ptr16, alignas(...), etc.
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.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' 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.
SmallVector< Expr *, 4 > FinalsConditions
List of final conditions required for the generation of the non-rectangular loops.
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.
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
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.
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
unsigned operator()(argument_type DK)
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.
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, OMPDeclareTargetDeclAttr::DevTypeTy DT)
Called on correct id-expression from the '#pragma omp declare target'.
Allows QualTypes to be sorted and hence used in maps and sets.
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
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 isFunctionNoProtoType() const
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.
SmallVector< Expr *, 4 > DependentInits
List of initializers required for the generation of the non-rectangular loops.
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.
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp parallel master taskloop' after parsing of the associated statemen...
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.
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...
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
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.
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.
static Stmt * tryToFindNextInnerLoop(Stmt *CurStmt, bool TryImperfectlyNestedLoops)
Try to find the next loop sub-statement in the specified statement CurStmt.
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.
OpenMPDirectiveKind argument_type
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.
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
QualType getCanonicalType() const
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, SourceRange SR, ArrayRef< OMPCtxSelectorData > Data)
Called on well-formed '#pragma omp declare variant' after parsing of the associated method/function...
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).
FunctionEmissionStatus
Status of the function emission on the host/device.
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)
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.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
Represents a static or instance method of a struct/union/class.
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 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.
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed '#pragma omp master taskloop' after parsing of the associated statement...
Stmt * getCapturedStmt()
Retrieve the statement being captured.
bool isFunctionProtoType() const
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.
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Expr * LB
LowerBound - local variable passed to runtime.
void clear(unsigned Size)
Initialize all the fields to null.
Expr * Init
Loop iteration variable init.
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp target parallel' after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'simd' clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
QualType withRestrict() const
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed 'unified_address' clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
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.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
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)...
static ImplicitConversionSequence TryImplicitConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit)
TryImplicitConversion - Attempt to perform an implicit conversion from the given expression (Expr) to...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
const Scope * getParent() const
getParent - Return the scope that this is nested in.
void ActOnCapturedRegionError()
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for 'atomic_default_mem_order' clause.
SmallVector< Expr *, 4 > DependentCounters
List of counters required for the generation of the non-rectangular loops.
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)
This represents 'unified_shared_memory' clause in the '#pragma omp requires' directive.
This represents clause 'linear' in the '#pragma omp ...' directives.
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build 'VarRef = Start.
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...
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
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)
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
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.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
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 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 ...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
bool isSet() const
Deprecated.
Expr * UB
DistributeUpperBound - used when composing 'omp distribute' with 'omp for' in a same construct...
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
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.
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, NamedDeclSetType &SameDirectiveDecls)
Searches for the provided declaration name for OpenMP declare target directive.
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'.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build 'VarRef = Start + Iter * Step'.
Expr * UB
UpperBound - local variable passed to runtime.
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
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)
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'.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
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.
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed '#pragma omp parallel master' after parsing of the associated statement...
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.
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
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...
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Stmt * PreInits
Init statement for all captured expressions.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
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.
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.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
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
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
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.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
void setType(QualType newType)
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.
static OMPParallelMasterTaskLoopSimdDirective * 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.
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.
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.
static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
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).