37#include "llvm/ADT/IndexedMap.h"
38#include "llvm/ADT/PointerEmbeddedInt.h"
39#include "llvm/ADT/STLExtras.h"
40#include "llvm/ADT/SmallSet.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/Frontend/OpenMP/OMPAssume.h"
43#include "llvm/Frontend/OpenMP/OMPConstants.h"
48using namespace llvm::omp;
61enum DefaultDataSharingAttributes {
66 DSA_firstprivate = 1 << 3,
76 unsigned Modifier = 0;
77 const Expr *RefExpr =
nullptr;
80 bool AppliedToPointee =
false;
81 DSAVarData() =
default;
85 bool AppliedToPointee)
86 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88 AppliedToPointee(AppliedToPointee) {}
90 using OperatorOffsetTy =
92 using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
94 enum class UsesAllocatorsDeclKind {
106 unsigned Modifier = 0;
109 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
113 bool AppliedToPointee =
false;
115 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
116 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
117 using LCDeclInfo = std::pair<unsigned, VarDecl *>;
118 using LoopControlVariablesMapTy =
119 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
122 struct MappedExprComponentTy {
126 using MappedExprComponentsTy =
127 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
128 using CriticalsWithHintsTy =
129 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
130 struct ReductionData {
131 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
133 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
134 ReductionData() =
default;
141 ReductionOp = RefExpr;
144 using DeclReductionMapTy =
145 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
146 struct DefaultmapInfo {
150 DefaultmapInfo() =
default;
152 : ImplicitBehavior(M), SLoc(Loc) {}
155 struct SharingMapTy {
156 DeclSAMapTy SharingMap;
157 DeclReductionMapTy ReductionMap;
158 UsedRefMapTy AlignedMap;
159 UsedRefMapTy NontemporalMap;
160 MappedExprComponentsTy MappedExprComponents;
161 LoopControlVariablesMapTy LCVMap;
162 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
171 Scope *CurScope =
nullptr;
177 DoacrossClauseMapTy DoacrossDepends;
181 std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182 bool RegionHasOrderConcurrent =
false;
183 unsigned AssociatedLoops = 1;
184 bool HasMutipleLoops =
false;
185 const Decl *PossiblyLoopCounter =
nullptr;
186 bool NowaitRegion =
false;
187 bool UntiedRegion =
false;
188 bool CancelRegion =
false;
189 bool LoopStart =
false;
190 bool BodyComplete =
false;
195 Expr *TaskgroupReductionRef =
nullptr;
204 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
208 struct ImplicitDefaultFDInfoTy {
212 size_t StackLevel = 0;
215 ImplicitDefaultFDInfoTy(
const FieldDecl *FD,
size_t StackLevel,
217 : FD(FD), StackLevel(StackLevel), VD(VD) {}
221 ImplicitDefaultFirstprivateFDs;
222 Expr *DeclareMapperVar =
nullptr;
226 :
Directive(DKind), DirectiveName(Name), CurScope(CurScope),
228 SharingMapTy() =
default;
234 DeclSAMapTy Threadprivates;
241 bool ForceCapturing =
false;
244 bool ForceCaptureByReferenceInTargetExecutable =
false;
245 CriticalsWithHintsTy Criticals;
246 unsigned IgnoredStackElements = 0;
250 using const_iterator = StackTy::const_reverse_iterator;
251 const_iterator begin()
const {
252 return Stack.empty() ? const_iterator()
253 : Stack.back().first.rbegin() + IgnoredStackElements;
255 const_iterator end()
const {
256 return Stack.empty() ? const_iterator() : Stack.back().first.rend();
258 using iterator = StackTy::reverse_iterator;
260 return Stack.empty() ? iterator()
261 : Stack.back().first.rbegin() + IgnoredStackElements;
264 return Stack.empty() ? iterator() : Stack.back().first.rend();
269 bool isStackEmpty()
const {
270 return Stack.empty() ||
271 Stack.back().second != CurrentNonCapturingFunctionScope ||
272 Stack.back().first.size() <= IgnoredStackElements;
274 size_t getStackSize()
const {
275 return isStackEmpty() ? 0
276 : Stack.back().first.size() - IgnoredStackElements;
279 SharingMapTy *getTopOfStackOrNull() {
280 size_t Size = getStackSize();
283 return &Stack.back().first[
Size - 1];
285 const SharingMapTy *getTopOfStackOrNull()
const {
286 return const_cast<DSAStackTy &
>(*this).getTopOfStackOrNull();
288 SharingMapTy &getTopOfStack() {
289 assert(!isStackEmpty() &&
"no current directive");
290 return *getTopOfStackOrNull();
292 const SharingMapTy &getTopOfStack()
const {
293 return const_cast<DSAStackTy &
>(*this).getTopOfStack();
296 SharingMapTy *getSecondOnStackOrNull() {
297 size_t Size = getStackSize();
300 return &Stack.back().first[
Size - 2];
302 const SharingMapTy *getSecondOnStackOrNull()
const {
303 return const_cast<DSAStackTy &
>(*this).getSecondOnStackOrNull();
312 SharingMapTy &getStackElemAtLevel(
unsigned Level) {
313 assert(Level < getStackSize() &&
"no such stack element");
314 return Stack.back().first[
Level];
316 const SharingMapTy &getStackElemAtLevel(
unsigned Level)
const {
317 return const_cast<DSAStackTy &
>(*this).getStackElemAtLevel(Level);
323 bool isOpenMPLocal(
VarDecl *D, const_iterator
Iter)
const;
336 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
345 explicit DSAStackTy(
Sema &S) : SemaRef(S) {}
348 void setOMPAllocatorHandleT(
QualType Ty) { OMPAllocatorHandleT = Ty; }
350 QualType getOMPAllocatorHandleT()
const {
return OMPAllocatorHandleT; }
352 void setOMPAlloctraitT(
QualType Ty) { OMPAlloctraitT = Ty; }
354 QualType getOMPAlloctraitT()
const {
return OMPAlloctraitT; }
356 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
358 OMPPredefinedAllocators[AllocatorKind] = Allocator;
361 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind)
const {
362 return OMPPredefinedAllocators[AllocatorKind];
365 void setOMPDependT(
QualType Ty) { OMPDependT = Ty; }
367 QualType getOMPDependT()
const {
return OMPDependT; }
370 void setOMPEventHandleT(
QualType Ty) { OMPEventHandleT = Ty; }
372 QualType getOMPEventHandleT()
const {
return OMPEventHandleT; }
374 bool isClauseParsingMode()
const {
return ClauseKindMode != OMPC_unknown; }
376 assert(isClauseParsingMode() &&
"Must be in clause parsing mode.");
377 return ClauseKindMode;
381 bool isBodyComplete()
const {
382 const SharingMapTy *Top = getTopOfStackOrNull();
383 return Top && Top->BodyComplete;
385 void setBodyComplete() { getTopOfStack().BodyComplete =
true; }
387 bool isForceVarCapturing()
const {
return ForceCapturing; }
388 void setForceVarCapturing(
bool V) { ForceCapturing =
V; }
390 void setForceCaptureByReferenceInTargetExecutable(
bool V) {
391 ForceCaptureByReferenceInTargetExecutable =
V;
393 bool isForceCaptureByReferenceInTargetExecutable()
const {
394 return ForceCaptureByReferenceInTargetExecutable;
399 assert(!IgnoredStackElements &&
400 "cannot change stack while ignoring elements");
402 Stack.back().second != CurrentNonCapturingFunctionScope)
403 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405 Stack.back().first.back().DefaultAttrLoc = Loc;
409 assert(!IgnoredStackElements &&
410 "cannot change stack while ignoring elements");
411 assert(!Stack.back().first.empty() &&
412 "Data-sharing attributes stack is empty!");
413 Stack.back().first.pop_back();
418 class ParentDirectiveScope {
423 ParentDirectiveScope(DSAStackTy &Self,
bool Activate)
424 : Self(Self), Active(
false) {
428 ~ParentDirectiveScope() { disable(); }
431 --Self.IgnoredStackElements;
437 ++Self.IgnoredStackElements;
446 "Expected loop-based directive.");
447 getTopOfStack().LoopStart =
true;
452 "Expected loop-based directive.");
453 getTopOfStack().LoopStart =
false;
456 bool isLoopStarted()
const {
458 "Expected loop-based directive.");
459 return !getTopOfStack().LoopStart;
462 void resetPossibleLoopCounter(
const Decl *D =
nullptr) {
463 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
466 const Decl *getPossiblyLoopCunter()
const {
467 return getTopOfStack().PossiblyLoopCounter;
470 void pushFunction() {
471 assert(!IgnoredStackElements &&
472 "cannot change stack while ignoring elements");
474 assert(!isa<CapturingScopeInfo>(CurFnScope));
475 CurrentNonCapturingFunctionScope = CurFnScope;
479 assert(!IgnoredStackElements &&
480 "cannot change stack while ignoring elements");
481 if (!Stack.empty() && Stack.back().second == OldFSI) {
482 assert(Stack.back().first.empty());
485 CurrentNonCapturingFunctionScope =
nullptr;
487 if (!isa<CapturingScopeInfo>(FSI)) {
488 CurrentNonCapturingFunctionScope = FSI;
497 const std::pair<const OMPCriticalDirective *, llvm::APSInt>
499 auto I = Criticals.find(Name.getAsString());
500 if (I != Criticals.end())
502 return std::make_pair(
nullptr, llvm::APSInt());
519 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D)
const;
524 const LCDeclInfo isParentLoopControlVariable(
const ValueDecl *D)
const;
529 const LCDeclInfo isLoopControlVariable(
const ValueDecl *D,
530 unsigned Level)
const;
533 const ValueDecl *getParentLoopControlVariable(
unsigned I)
const;
536 void markDeclAsUsedInScanDirective(
ValueDecl *D) {
537 if (SharingMapTy *Stack = getSecondOnStackOrNull())
538 Stack->UsedInScanDirective.insert(D);
542 bool isUsedInScanDirective(
ValueDecl *D)
const {
543 if (
const SharingMapTy *Stack = getTopOfStackOrNull())
544 return Stack->UsedInScanDirective.contains(D);
550 DeclRefExpr *PrivateCopy =
nullptr,
unsigned Modifier = 0,
551 bool AppliedToPointee =
false);
560 const Expr *ReductionRef);
566 Expr *&TaskgroupDescriptor)
const;
571 const Expr *&ReductionRef,
572 Expr *&TaskgroupDescriptor)
const;
575 Expr *getTaskgroupReductionRef()
const {
576 assert((getTopOfStack().
Directive == OMPD_taskgroup ||
580 "taskgroup reference expression requested for non taskgroup or "
581 "parallel/worksharing directive.");
582 return getTopOfStack().TaskgroupReductionRef;
586 bool isTaskgroupReductionRef(
const ValueDecl *VD,
unsigned Level)
const {
587 return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
594 const DSAVarData getTopDSA(
ValueDecl *D,
bool FromParent);
596 const DSAVarData getImplicitDSA(
ValueDecl *D,
bool FromParent)
const;
598 const DSAVarData getImplicitDSA(
ValueDecl *D,
unsigned Level)
const;
605 DefaultDataSharingAttributes)>
608 bool FromParent)
const;
616 bool FromParent)
const;
623 unsigned Level,
bool NotLastprivate =
false)
const;
627 bool hasExplicitDirective(
629 unsigned Level)
const;
633 const llvm::function_ref<
bool(
636 bool FromParent)
const;
640 const SharingMapTy *Top = getTopOfStackOrNull();
641 return Top ? Top->Directive : OMPD_unknown;
644 const SharingMapTy *Top = getTopOfStackOrNull();
645 return Top ? Top->MappedDirective : OMPD_unknown;
648 SharingMapTy *Top = getTopOfStackOrNull();
650 "Before calling setCurrentDirective Top of Stack not to be NULL.");
652 Top->Directive = NewDK;
655 SharingMapTy *Top = getTopOfStackOrNull();
657 "Before calling setMappedDirective Top of Stack not to be NULL.");
659 Top->MappedDirective = NewDK;
663 assert(!isStackEmpty() &&
"No directive at specified level.");
664 return getStackElemAtLevel(Level).Directive;
668 unsigned OpenMPCaptureLevel)
const {
671 return CaptureRegions[OpenMPCaptureLevel];
675 const SharingMapTy *
Parent = getSecondOnStackOrNull();
680 void addRequiresDecl(
OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
683 template <
typename ClauseType>
bool hasRequiresDeclWithClause()
const {
686 return isa<ClauseType>(C);
694 bool IsDuplicate =
false;
697 for (
const OMPClause *CPrev : D->clauselists()) {
698 if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699 SemaRef.
Diag(CNew->getBeginLoc(),
700 diag::err_omp_requires_clause_redeclaration)
701 << getOpenMPClauseName(CNew->getClauseKind());
702 SemaRef.
Diag(CPrev->getBeginLoc(),
703 diag::note_omp_requires_previous_clause)
704 << getOpenMPClauseName(CPrev->getClauseKind());
715 TargetLocations.push_back(LocStart);
721 AtomicLocation = Loc;
726 SourceLocation getAtomicDirectiveLoc()
const {
return AtomicLocation; }
730 return TargetLocations;
735 getTopOfStack().DefaultAttr = DSA_none;
736 getTopOfStack().DefaultAttrLoc = Loc;
740 getTopOfStack().DefaultAttr = DSA_shared;
741 getTopOfStack().DefaultAttrLoc = Loc;
745 getTopOfStack().DefaultAttr = DSA_private;
746 getTopOfStack().DefaultAttrLoc = Loc;
750 getTopOfStack().DefaultAttr = DSA_firstprivate;
751 getTopOfStack().DefaultAttrLoc = Loc;
756 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[
Kind];
757 DMI.ImplicitBehavior = M;
763 return getTopOfStack()
764 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
767 .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
770 .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
772 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
777 return ConstructTraits;
782 ConstructTraits.append(Traits.begin(), Traits.end());
784 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
785 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786 assert(Top == Trait &&
"Something left a trait on the stack!");
792 DefaultDataSharingAttributes getDefaultDSA(
unsigned Level)
const {
793 return getStackSize() <=
Level ? DSA_unspecified
794 : getStackElemAtLevel(Level).DefaultAttr;
796 DefaultDataSharingAttributes getDefaultDSA()
const {
797 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
800 return isStackEmpty() ?
SourceLocation() : getTopOfStack().DefaultAttrLoc;
804 return isStackEmpty()
806 : getTopOfStack().DefaultmapMap[
Kind].ImplicitBehavior;
809 getDefaultmapModifierAtLevel(
unsigned Level,
811 return getStackElemAtLevel(Level).DefaultmapMap[
Kind].ImplicitBehavior;
813 bool isDefaultmapCapturedByRef(
unsigned Level,
816 getDefaultmapModifierAtLevel(Level, Kind);
817 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
818 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819 (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
820 (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
821 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
828 case OMPC_DEFAULTMAP_scalar:
829 case OMPC_DEFAULTMAP_pointer:
831 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
832 (M == OMPC_DEFAULTMAP_MODIFIER_default);
833 case OMPC_DEFAULTMAP_aggregate:
834 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
838 llvm_unreachable(
"Unexpected OpenMPDefaultmapClauseKind enum");
840 bool mustBeFirstprivateAtLevel(
unsigned Level,
843 getDefaultmapModifierAtLevel(Level, Kind);
844 return mustBeFirstprivateBase(M, Kind);
848 return mustBeFirstprivateBase(M, Kind);
852 bool isThreadPrivate(
VarDecl *D) {
853 const DSAVarData DVar = getTopDSA(D,
false);
858 void setOrderedRegion(
bool IsOrdered,
const Expr *Param,
861 getTopOfStack().OrderedRegion.emplace(Param, Clause);
863 getTopOfStack().OrderedRegion.reset();
867 bool isOrderedRegion()
const {
868 if (
const SharingMapTy *Top = getTopOfStackOrNull())
869 return Top->OrderedRegion.has_value();
873 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam()
const {
874 if (
const SharingMapTy *Top = getTopOfStackOrNull())
875 if (Top->OrderedRegion)
876 return *Top->OrderedRegion;
877 return std::make_pair(
nullptr,
nullptr);
881 bool isParentOrderedRegion()
const {
882 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
883 return Parent->OrderedRegion.has_value();
887 std::pair<const Expr *, OMPOrderedClause *>
888 getParentOrderedRegionParam()
const {
889 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
890 if (
Parent->OrderedRegion)
891 return *
Parent->OrderedRegion;
892 return std::make_pair(
nullptr,
nullptr);
895 void setRegionHasOrderConcurrent(
bool HasOrderConcurrent) {
896 getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
900 bool isParentOrderConcurrent()
const {
901 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
902 return Parent->RegionHasOrderConcurrent;
906 void setNowaitRegion(
bool IsNowait =
true) {
907 getTopOfStack().NowaitRegion = IsNowait;
911 bool isParentNowaitRegion()
const {
912 if (
const SharingMapTy *
Parent = getSecondOnStackOrNull())
913 return Parent->NowaitRegion;
917 void setUntiedRegion(
bool IsUntied =
true) {
918 getTopOfStack().UntiedRegion = IsUntied;
921 bool isUntiedRegion()
const {
922 const SharingMapTy *Top = getTopOfStackOrNull();
923 return Top ? Top->UntiedRegion :
false;
926 void setParentCancelRegion(
bool Cancel =
true) {
927 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
928 Parent->CancelRegion |= Cancel;
931 bool isCancelRegion()
const {
932 const SharingMapTy *Top = getTopOfStackOrNull();
933 return Top ? Top->CancelRegion :
false;
938 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
939 Parent->PrevScanLocation = Loc;
942 bool doesParentHasScanDirective()
const {
943 const SharingMapTy *Top = getSecondOnStackOrNull();
944 return Top ? Top->PrevScanLocation.isValid() :
false;
948 const SharingMapTy *Top = getSecondOnStackOrNull();
953 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
954 Parent->PrevOrderedLocation = Loc;
957 bool doesParentHasOrderedDirective()
const {
958 const SharingMapTy *Top = getSecondOnStackOrNull();
959 return Top ? Top->PrevOrderedLocation.isValid() :
false;
963 const SharingMapTy *Top = getSecondOnStackOrNull();
968 void setAssociatedLoops(
unsigned Val) {
969 getTopOfStack().AssociatedLoops = Val;
971 getTopOfStack().HasMutipleLoops =
true;
974 unsigned getAssociatedLoops()
const {
975 const SharingMapTy *Top = getTopOfStackOrNull();
976 return Top ? Top->AssociatedLoops : 0;
979 bool hasMutipleLoops()
const {
980 const SharingMapTy *Top = getTopOfStackOrNull();
981 return Top ? Top->HasMutipleLoops :
false;
987 if (SharingMapTy *
Parent = getSecondOnStackOrNull())
988 Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
991 bool hasInnerTeamsRegion()
const {
992 return getInnerTeamsRegionLoc().
isValid();
996 const SharingMapTy *Top = getTopOfStackOrNull();
1000 Scope *getCurScope()
const {
1001 const SharingMapTy *Top = getTopOfStackOrNull();
1002 return Top ? Top->CurScope :
nullptr;
1004 void setContext(
DeclContext *DC) { getTopOfStack().Context = DC; }
1006 const SharingMapTy *Top = getTopOfStackOrNull();
1012 bool checkMappableExprComponentListsForDecl(
1013 const ValueDecl *VD,
bool CurrentRegionOnly,
1014 const llvm::function_ref<
1026 if (CurrentRegionOnly)
1029 std::advance(SI, 1);
1031 for (; SI != SE; ++SI) {
1032 auto MI = SI->MappedExprComponents.find(VD);
1033 if (MI != SI->MappedExprComponents.end())
1035 MI->second.Components)
1036 if (Check(L, MI->second.Kind))
1044 bool checkMappableExprComponentListsForDeclAtLevel(
1046 const llvm::function_ref<
1050 if (getStackSize() <= Level)
1053 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054 auto MI = StackElem.MappedExprComponents.find(VD);
1055 if (MI != StackElem.MappedExprComponents.end())
1057 MI->second.Components)
1058 if (Check(L, MI->second.Kind))
1065 void addMappableExpressionComponents(
1069 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1071 MEC.Components.resize(MEC.Components.size() + 1);
1072 MEC.Components.back().append(Components.begin(), Components.end());
1073 MEC.Kind = WhereFoundClauseKind;
1076 unsigned getNestingLevel()
const {
1077 assert(!isStackEmpty());
1078 return getStackSize() - 1;
1080 void addDoacrossDependClause(
OMPClause *
C,
const OperatorOffsetTy &OpsOffs) {
1081 SharingMapTy *
Parent = getSecondOnStackOrNull();
1083 Parent->DoacrossDepends.try_emplace(
C, OpsOffs);
1085 llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1086 getDoacrossDependClauses()
const {
1087 const SharingMapTy &StackElem = getTopOfStack();
1089 const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090 return llvm::make_range(Ref.begin(), Ref.end());
1092 return llvm::make_range(StackElem.DoacrossDepends.end(),
1093 StackElem.DoacrossDepends.end());
1097 void addMappedClassesQualTypes(
QualType QT) {
1098 SharingMapTy &StackElem = getTopOfStack();
1099 StackElem.MappedClassesQualTypes.insert(QT);
1103 bool isClassPreviouslyMapped(
QualType QT)
const {
1104 const SharingMapTy &StackElem = getTopOfStack();
1105 return StackElem.MappedClassesQualTypes.contains(QT);
1109 void addToParentTargetRegionLinkGlobals(
DeclRefExpr *E) {
1110 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111 E->
getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112 "Expected declare target link global.");
1113 for (
auto &Elem : *
this) {
1115 Elem.DeclareTargetLinkVarDecls.push_back(E);
1125 "Expected target executable directive.");
1126 return getTopOfStack().DeclareTargetLinkVarDecls;
1130 void addInnerAllocatorExpr(
Expr *E) {
1131 getTopOfStack().InnerUsedAllocators.push_back(E);
1135 return getTopOfStack().InnerUsedAllocators;
1139 void addImplicitTaskFirstprivate(
unsigned Level,
Decl *D) {
1140 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1143 bool isImplicitTaskFirstprivate(
Decl *D)
const {
1144 return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1148 void addUsesAllocatorsDecl(
const Decl *D, UsesAllocatorsDeclKind Kind) {
1149 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1153 std::optional<UsesAllocatorsDeclKind>
1154 isUsesAllocatorsDecl(
unsigned Level,
const Decl *D)
const {
1155 const SharingMapTy &StackElem = getTopOfStack();
1156 auto I = StackElem.UsesAllocatorsDecls.find(D);
1157 if (I == StackElem.UsesAllocatorsDecls.end())
1158 return std::nullopt;
1159 return I->getSecond();
1161 std::optional<UsesAllocatorsDeclKind>
1162 isUsesAllocatorsDecl(
const Decl *D)
const {
1163 const SharingMapTy &StackElem = getTopOfStack();
1164 auto I = StackElem.UsesAllocatorsDecls.find(D);
1165 if (I == StackElem.UsesAllocatorsDecls.end())
1166 return std::nullopt;
1167 return I->getSecond();
1170 void addDeclareMapperVarRef(
Expr *Ref) {
1171 SharingMapTy &StackElem = getTopOfStack();
1172 StackElem.DeclareMapperVar = Ref;
1174 const Expr *getDeclareMapperVarRef()
const {
1175 const SharingMapTy *Top = getTopOfStackOrNull();
1176 return Top ? Top->DeclareMapperVar :
nullptr;
1180 void addIteratorVarDecl(
VarDecl *VD) {
1181 SharingMapTy &StackElem = getTopOfStack();
1185 bool isIteratorVarDecl(
const VarDecl *VD)
const {
1186 const SharingMapTy *Top = getTopOfStackOrNull();
1194 const_iterator I = begin();
1195 const_iterator EndI = end();
1196 size_t StackLevel = getStackSize();
1197 for (; I != EndI; ++I) {
1198 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1202 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1205 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206 if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1211 bool isImplicitDefaultFirstprivateFD(
VarDecl *VD)
const {
1212 const_iterator I = begin();
1213 const_iterator EndI = end();
1214 for (; I != EndI; ++I)
1215 if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1219 for (
const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1226 iterator I = begin();
1227 const_iterator EndI = end();
1228 size_t StackLevel = getStackSize();
1229 for (; I != EndI; ++I) {
1230 if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1231 I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1236 assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1246 DKind == OMPD_unknown;
1252 if (
const auto *FE = dyn_cast<FullExpr>(E))
1253 E = FE->getSubExpr();
1255 if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256 E = MTE->getSubExpr();
1258 while (
const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259 E = Binder->getSubExpr();
1261 if (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262 E = ICE->getSubExprAsWritten();
1271 if (
const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272 if (
const auto *ME = dyn_cast<MemberExpr>(
getExprAsWritten(CED->getInit())))
1273 D = ME->getMemberDecl();
1274 const auto *VD = dyn_cast<VarDecl>(D);
1275 const auto *FD = dyn_cast<FieldDecl>(D);
1276 if (VD !=
nullptr) {
1292DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &
Iter,
1295 auto *VD = dyn_cast<VarDecl>(D);
1296 const auto *FD = dyn_cast<FieldDecl>(D);
1298 if (
Iter == end()) {
1305 DVar.CKind = OMPC_shared;
1312 DVar.CKind = OMPC_shared;
1316 DVar.CKind = OMPC_shared;
1327 DVar.CKind = OMPC_private;
1331 DVar.DKind =
Iter->Directive;
1334 if (
Iter->SharingMap.count(D)) {
1335 const DSAInfo &
Data =
Iter->SharingMap.lookup(D);
1336 DVar.RefExpr =
Data.RefExpr.getPointer();
1337 DVar.PrivateCopy =
Data.PrivateCopy;
1338 DVar.CKind =
Data.Attributes;
1339 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1340 DVar.Modifier =
Data.Modifier;
1341 DVar.AppliedToPointee =
Data.AppliedToPointee;
1349 switch (
Iter->DefaultAttr) {
1351 DVar.CKind = OMPC_shared;
1352 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1356 case DSA_firstprivate:
1359 DVar.CKind = OMPC_unknown;
1361 DVar.CKind = OMPC_firstprivate;
1363 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1371 DVar.CKind = OMPC_unknown;
1373 DVar.CKind = OMPC_private;
1375 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1377 case DSA_unspecified:
1382 DVar.ImplicitDSALoc =
Iter->DefaultAttrLoc;
1386 DVar.CKind = OMPC_shared;
1396 DSAVarData DVarTemp;
1397 const_iterator I =
Iter, E = end();
1405 DVarTemp = getDSA(I, D);
1406 if (DVarTemp.CKind != OMPC_shared) {
1407 DVar.RefExpr =
nullptr;
1408 DVar.CKind = OMPC_firstprivate;
1411 }
while (I != E && !isImplicitTaskingRegion(I->Directive));
1413 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1422 return getDSA(++
Iter, D);
1426 const Expr *NewDE) {
1427 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1429 SharingMapTy &StackElem = getTopOfStack();
1430 auto It = StackElem.AlignedMap.find(D);
1431 if (It == StackElem.AlignedMap.end()) {
1432 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1433 StackElem.AlignedMap[D] = NewDE;
1436 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1440const Expr *DSAStackTy::addUniqueNontemporal(
const ValueDecl *D,
1441 const Expr *NewDE) {
1442 assert(!isStackEmpty() &&
"Data sharing attributes stack is empty");
1444 SharingMapTy &StackElem = getTopOfStack();
1445 auto It = StackElem.NontemporalMap.find(D);
1446 if (It == StackElem.NontemporalMap.end()) {
1447 assert(NewDE &&
"Unexpected nullptr expr to be added into aligned map");
1448 StackElem.NontemporalMap[D] = NewDE;
1451 assert(It->second &&
"Unexpected nullptr expr in the aligned map");
1456 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1458 SharingMapTy &StackElem = getTopOfStack();
1459 StackElem.LCVMap.try_emplace(
1460 D, LCDeclInfo(StackElem.LCVMap.size() + 1,
Capture));
1463const DSAStackTy::LCDeclInfo
1464DSAStackTy::isLoopControlVariable(
const ValueDecl *D)
const {
1465 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1467 const SharingMapTy &StackElem = getTopOfStack();
1468 auto It = StackElem.LCVMap.find(D);
1469 if (It != StackElem.LCVMap.end())
1471 return {0,
nullptr};
1474const DSAStackTy::LCDeclInfo
1475DSAStackTy::isLoopControlVariable(
const ValueDecl *D,
unsigned Level)
const {
1476 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1478 for (
unsigned I = Level + 1; I > 0; --I) {
1479 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480 auto It = StackElem.LCVMap.find(D);
1481 if (It != StackElem.LCVMap.end())
1484 return {0,
nullptr};
1487const DSAStackTy::LCDeclInfo
1488DSAStackTy::isParentLoopControlVariable(
const ValueDecl *D)
const {
1489 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1490 assert(
Parent &&
"Data-sharing attributes stack is empty");
1492 auto It =
Parent->LCVMap.find(D);
1493 if (It !=
Parent->LCVMap.end())
1495 return {0,
nullptr};
1498const ValueDecl *DSAStackTy::getParentLoopControlVariable(
unsigned I)
const {
1499 const SharingMapTy *
Parent = getSecondOnStackOrNull();
1500 assert(
Parent &&
"Data-sharing attributes stack is empty");
1501 if (
Parent->LCVMap.size() < I)
1503 for (
const auto &Pair :
Parent->LCVMap)
1504 if (Pair.second.first == I)
1511 bool AppliedToPointee) {
1513 if (A == OMPC_threadprivate) {
1514 DSAInfo &
Data = Threadprivates[D];
1515 Data.Attributes = A;
1516 Data.RefExpr.setPointer(E);
1517 Data.PrivateCopy =
nullptr;
1518 Data.Modifier = Modifier;
1520 DSAInfo &
Data = getTopOfStack().SharingMap[D];
1521 assert(
Data.Attributes == OMPC_unknown || (A ==
Data.Attributes) ||
1522 (A == OMPC_firstprivate &&
Data.Attributes == OMPC_lastprivate) ||
1523 (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) ||
1524 (isLoopControlVariable(D).first && A == OMPC_private));
1525 Data.Modifier = Modifier;
1526 if (A == OMPC_lastprivate &&
Data.Attributes == OMPC_firstprivate) {
1527 Data.RefExpr.setInt(
true);
1530 const bool IsLastprivate =
1531 A == OMPC_lastprivate ||
Data.Attributes == OMPC_lastprivate;
1532 Data.Attributes = A;
1533 Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534 Data.PrivateCopy = PrivateCopy;
1535 Data.AppliedToPointee = AppliedToPointee;
1537 DSAInfo &
Data = getTopOfStack().SharingMap[PrivateCopy->
getDecl()];
1538 Data.Modifier = Modifier;
1539 Data.Attributes = A;
1540 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541 Data.PrivateCopy =
nullptr;
1542 Data.AppliedToPointee = AppliedToPointee;
1549 StringRef Name,
const AttrVec *Attrs =
nullptr,
1564 OMPReferencedVarAttr::CreateImplicit(SemaRef.
Context, OrigRef));
1571 bool RefersToCapture =
false) {
1582 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1584 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585 "Additional reduction info may be specified only for reduction items.");
1586 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587 assert(ReductionData.ReductionRange.isInvalid() &&
1588 (getTopOfStack().
Directive == OMPD_taskgroup ||
1592 "Additional reduction info may be specified only once for reduction "
1594 ReductionData.set(BOK, SR);
1595 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596 if (!TaskgroupReductionRef) {
1599 TaskgroupReductionRef =
1605 const Expr *ReductionRef) {
1607 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty");
1609 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610 "Additional reduction info may be specified only for reduction items.");
1611 ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612 assert(ReductionData.ReductionRange.isInvalid() &&
1613 (getTopOfStack().
Directive == OMPD_taskgroup ||
1617 "Additional reduction info may be specified only once for reduction "
1619 ReductionData.set(ReductionRef, SR);
1620 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621 if (!TaskgroupReductionRef) {
1624 TaskgroupReductionRef =
1629const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1631 Expr *&TaskgroupDescriptor)
const {
1633 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1634 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1635 const DSAInfo &
Data = I->SharingMap.lookup(D);
1636 if (
Data.Attributes != OMPC_reduction ||
1637 Data.Modifier != OMPC_REDUCTION_task)
1639 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640 if (!ReductionData.ReductionOp ||
1641 ReductionData.ReductionOp.is<
const Expr *>())
1642 return DSAVarData();
1643 SR = ReductionData.ReductionRange;
1644 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1645 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1646 "expression for the descriptor is not "
1648 TaskgroupDescriptor = I->TaskgroupReductionRef;
1649 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1650 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1653 return DSAVarData();
1656const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1658 Expr *&TaskgroupDescriptor)
const {
1660 assert(!isStackEmpty() &&
"Data-sharing attributes stack is empty.");
1661 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1662 const DSAInfo &
Data = I->SharingMap.lookup(D);
1663 if (
Data.Attributes != OMPC_reduction ||
1664 Data.Modifier != OMPC_REDUCTION_task)
1666 const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667 if (!ReductionData.ReductionOp ||
1668 !ReductionData.ReductionOp.is<
const Expr *>())
1669 return DSAVarData();
1670 SR = ReductionData.ReductionRange;
1671 ReductionRef = ReductionData.ReductionOp.get<
const Expr *>();
1672 assert(I->TaskgroupReductionRef &&
"taskgroup reduction reference "
1673 "expression for the descriptor is not "
1675 TaskgroupDescriptor = I->TaskgroupReductionRef;
1676 return DSAVarData(I->Directive, OMPC_reduction,
Data.RefExpr.getPointer(),
1677 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1680 return DSAVarData();
1683bool DSAStackTy::isOpenMPLocal(
VarDecl *D, const_iterator I)
const {
1685 for (const_iterator E = end(); I != E; ++I) {
1686 if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1690 Scope *CurScope = getCurScope();
1691 while (CurScope && CurScope != TopScope && !CurScope->
isDeclScope(D))
1693 return CurScope != TopScope;
1696 if (I->Context == DC)
1705 bool AcceptIfMutable =
true,
1706 bool *IsClassType =
nullptr) {
1708 Type =
Type.getNonReferenceType().getCanonicalType();
1709 bool IsConstant =
Type.isConstant(Context);
1714 if (
const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1716 RD = CTD->getTemplatedDecl();
1719 return IsConstant && !(SemaRef.
getLangOpts().CPlusPlus && RD &&
1726 bool AcceptIfMutable =
true,
1727 bool ListItemNotVar =
false) {
1731 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1732 : IsClassType ? diag::err_omp_const_not_mutable_variable
1733 : diag::err_omp_const_variable;
1734 SemaRef.
Diag(ELoc,
Diag) << getOpenMPClauseName(CKind);
1735 if (!ListItemNotVar && D) {
1736 const VarDecl *VD = dyn_cast<VarDecl>(D);
1740 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1748const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(
ValueDecl *D,
1753 auto *VD = dyn_cast<VarDecl>(D);
1754 auto TI = Threadprivates.find(D);
1755 if (TI != Threadprivates.end()) {
1756 DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757 DVar.CKind = OMPC_threadprivate;
1758 DVar.Modifier = TI->getSecond().Modifier;
1761 if (VD && VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
1764 VD->
getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765 DVar.CKind = OMPC_threadprivate;
1766 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1773 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
1780 DVar.CKind = OMPC_threadprivate;
1781 addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1786 !isLoopControlVariable(D).first) {
1787 const_iterator IterTarget =
1788 std::find_if(begin(), end(), [](
const SharingMapTy &
Data) {
1791 if (IterTarget != end()) {
1792 const_iterator ParentIterTarget = IterTarget + 1;
1793 for (const_iterator
Iter = begin();
Iter != ParentIterTarget; ++
Iter) {
1794 if (isOpenMPLocal(VD,
Iter)) {
1798 DVar.CKind = OMPC_threadprivate;
1802 if (!isClauseParsingMode() || IterTarget != begin()) {
1803 auto DSAIter = IterTarget->SharingMap.find(D);
1804 if (DSAIter != IterTarget->SharingMap.end() &&
1806 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807 DVar.CKind = OMPC_threadprivate;
1810 const_iterator End = end();
1812 std::distance(ParentIterTarget, End),
1816 IterTarget->ConstructLoc);
1817 DVar.CKind = OMPC_threadprivate;
1837 const_iterator I = begin();
1838 const_iterator EndI = end();
1839 if (FromParent && I != EndI)
1842 auto It = I->SharingMap.find(D);
1843 if (It != I->SharingMap.end()) {
1844 const DSAInfo &
Data = It->getSecond();
1845 DVar.RefExpr =
Data.RefExpr.getPointer();
1846 DVar.PrivateCopy =
Data.PrivateCopy;
1847 DVar.CKind =
Data.Attributes;
1848 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849 DVar.DKind = I->Directive;
1850 DVar.Modifier =
Data.Modifier;
1851 DVar.AppliedToPointee =
Data.AppliedToPointee;
1856 DVar.CKind = OMPC_shared;
1863 if (SemaRef.
LangOpts.OpenMP <= 31) {
1871 DSAVarData DVarTemp = hasInnermostDSA(
1874 return C == OMPC_firstprivate ||
C == OMPC_shared;
1876 MatchesAlways, FromParent);
1877 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1880 DVar.CKind = OMPC_shared;
1887 const_iterator I = begin();
1888 const_iterator EndI = end();
1889 if (FromParent && I != EndI)
1893 auto It = I->SharingMap.find(D);
1894 if (It != I->SharingMap.end()) {
1895 const DSAInfo &
Data = It->getSecond();
1896 DVar.RefExpr =
Data.RefExpr.getPointer();
1897 DVar.PrivateCopy =
Data.PrivateCopy;
1898 DVar.CKind =
Data.Attributes;
1899 DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900 DVar.DKind = I->Directive;
1901 DVar.Modifier =
Data.Modifier;
1902 DVar.AppliedToPointee =
Data.AppliedToPointee;
1908const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1909 bool FromParent)
const {
1910 if (isStackEmpty()) {
1912 return getDSA(I, D);
1915 const_iterator StartI = begin();
1916 const_iterator EndI = end();
1917 if (FromParent && StartI != EndI)
1919 return getDSA(StartI, D);
1922const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(
ValueDecl *D,
1923 unsigned Level)
const {
1924 if (getStackSize() <= Level)
1925 return DSAVarData();
1927 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928 return getDSA(StartI, D);
1931const DSAStackTy::DSAVarData
1934 DefaultDataSharingAttributes)>
1937 bool FromParent)
const {
1941 const_iterator I = begin();
1942 const_iterator EndI = end();
1943 if (FromParent && I != EndI)
1945 for (; I != EndI; ++I) {
1946 if (!DPred(I->Directive) &&
1947 !isImplicitOrExplicitTaskingRegion(I->Directive))
1949 const_iterator NewI = I;
1950 DSAVarData DVar = getDSA(NewI, D);
1951 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1957const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1960 bool FromParent)
const {
1964 const_iterator StartI = begin();
1965 const_iterator EndI = end();
1966 if (FromParent && StartI != EndI)
1968 if (StartI == EndI || !DPred(StartI->Directive))
1970 const_iterator NewI = StartI;
1971 DSAVarData DVar = getDSA(NewI, D);
1972 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1977bool DSAStackTy::hasExplicitDSA(
1980 unsigned Level,
bool NotLastprivate)
const {
1981 if (getStackSize() <= Level)
1984 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985 auto I = StackElem.SharingMap.find(D);
1986 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1987 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1988 (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1991 auto LI = StackElem.LCVMap.find(D);
1992 if (LI != StackElem.LCVMap.end())
1993 return CPred(OMPC_private,
false);
1997bool DSAStackTy::hasExplicitDirective(
1999 unsigned Level)
const {
2000 if (getStackSize() <= Level)
2002 const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003 return DPred(StackElem.Directive);
2006bool DSAStackTy::hasDirective(
2010 bool FromParent)
const {
2012 size_t Skip = FromParent ? 2 : 1;
2013 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2015 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2021void Sema::InitDataSharingAttributesStack() {
2022 VarDataSharingAttributesStack =
new DSAStackTy(*
this);
2025#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2027void Sema::pushOpenMPFunctionRegion() {
DSAStack->pushFunction(); }
2035 "Expected OpenMP device compilation.");
2041enum class FunctionEmissionStatus {
2052 "Expected OpenMP device compilation.");
2078 llvm_unreachable(
"CUDADiscarded unexpected in OpenMP device compilation");
2090 "Expected OpenMP host compilation.");
2115 if (LO.OpenMP <= 45) {
2117 return OMPC_DEFAULTMAP_scalar;
2118 return OMPC_DEFAULTMAP_aggregate;
2121 return OMPC_DEFAULTMAP_pointer;
2123 return OMPC_DEFAULTMAP_scalar;
2124 return OMPC_DEFAULTMAP_aggregate;
2128 unsigned OpenMPCaptureLevel)
const {
2129 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2132 bool IsByRef =
true;
2138 bool IsVariableUsedInMapClause =
false;
2200 bool IsVariableAssociatedWithSection =
false;
2202 DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2204 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2211 if (WhereFoundClauseKind != OMPC_map &&
2212 WhereFoundClauseKind != OMPC_has_device_addr)
2215 auto EI = MapExprComponents.rbegin();
2216 auto EE = MapExprComponents.rend();
2218 assert(EI != EE &&
"Invalid map expression!");
2220 if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2226 auto Last = std::prev(EE);
2228 dyn_cast<UnaryOperator>(
Last->getAssociatedExpression());
2229 if ((UO && UO->getOpcode() == UO_Deref) ||
2230 isa<ArraySubscriptExpr>(
Last->getAssociatedExpression()) ||
2231 isa<OMPArraySectionExpr>(
Last->getAssociatedExpression()) ||
2232 isa<MemberExpr>(EI->getAssociatedExpression()) ||
2233 isa<OMPArrayShapingExpr>(
Last->getAssociatedExpression())) {
2234 IsVariableAssociatedWithSection =
true;
2243 if (IsVariableUsedInMapClause) {
2246 IsByRef = !(Ty->
isPointerType() && IsVariableAssociatedWithSection);
2251 IsByRef = (
DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2254 DSAStack->isDefaultmapCapturedByRef(
2259 return K == OMPC_reduction && !AppliedToPointee;
2267 ((IsVariableUsedInMapClause &&
2268 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2273 return K == OMPC_firstprivate ||
2274 (K == OMPC_reduction && AppliedToPointee);
2277 DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2280 !(isa<OMPCapturedExprDecl>(D) && !D->
hasAttr<OMPCaptureNoInitAttr>() &&
2281 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2284 !((
DSAStack->getDefaultDSA() == DSA_firstprivate ||
2285 DSAStack->getDefaultDSA() == DSA_private) &&
2289 !
DSAStack->isLoopControlVariable(D, Level).first);
2306unsigned Sema::getOpenMPNestingLevel()
const {
2308 return DSAStack->getNestingLevel();
2318 !
DSAStack->isClauseParsingMode()) ||
2329 if (!dyn_cast<FieldDecl>(D))
2331 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2334 DefaultDataSharingAttributes DefaultAttr) {
2336 (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2340 if (DVarPrivate.CKind != OMPC_unknown)
2346 Expr *CaptureExpr,
bool WithInit,
2352 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2355 auto *VD = dyn_cast<VarDecl>(D);
2364 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2373 DSAStackTy::DSAVarData DVarTop =
2375 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2380 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2386 if (!isa<CapturingScopeInfo>(FSI))
2388 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2394 assert(CSI &&
"Failed to find CapturedRegionScopeInfo");
2405 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2411 if (CheckScopeInfo) {
2412 bool OpenMPFound =
false;
2413 for (
unsigned I = StopAt + 1; I > 0; --I) {
2415 if (!isa<CapturingScopeInfo>(FSI))
2417 if (
auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2427 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2428 (!
DSAStack->isClauseParsingMode() ||
2429 DSAStack->getParentDirective() != OMPD_unknown)) {
2430 auto &&Info =
DSAStack->isLoopControlVariable(D);
2433 isImplicitOrExplicitTaskingRegion(
DSAStack->getCurrentDirective())) ||
2434 (VD &&
DSAStack->isForceVarCapturing()))
2435 return VD ? VD : Info.second;
2436 DSAStackTy::DSAVarData DVarTop =
2438 if (DVarTop.CKind != OMPC_unknown &&
isOpenMPPrivate(DVarTop.CKind) &&
2440 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2446 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2454 if (VD && !VD->
hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2455 ((
DSAStack->getDefaultDSA() != DSA_none &&
2456 DSAStack->getDefaultDSA() != DSA_private &&
2457 DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2458 DVarTop.CKind == OMPC_shared))
2460 auto *FD = dyn_cast<FieldDecl>(D);
2461 if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2462 !DVarPrivate.PrivateCopy) {
2463 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2466 DefaultDataSharingAttributes DefaultAttr) {
2468 (DefaultAttr == DSA_firstprivate ||
2469 DefaultAttr == DSA_private);
2473 if (DVarPrivate.CKind == OMPC_unknown)
2491 *
this, FD->
getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2495 VD = cast<VarDecl>(VDPrivateRefExpr->
getDecl());
2496 DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2499 if (DVarPrivate.CKind != OMPC_unknown ||
2500 (VD && (
DSAStack->getDefaultDSA() == DSA_none ||
2501 DSAStack->getDefaultDSA() == DSA_private ||
2502 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2503 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2508void Sema::adjustOpenMPTargetScopeIndex(
unsigned &FunctionScopesIndex,
2509 unsigned Level)
const {
2514 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2520 assert(
LangOpts.OpenMP &&
"OpenMP must be enabled.");
2522 DSAStack->resetPossibleLoopCounter();
2528 unsigned CapLevel)
const {
2529 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2530 if (
DSAStack->getCurrentDirective() != OMPD_unknown &&
2531 (!
DSAStack->isClauseParsingMode() ||
2532 DSAStack->getParentDirective() != OMPD_unknown)) {
2533 DSAStackTy::DSAVarData DVarPrivate =
DSAStack->hasDSA(
2536 DefaultDataSharingAttributes DefaultAttr) {
2538 DefaultAttr == DSA_private;
2542 if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2543 DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2544 !
DSAStack->isLoopControlVariable(D).first)
2545 return OMPC_private;
2548 bool IsTriviallyCopyable =
2558 (IsTriviallyCopyable ||
2564 return OMPC_firstprivate;
2565 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2566 if (DVar.CKind != OMPC_shared &&
2567 !
DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2568 DSAStack->addImplicitTaskFirstprivate(Level, D);
2569 return OMPC_firstprivate;
2576 DSAStack->resetPossibleLoopCounter(D);
2578 return OMPC_private;
2581 DSAStack->isLoopControlVariable(D).first) &&
2586 return OMPC_private;
2588 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2594 return OMPC_private;
2599 DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2600 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602 return OMPC_private;
2606 (
DSAStack->isClauseParsingMode() &&
2607 DSAStack->getClauseParsingMode() == OMPC_private) ||
2612 return K == OMPD_taskgroup ||
2613 ((isOpenMPParallelDirective(K) ||
2614 isOpenMPWorksharingDirective(K)) &&
2615 !isOpenMPSimdDirective(K));
2618 DSAStack->isTaskgroupReductionRef(D, Level)))
2625 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2628 for (
unsigned I =
DSAStack->getNestingLevel() + 1; I > Level; --I) {
2629 const unsigned NewLevel = I - 1;
2633 if (isOpenMPPrivate(K) && !AppliedToPointee) {
2641 if (
DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2651 if (
DSAStack->mustBeFirstprivateAtLevel(
2653 OMPC = OMPC_firstprivate;
2657 if (OMPC != OMPC_unknown)
2658 FD->
addAttr(OMPCaptureKindAttr::CreateImplicit(Context,
unsigned(OMPC)));
2662 unsigned CaptureLevel)
const {
2663 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2668 const auto *VD = dyn_cast<VarDecl>(D);
2672 Regions[CaptureLevel] != OMPD_task;
2676 unsigned CaptureLevel)
const {
2677 assert(
LangOpts.OpenMP &&
"OpenMP is not allowed");
2680 if (
const auto *VD = dyn_cast<VarDecl>(D)) {
2684 DSAStackTy::DSAVarData TopDVar =
2686 unsigned NumLevels =
2691 return (NumLevels == CaptureLevel + 1 &&
2692 (TopDVar.CKind != OMPC_shared ||
2693 DSAStack->getDefaultDSA() == DSA_firstprivate));
2696 DSAStackTy::DSAVarData DVar =
DSAStack->getImplicitDSA(D, Level);
2697 if (DVar.CKind != OMPC_shared)
2699 }
while (Level > 0);
2705void Sema::DestroyDataSharingAttributesStack() {
delete DSAStack; }
2709 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2714 "Not in OpenMP declare variant scope!");
2716 OMPDeclareVariantScopes.pop_back();
2722 assert(
LangOpts.OpenMP &&
"Expected OpenMP compilation mode.");
2723 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2726 if (
LangOpts.OpenMPIsTargetDevice &&
2727 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2730 if (!
LangOpts.OpenMPIsTargetDevice && DevTy &&
2731 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2734 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735 if (
LangOpts.OpenMPIsTargetDevice && DevTy &&
2736 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2738 StringRef HostDevTy =
2740 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742 diag::note_omp_marked_device_type_here)
2747 DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2751 for (OMPDeclareVariantAttr *A :
2752 Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753 auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754 auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755 std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756 OMPDeclareTargetDeclAttr::getDeviceType(
2757 VariantFD->getMostRecentDecl());
2758 if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2764 Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2768 OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771 diag::note_omp_marked_device_type_here)
2779 DSAStack->push(DKind, DirName, CurScope, Loc);
2789 DSAStack->setClauseParsingMode(OMPC_unknown);
2793static std::pair<ValueDecl *, bool>
2795 SourceRange &ERange,
bool AllowArraySection =
false,
2796 StringRef DiagType =
"");
2801 bool InscanFound =
false;
2808 if (
C->getClauseKind() != OMPC_reduction)
2810 auto *RC = cast<OMPReductionClause>(
C);
2811 if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2813 InscanLoc = RC->getModifierLoc();
2816 if (RC->getModifier() == OMPC_REDUCTION_task) {
2826 S.
Diag(RC->getModifierLoc(),
2827 diag::err_omp_reduction_task_not_parallel_or_worksharing);
2833 if (
C->getClauseKind() != OMPC_reduction)
2835 auto *RC = cast<OMPReductionClause>(
C);
2836 if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2839 : RC->getModifierLoc(),
2840 diag::err_omp_inscan_reduction_expected);
2841 S.
Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2844 for (
Expr *Ref : RC->varlists()) {
2845 assert(Ref &&
"NULL expr in OpenMP nontemporal clause.");
2848 Expr *SimpleRefExpr = Ref;
2855 S.
Diag(Ref->getExprLoc(),
2856 diag::err_omp_reduction_not_inclusive_exclusive)
2857 << Ref->getSourceRange();
2871 const DSAStackTy::DSAVarData &DVar,
2872 bool IsLoopIterVar =
false);
2880 if (
const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2882 if (
auto *Clause = dyn_cast<OMPLastprivateClause>(
C)) {
2884 for (
Expr *DE : Clause->varlists()) {
2885 if (DE->isValueDependent() || DE->isTypeDependent()) {
2886 PrivateCopies.push_back(
nullptr);
2889 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890 auto *VD = cast<VarDecl>(DRE->getDecl());
2892 const DSAStackTy::DSAVarData DVar =
2894 if (DVar.CKind == OMPC_lastprivate) {
2901 *
this, DE->getExprLoc(),
Type.getUnqualifiedType(),
2905 PrivateCopies.push_back(
nullptr);
2909 *
this, VDPrivate, DE->
getType(), DE->getExprLoc()));
2913 PrivateCopies.push_back(
nullptr);
2916 Clause->setPrivateCopies(PrivateCopies);
2920 if (
auto *Clause = dyn_cast<OMPNontemporalClause>(
C)) {
2922 for (
Expr *RefExpr : Clause->varlists()) {
2923 assert(RefExpr &&
"NULL expr in OpenMP nontemporal clause.");
2926 Expr *SimpleRefExpr = RefExpr;
2930 PrivateRefs.push_back(RefExpr);
2935 const DSAStackTy::DSAVarData DVar =
2937 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2940 Clause->setPrivateRefs(PrivateRefs);
2943 if (
auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
2944 for (
unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2950 if (!VD || !isa<VarDecl>(VD))
2952 DSAStackTy::DSAVarData DVar =
2958 Expr *MapExpr =
nullptr;
2960 DSAStack->checkMappableExprComponentListsForDecl(
2966 auto MI = MapExprComponents.rbegin();
2967 auto ME = MapExprComponents.rend();
2969 MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970 VD->getCanonicalDecl()) {
2971 MapExpr = MI->getAssociatedExpression();
2976 Diag(D.Allocator->getExprLoc(),
2977 diag::err_omp_allocator_used_in_clauses)
2982 Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983 << MapExpr->getSourceRange();
2996 DiscardCleanupsInEvaluationContext();
2997 PopExpressionEvaluationContext();
3001 Expr *NumIterations,
Sema &SemaRef,
3002 Scope *S, DSAStackTy *Stack);
3011 explicit VarDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3012 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3014 if (
const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3022 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3023 return std::make_unique<VarDeclFilterCCC>(*
this);
3032 explicit VarOrFuncDeclFilterCCC(
Sema &S) : SemaRef(S) {}
3033 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
3035 if (ND && ((isa<VarDecl>(ND) && ND->
getKind() == Decl::Var) ||
3036 isa<FunctionDecl>(ND))) {
3043 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
3044 return std::make_unique<VarOrFuncDeclFilterCCC>(*
this);
3062 VarDeclFilterCCC CCC(*
this);
3068 ? diag::err_undeclared_var_use_suggest
3069 : diag::err_omp_expected_var_arg_suggest)
3071 VD = Corrected.getCorrectionDeclAs<
VarDecl>();
3073 Diag(
Id.getLoc(), Lookup.
empty() ? diag::err_undeclared_var_use
3074 : diag::err_omp_expected_var_arg)
3079 Diag(
Id.getLoc(), diag::err_omp_expected_var_arg) <<
Id.getName();
3088 Diag(
Id.getLoc(), diag::err_omp_global_var_arg)
3093 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3105 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3106 << getOpenMPDirectiveName(Kind) << VD;
3110 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3120 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3121 << getOpenMPDirectiveName(Kind) << VD;
3125 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3136 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3137 << getOpenMPDirectiveName(Kind) << VD;
3141 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3150 Diag(
Id.getLoc(), diag::err_omp_var_scope)
3151 << getOpenMPDirectiveName(Kind) << VD;
3155 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3163 if (Kind == OMPD_threadprivate && VD->
isUsed() &&
3165 Diag(
Id.getLoc(), diag::err_omp_var_used)
3166 << getOpenMPDirectiveName(Kind) << VD;
3188class LocalVarRefChecker final
3194 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3197 diag::err_omp_local_var_in_threadprivate_init)
3199 SemaRef.Diag(VD->
getLocation(), diag::note_defined_here)
3206 bool VisitStmt(
const Stmt *S) {
3207 for (
const Stmt *Child : S->children()) {
3208 if (Child && Visit(Child))
3213 explicit LocalVarRefChecker(
Sema &SemaRef) : SemaRef(SemaRef) {}
3220 for (
Expr *RefExpr : VarList) {
3221 auto *DE = cast<DeclRefExpr>(RefExpr);
3222 auto *VD = cast<VarDecl>(DE->getDecl());
3239 diag::err_omp_threadprivate_incomplete_type)) {
3246 Diag(ILoc, diag::err_omp_ref_type_arg)
3247 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->
getType();
3251 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3259 !(VD->
hasAttr<OMPThreadPrivateDeclAttr>() &&
3264 Diag(ILoc, diag::err_omp_var_thread_local)
3269 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3277 LocalVarRefChecker Checker(*
this);
3278 if (Checker.Visit(Init))
3282 Vars.push_back(RefExpr);
3283 DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284 VD->
addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3287 ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3290 if (!Vars.empty()) {
3298static OMPAllocateDeclAttr::AllocatorTypeTy
3301 return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302 if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303 Allocator->isInstantiationDependent() ||
3304 Allocator->containsUnexpandedParameterPack())
3305 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307 llvm::FoldingSetNodeID AEId;
3308 const Expr *AE = Allocator->IgnoreParenImpCasts();
3310 for (
int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3311 auto AllocatorKind =
static_cast<OMPAllocateDeclAttr::AllocatorTypeTy
>(I);
3312 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313 llvm::FoldingSetNodeID DAEId;
3316 if (AEId == DAEId) {
3317 AllocatorKindRes = AllocatorKind;
3321 return AllocatorKindRes;
3326 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
Expr *Allocator) {
3327 if (!VD->
hasAttr<OMPAllocateDeclAttr>())
3329 const auto *A = VD->
getAttr<OMPAllocateDeclAttr>();
3330 Expr *PrevAllocator = A->getAllocator();
3331 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3333 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334 if (AllocatorsMatch &&
3335 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3336 Allocator && PrevAllocator) {
3337 const Expr *AE = Allocator->IgnoreParenImpCasts();
3339 llvm::FoldingSetNodeID AEId, PAEId;
3342 AllocatorsMatch = AEId == PAEId;
3344 if (!AllocatorsMatch) {
3346 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3350 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3352 PrevAllocator->printPretty(PrevAllocatorStream,
nullptr,
3356 Allocator ? Allocator->getExprLoc() : RefExpr->
getExprLoc();
3358 Allocator ? Allocator->getSourceRange() : RefExpr->
getSourceRange();
3360 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3362 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3363 S.
Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364 << (Allocator ? 1 : 0) << AllocatorStream.str()
3365 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3367 S.
Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368 << PrevAllocatorRange;
3376 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3378 if (VD->
hasAttr<OMPAllocateDeclAttr>())
3387 (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3388 Allocator->isInstantiationDependent() ||
3389 Allocator->containsUnexpandedParameterPack()))
3391 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.
Context, AllocatorKind,
3392 Allocator, Alignment, SR);
3395 ML->DeclarationMarkedOpenMPAllocate(VD, A);
3402 assert(Clauses.size() <= 2 &&
"Expected at most two clauses.");
3403 Expr *Alignment =
nullptr;
3404 Expr *Allocator =
nullptr;
3405 if (Clauses.empty()) {
3410 if (
LangOpts.OpenMPIsTargetDevice &&
3412 targetDiag(Loc, diag::err_expected_allocator_clause);
3415 if (
const auto *AC = dyn_cast<OMPAllocatorClause>(
C))
3416 Allocator = AC->getAllocator();
3417 else if (
const auto *AC = dyn_cast<OMPAlignClause>(
C))
3418 Alignment = AC->getAlignment();
3420 llvm_unreachable(
"Unexpected clause on allocate directive");
3422 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3425 for (
Expr *RefExpr : VarList) {
3426 auto *DE = cast<DeclRefExpr>(RefExpr);
3427 auto *VD = cast<VarDecl>(DE->getDecl());
3431 VD->
hasAttr<OMPThreadPrivateDeclAttr>() ||
3439 AllocatorKind, Allocator))
3447 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448 Diag(Allocator->getExprLoc(),
3449 diag::err_omp_expected_predefined_allocator)
3450 << Allocator->getSourceRange();
3454 IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3460 Vars.push_back(RefExpr);
3479 Diag(Loc, diag::err_omp_invalid_scope) <<
"requires";
3493 bool SkippedClauses) {
3494 if (!SkippedClauses && Assumptions.empty())
3495 Diag(Loc, diag::err_omp_no_clause_for_directive)
3496 << llvm::omp::getAllAssumeClauseOptions()
3497 << llvm::omp::getOpenMPDirectiveName(DKind);
3499 auto *AA = AssumptionAttr::Create(
Context, llvm::join(Assumptions,
","), Loc);
3500 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501 OMPAssumeScoped.push_back(AA);
3506 if (Assumptions.empty())
3509 assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510 "Unexpected omp assumption directive!");
3511 OMPAssumeGlobal.push_back(AA);
3519 while (Ctx->getLexicalParent())
3521 DeclContexts.push_back(Ctx);
3522 while (!DeclContexts.empty()) {
3524 for (
auto *SubDC : DC->
decls()) {
3525 if (SubDC->isInvalidDecl())
3527 if (
auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528 DeclContexts.push_back(CTD->getTemplatedDecl());
3529 llvm::append_range(DeclContexts, CTD->specializations());
3532 if (
auto *DC = dyn_cast<DeclContext>(SubDC))
3533 DeclContexts.push_back(DC);
3534 if (
auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3544 OMPAssumeScoped.pop_back();
3553 DSAStack->getEncounteredTargetLocs();
3555 if (!TargetLocations.empty() || !AtomicLoc.
isInvalid()) {
3556 for (
const OMPClause *CNew : ClauseList) {
3558 if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559 isa<OMPUnifiedAddressClause>(CNew) ||
3560 isa<OMPReverseOffloadClause>(CNew) ||
3561 isa<OMPDynamicAllocatorsClause>(CNew)) {
3562 Diag(Loc, diag::err_omp_directive_before_requires)
3563 <<
"target" << getOpenMPClauseName(CNew->getClauseKind());
3565 Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3569 isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3570 Diag(Loc, diag::err_omp_directive_before_requires)
3571 <<
"atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3578 if (!
DSAStack->hasDuplicateRequiresClause(ClauseList))
3586 const DSAStackTy::DSAVarData &DVar,
3587 bool IsLoopIterVar) {
3589 SemaRef.
Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590 << getOpenMPClauseName(DVar.CKind);
3594 PDSA_StaticMemberShared,
3595 PDSA_StaticLocalVarShared,
3596 PDSA_LoopIterVarPrivate,
3597 PDSA_LoopIterVarLinear,
3598 PDSA_LoopIterVarLastprivate,
3599 PDSA_ConstVarShared,
3600 PDSA_GlobalVarShared,
3601 PDSA_TaskVarFirstprivate,
3602 PDSA_LocalVarPrivate,
3604 } Reason = PDSA_Implicit;
3605 bool ReportHint =
false;
3607 auto *VD = dyn_cast<VarDecl>(D);
3608 if (IsLoopIterVar) {
3609 if (DVar.CKind == OMPC_private)
3610 Reason = PDSA_LoopIterVarPrivate;
3611 else if (DVar.CKind == OMPC_lastprivate)
3612 Reason = PDSA_LoopIterVarLastprivate;
3614 Reason = PDSA_LoopIterVarLinear;
3616 DVar.CKind == OMPC_firstprivate) {
3617 Reason = PDSA_TaskVarFirstprivate;
3618 ReportLoc = DVar.ImplicitDSALoc;
3620 Reason = PDSA_StaticLocalVarShared;
3622 Reason = PDSA_StaticMemberShared;
3624 Reason = PDSA_GlobalVarShared;
3626 Reason = PDSA_ConstVarShared;
3627 else if (VD && VD->
isLocalVarDecl() && DVar.CKind == OMPC_private) {
3629 Reason = PDSA_LocalVarPrivate;
3631 if (Reason != PDSA_Implicit) {
3632 SemaRef.
Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633 << Reason << ReportHint
3634 << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635 }
else if (DVar.ImplicitDSALoc.isValid()) {
3636 SemaRef.
Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637 << getOpenMPClauseName(DVar.CKind);
3643 bool IsAggregateOrDeclareTarget) {
3646 case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647 Kind = OMPC_MAP_alloc;
3649 case OMPC_DEFAULTMAP_MODIFIER_to:
3652 case OMPC_DEFAULTMAP_MODIFIER_from:
3653 Kind = OMPC_MAP_from;
3655 case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656 Kind = OMPC_MAP_tofrom;
3658 case OMPC_DEFAULTMAP_MODIFIER_present:
3664 Kind = OMPC_MAP_alloc;
3666 case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3668 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3669 case OMPC_DEFAULTMAP_MODIFIER_none:
3670 case OMPC_DEFAULTMAP_MODIFIER_default:
3675 if (IsAggregateOrDeclareTarget) {
3676 Kind = OMPC_MAP_tofrom;
3679 llvm_unreachable(
"Unexpected defaultmap implicit behavior");
3686class DSAAttrChecker final :
public StmtVisitor<DSAAttrChecker, void> {
3689 bool ErrorFound =
false;
3690 bool TryCaptureCXXThisMembers =
false;
3692 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3697 ImplicitMapModifier[DefaultmapKindNum];
3699 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3703 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3705 if (S->getDirectiveKind() == OMPD_atomic ||
3706 S->getDirectiveKind() == OMPD_critical ||
3707 S->getDirectiveKind() == OMPD_section ||
3708 S->getDirectiveKind() == OMPD_master ||
3709 S->getDirectiveKind() == OMPD_masked ||
3710 S->getDirectiveKind() == OMPD_scope ||
3712 Visit(S->getAssociatedStmt());
3715 visitSubCaptures(S->getInnermostCapturedStmt());
3718 if (TryCaptureCXXThisMembers ||
3720 llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3722 return C.capturesThis();
3724 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725 TryCaptureCXXThisMembers =
true;
3726 Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3734 if (
auto *FC = dyn_cast<OMPFirstprivateClause>(
C)) {
3735 for (
Expr *Ref : FC->varlists())
3747 if (
auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
3750 !Stack->getTopDSA(VD,
false).RefExpr &&
3751 !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3752 if (
auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754 Visit(CED->getInit());
3757 }
else if (VD->
isImplicit() || isa<OMPCapturedExprDecl>(VD))
3760 if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3765 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3766 !Stack->isImplicitTaskFirstprivate(VD))
3769 if (Stack->isUsesAllocatorsDecl(VD))
3772 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD,
false);
3774 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3778 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3782 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3783 !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3784 !Stack->isImplicitTaskFirstprivate(VD))
3793 if (DVar.CKind == OMPC_unknown &&
3794 (Stack->getDefaultDSA() == DSA_none ||
3795 Stack->getDefaultDSA() == DSA_private ||
3796 Stack->getDefaultDSA() == DSA_firstprivate) &&
3797 isImplicitOrExplicitTaskingRegion(DKind) &&
3798 VarsWithInheritedDSA.count(VD) == 0) {
3799 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3801 Stack->getDefaultDSA() == DSA_private)) {
3802 DSAStackTy::DSAVarData DVar =
3803 Stack->getImplicitDSA(VD,
false);
3804 InheritedDSA = DVar.CKind == OMPC_unknown;
3807 VarsWithInheritedDSA[VD] = E;
3808 if (Stack->getDefaultDSA() == DSA_none)
3823 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824 OMPC_DEFAULTMAP_MODIFIER_none;
3825 if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3826 VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3830 if (!Stack->checkMappableExprComponentListsForDecl(
3835 auto MI = MapExprComponents.rbegin();
3836 auto ME = MapExprComponents.rend();
3837 return MI != ME && MI->getAssociatedDeclaration() == VD;
3839 VarsWithInheritedDSA[VD] = E;
3845 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846 OMPC_DEFAULTMAP_MODIFIER_present;
3847 if (IsModifierPresent) {
3848 if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849 OMPC_MAP_MODIFIER_present)) {
3850 ImplicitMapModifier[ClauseKind].push_back(
3851 OMPC_MAP_MODIFIER_present);
3857 !Stack->isLoopControlVariable(VD).first) {
3858 if (!Stack->checkMappableExprComponentListsForDecl(
3863 if (SemaRef.LangOpts.OpenMP >= 50)
3864 return !StackComponents.empty();
3867 return StackComponents.size() == 1 ||
3869 llvm::drop_begin(llvm::reverse(StackComponents)),
3870 [](const OMPClauseMappableExprCommon::
3871 MappableComponent &MC) {
3872 return MC.getAssociatedDeclaration() ==
3874 (isa<OMPArraySectionExpr>(
3875 MC.getAssociatedExpression()) ||
3876 isa<OMPArrayShapingExpr>(
3877 MC.getAssociatedExpression()) ||
3878 isa<ArraySubscriptExpr>(
3879 MC.getAssociatedExpression()));
3882 bool IsFirstprivate =
false;
3884 if (
const auto *RD =
3886 IsFirstprivate = RD->isLambda();
3888 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3889 if (IsFirstprivate) {
3890 ImplicitFirstprivate.emplace_back(E);
3893 Stack->getDefaultmapModifier(ClauseKind);
3895 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3896 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
3906 DVar = Stack->hasInnermostDSA(
3909 return C == OMPC_reduction && !AppliedToPointee;
3918 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
3924 DVar = Stack->getImplicitDSA(VD,
false);
3926 (((Stack->getDefaultDSA() == DSA_firstprivate &&
3927 DVar.CKind == OMPC_firstprivate) ||
3928 (Stack->getDefaultDSA() == DSA_private &&
3929 DVar.CKind == OMPC_private)) &&
3931 !Stack->isLoopControlVariable(VD).first) {
3932 if (Stack->getDefaultDSA() == DSA_private)
3933 ImplicitPrivate.push_back(E);
3935 ImplicitFirstprivate.push_back(E);
3942 *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3943 Stack->addToParentTargetRegionLinkGlobals(E);
3957 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD,
false);
3960 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3964 !Stack->isLoopControlVariable(FD).first &&
3965 !Stack->checkMappableExprComponentListsForDecl(
3970 return isa<CXXThisExpr>(
3972 StackComponents.back().getAssociatedExpression())
3984 if (Stack->isClassPreviouslyMapped(TE->getType()))
3988 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3993 ImplicitMap[ClauseKind][
Kind].emplace_back(E);
4002 DVar = Stack->hasInnermostDSA(
4005 return C == OMPC_reduction && !AppliedToPointee;
4014 SemaRef.
Diag(ELoc, diag::err_omp_reduction_in_task);
4020 DVar = Stack->getImplicitDSA(FD,
false);
4022 !Stack->isLoopControlVariable(FD).first) {
4027 if (DVar.CKind != OMPC_unknown)
4028 ImplicitFirstprivate.push_back(E);
4035 Stack->getCurrentDirective(),
4038 const auto *VD = cast<ValueDecl>(
4039 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040 if (!Stack->checkMappableExprComponentListsForDecl(
4046 auto CCI = CurComponents.rbegin();
4047 auto CCE = CurComponents.rend();
4048 for (const auto &SC : llvm::reverse(StackComponents)) {
4050 if (CCI->getAssociatedExpression()->getStmtClass() !=
4051 SC.getAssociatedExpression()->getStmtClass())
4052 if (!((isa<OMPArraySectionExpr>(
4053 SC.getAssociatedExpression()) ||
4054 isa<OMPArrayShapingExpr>(
4055 SC.getAssociatedExpression())) &&
4056 isa<ArraySubscriptExpr>(
4057 CCI->getAssociatedExpression())))
4060 const Decl *CCD = CCI->getAssociatedDeclaration();
4061 const Decl *SCD = SC.getAssociatedDeclaration();
4062 CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4063 SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4066 std::advance(CCI, 1);
4074 }
else if (!TryCaptureCXXThisMembers) {
4082 if (isa_and_nonnull<OMPPrivateClause>(
C))
4088 if (
C && !((isa<OMPFirstprivateClause>(
C) || isa<OMPMapClause>(
C)) &&
4091 for (
Stmt *CC :
C->children()) {
4098 VisitSubCaptures(S);
4107 for (
Stmt *
C : S->arguments()) {
4114 if (
Expr *Callee = S->getCallee()) {
4115 auto *CI =
Callee->IgnoreParenImpCasts();
4116 if (
auto *CE = dyn_cast<MemberExpr>(CI))
4117 Visit(CE->getBase());
4118 else if (
auto *CE = dyn_cast<DeclRefExpr>(CI))
4122 void VisitStmt(
Stmt *S) {
4123 for (
Stmt *
C : S->children()) {
4134 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4136 VarDecl *VD = Cap.getCapturedVar();
4140 Stack->checkMappableExprComponentListsForDecl(
4147 Cap.getLocation(),
true);
4151 bool isErrorFound()
const {
return ErrorFound; }
4153 return ImplicitFirstprivate;
4158 return ImplicitMap[DK][MK];
4162 return ImplicitMapModifier[
Kind];
4165 return VarsWithInheritedDSA;
4169 : Stack(S), SemaRef(SemaRef), ErrorFound(
false), CS(CS) {
4184 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4186 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4188 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4190 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4192 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193 Stack->handleConstructTrait(Traits, ScopeEntry);
4199 case OMPD_parallel_for:
4200 case OMPD_parallel_for_simd:
4201 case OMPD_parallel_sections:
4202 case OMPD_parallel_master:
4203 case OMPD_parallel_masked:
4204 case OMPD_parallel_loop:
4206 case OMPD_teams_distribute:
4207 case OMPD_teams_distribute_simd: {
4212 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4213 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4214 std::make_pair(StringRef(),
QualType())
4220 case OMPD_target_teams:
4221 case OMPD_target_parallel:
4222 case OMPD_target_parallel_for:
4223 case OMPD_target_parallel_for_simd:
4224 case OMPD_target_parallel_loop:
4225 case OMPD_target_teams_distribute:
4226 case OMPD_target_teams_distribute_simd: {
4236 std::make_pair(
".global_tid.", KmpInt32Ty),
4237 std::make_pair(
".part_id.", KmpInt32PtrTy),
4238 std::make_pair(
".privates.", VoidPtrTy),
4243 std::make_pair(StringRef(),
QualType())
4250 AlwaysInlineAttr::CreateImplicit(
4251 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4253 std::make_pair(StringRef(),
QualType())
4259 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4260 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4261 std::make_pair(StringRef(),
QualType())
4266 ParamsTeamsOrParallel, 2);
4270 case OMPD_target_simd: {
4280 std::make_pair(
".global_tid.", KmpInt32Ty),
4281 std::make_pair(
".part_id.", KmpInt32PtrTy),
4282 std::make_pair(
".privates.", VoidPtrTy),
4287 std::make_pair(StringRef(),
QualType())
4294 AlwaysInlineAttr::CreateImplicit(
4295 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4297 std::make_pair(StringRef(),
QualType()),
4317 case OMPD_taskgroup:
4318 case OMPD_distribute:
4319 case OMPD_distribute_simd:
4322 case OMPD_target_data:
4323 case OMPD_dispatch: {
4325 std::make_pair(StringRef(),
QualType())
4341 std::make_pair(
".global_tid.", KmpInt32Ty),
4342 std::make_pair(
".part_id.", KmpInt32PtrTy),
4343 std::make_pair(
".privates.", VoidPtrTy),
4348 std::make_pair(StringRef(),
QualType())
4355 AlwaysInlineAttr::CreateImplicit(
4356 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4360 case OMPD_taskloop_simd:
4361 case OMPD_master_taskloop:
4362 case OMPD_masked_taskloop:
4363 case OMPD_masked_taskloop_simd:
4364 case OMPD_master_taskloop_simd: {
4382 std::make_pair(
".global_tid.", KmpInt32Ty),
4383 std::make_pair(
".part_id.", KmpInt32PtrTy),
4384 std::make_pair(
".privates.", VoidPtrTy),
4389 std::make_pair(
".lb.", KmpUInt64Ty),
4390 std::make_pair(
".ub.", KmpUInt64Ty),
4391 std::make_pair(
".st.", KmpInt64Ty),
4392 std::make_pair(
".liter.", KmpInt32Ty),
4393 std::make_pair(
".reductions.", VoidPtrTy),
4394 std::make_pair(StringRef(),
QualType())
4401 AlwaysInlineAttr::CreateImplicit(
4402 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4405 case OMPD_parallel_masked_taskloop:
4406 case OMPD_parallel_masked_taskloop_simd:
4407 case OMPD_parallel_master_taskloop:
4408 case OMPD_parallel_master_taskloop_simd: {
4422 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4423 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4424 std::make_pair(StringRef(),
QualType())
4434 std::make_pair(
".global_tid.", KmpInt32Ty),
4435 std::make_pair(
".part_id.", KmpInt32PtrTy),
4436 std::make_pair(
".privates.", VoidPtrTy),
4441 std::make_pair(
".lb.", KmpUInt64Ty),
4442 std::make_pair(
".ub.", KmpUInt64Ty),
4443 std::make_pair(
".st.", KmpInt64Ty),
4444 std::make_pair(
".liter.", KmpInt32Ty),
4445 std::make_pair(
".reductions.", VoidPtrTy),
4446 std::make_pair(StringRef(),
QualType())
4453 AlwaysInlineAttr::CreateImplicit(
4454 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4457 case OMPD_distribute_parallel_for_simd:
4458 case OMPD_distribute_parallel_for: {
4463 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4464 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4467 std::make_pair(StringRef(),
QualType())
4473 case OMPD_target_teams_loop:
4474 case OMPD_target_teams_distribute_parallel_for:
4475 case OMPD_target_teams_distribute_parallel_for_simd: {
4486 std::make_pair(
".global_tid.", KmpInt32Ty),
4487 std::make_pair(
".part_id.", KmpInt32PtrTy),
4488 std::make_pair(
".privates.", VoidPtrTy),
4493 std::make_pair(StringRef(),
QualType())
4500 AlwaysInlineAttr::CreateImplicit(
4501 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4503 std::make_pair(StringRef(),
QualType())
4510 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4511 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4512 std::make_pair(StringRef(),
QualType())
4519 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4520 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4523 std::make_pair(StringRef(),
QualType())
4532 case OMPD_teams_loop:
4533 case OMPD_teams_distribute_parallel_for:
4534 case OMPD_teams_distribute_parallel_for_simd: {
4540 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4541 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4542 std::make_pair(StringRef(),
QualType())
4549 std::make_pair(
".global_tid.", KmpInt32PtrTy),
4550 std::make_pair(
".bound_tid.", KmpInt32PtrTy),
4553 std::make_pair(StringRef(),
QualType())
4561 case OMPD_target_update:
4562 case OMPD_target_enter_data:
4563 case OMPD_target_exit_data: {
4573 std::make_pair(
".global_tid.", KmpInt32Ty),
4574 std::make_pair(
".part_id.", KmpInt32PtrTy),
4575 std::make_pair(
".privates.", VoidPtrTy),
4580 std::make_pair(StringRef(),
QualType())
4587 AlwaysInlineAttr::CreateImplicit(
4588 Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4591 case OMPD_threadprivate:
4593 case OMPD_taskyield:
4597 case OMPD_cancellation_point:
4602 case OMPD_declare_reduction:
4603 case OMPD_declare_mapper:
4604 case OMPD_declare_simd:
4605 case OMPD_declare_target:
4606 case OMPD_end_declare_target:
4608 case OMPD_declare_variant:
4609 case OMPD_begin_declare_variant:
4610 case OMPD_end_declare_variant:
4611 case OMPD_metadirective:
4612 llvm_unreachable(
"OpenMP Directive is not allowed");
4615 llvm_unreachable(
"Unknown OpenMP directive");
4621int Sema::getNumberOfConstructScopes(
unsigned Level)
const {
4628 return CaptureRegions.size();
4632 Expr *CaptureExpr,
bool WithInit,
4634 bool AsExpression) {
4635 assert(CaptureExpr);
4641 Ty =
C.getLValueReferenceType(Ty);
4643 Ty =
C.getPointerType(Ty);
4655 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(
C));
4666 CD = cast<OMPCapturedExprDecl>(VD);
4705class CaptureRegionUnwinderRAII {
4712 CaptureRegionUnwinderRAII(
Sema &S,
bool &ErrorFound,
4714 : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4715 ~CaptureRegionUnwinderRAII() {
4718 while (--ThisCaptureLevel >= 0)
4731 DSAStack->getCurrentDirective()))) {
4733 if (
const auto *RD =
Type.getCanonicalType()
4734 .getNonReferenceType()
4736 bool SavedForceCaptureByReferenceInTargetExecutable =
4737 DSAStack->isForceCaptureByReferenceInTargetExecutable();
4738 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4740 if (RD->isLambda()) {
4741 llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4743 RD->getCaptureFields(Captures, ThisCapture);
4746 VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4751 }
else if (LC.getCaptureKind() ==
LCK_This) {
4759 DSAStack->setForceCaptureByReferenceInTargetExecutable(
4760 SavedForceCaptureByReferenceInTargetExecutable);
4770 for (
const OMPClause *Clause : Clauses) {
4772 Ordered = cast<OMPOrderedClause>(Clause);
4774 Order = cast<OMPOrderClause>(Clause);
4775 if (Order->
getKind() != OMPC_ORDER_concurrent)
4778 if (Ordered && Order)
4782 if (Ordered && Order) {
4784 diag::err_omp_simple_clause_incompatible_with_ordered)
4785 << getOpenMPClauseName(OMPC_order)
4799 if (
DSAStack->getCurrentDirective() == OMPD_atomic ||
4800 DSAStack->getCurrentDirective() == OMPD_critical ||
4801 DSAStack->getCurrentDirective() == OMPD_section ||
4802 DSAStack->getCurrentDirective() == OMPD_master ||
4803 DSAStack->getCurrentDirective() == OMPD_masked)
4806 bool ErrorFound =
false;
4807 CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4808 *
this, ErrorFound,
DSAStack->getCurrentDirective());
4809 if (!S.isUsable()) {
4824 DSAStack->getCurrentDirective() == OMPD_target) &&
4828 auto *IRC = cast<OMPInReductionClause>(Clause);
4829 for (
Expr *E : IRC->taskgroup_descriptors())
4841 if (
auto *E = cast_or_null<Expr>(VarRef)) {
4845 DSAStack->setForceVarCapturing(
false);
4847 DSAStack->getCurrentDirective())) {
4848 assert(CaptureRegions.empty() &&
4849 "No captured regions in loop transformation directives.");
4850 }
else if (CaptureRegions.size() > 1 ||
4851 CaptureRegions.back() != OMPD_unknown) {
4855 if (
Expr *E =
C->getPostUpdateExpr())
4860 SC = cast<OMPScheduleClause>(Clause);
4862 OC = cast<OMPOrderedClause>(Clause);
4864 LCs.push_back(cast<OMPLinearClause>(Clause));
4875 OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4880 diag::err_omp_simple_clause_incompatible_with_ordered)
4881 << getOpenMPClauseName(OMPC_schedule)
4883 OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4894 Diag(
C->getBeginLoc(), diag::err_omp_linear_ordered)
4903 << getOpenMPDirectiveName(
DSAStack->getCurrentDirective());
4910 unsigned CompletedRegions = 0;
4915 if (ThisCaptureRegion != OMPD_unknown) {
4923 if (CaptureRegion == ThisCaptureRegion ||
4924 CaptureRegion == OMPD_unknown) {
4925 if (
auto *DS = cast_or_null<DeclStmt>(
C->getPreInitStmt())) {
4926 for (
Decl *D : DS->decls())
4932 if (ThisCaptureRegion == OMPD_target) {
4936 if (
const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(
C)) {
4937 for (
unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4947 if (ThisCaptureRegion == OMPD_parallel) {
4951 if (
auto *RC = dyn_cast<OMPReductionClause>(
C)) {
4952 if (RC->getModifier() != OMPC_REDUCTION_inscan)
4954 for (
Expr *E : RC->copy_array_temps())
4957 if (
auto *AC = dyn_cast<OMPAlignedClause>(
C)) {
4958 for (
Expr *E : AC->varlists())
4963 if (++CompletedRegions == CaptureRegions.size())
4974 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4977 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4978 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4981 SemaRef.
Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4982 << getOpenMPDirectiveName(CancelRegion);
4992 if (Stack->getCurScope()) {
4995 bool NestingProhibited =
false;
4996 bool CloseNesting =
true;
4997 bool OrphanSeen =
false;
5000 ShouldBeInParallelRegion,
5001 ShouldBeInOrderedRegion,
5002 ShouldBeInTargetRegion,
5003 ShouldBeInTeamsRegion,
5004 ShouldBeInLoopSimdRegion,
5005 } Recommend = NoRecommend;
5006 if (SemaRef.
LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5007 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5008 CurrentRegion != OMPD_parallel &&
5010 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_order)
5011 << getOpenMPDirectiveName(CurrentRegion);
5015 ((SemaRef.
LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5016 (SemaRef.
LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5017 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5018 CurrentRegion != OMPD_scan))) {
5031 SemaRef.
Diag(StartLoc, (CurrentRegion != OMPD_simd)
5032 ? diag::err_omp_prohibited_region_simd
5033 : diag::warn_omp_nesting_simd)
5034 << (SemaRef.
LangOpts.OpenMP >= 50 ? 1 : 0);
5035 return CurrentRegion != OMPD_simd;
5037 if (ParentRegion == OMPD_atomic) {
5040 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5043 if (CurrentRegion == OMPD_section) {
5048 if (ParentRegion != OMPD_sections &&
5049 ParentRegion != OMPD_parallel_sections) {
5050 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5051 << (ParentRegion != OMPD_unknown)
5052 << getOpenMPDirectiveName(ParentRegion);
5060 if (ParentRegion == OMPD_unknown &&
5062 CurrentRegion != OMPD_cancellation_point &&
5063 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5065 if (CurrentRegion == OMPD_cancellation_point ||
5066 CurrentRegion == OMPD_cancel) {
5079 !((CancelRegion == OMPD_parallel &&
5080 (ParentRegion == OMPD_parallel ||
5081 ParentRegion == OMPD_target_parallel)) ||
5082 (CancelRegion == OMPD_for &&
5083 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5084 ParentRegion == OMPD_target_parallel_for ||
5085 ParentRegion == OMPD_distribute_parallel_for ||
5086 ParentRegion == OMPD_teams_distribute_parallel_for ||
5087 ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5088 (CancelRegion == OMPD_taskgroup &&
5089 (ParentRegion == OMPD_task ||
5091 (ParentRegion == OMPD_taskloop ||
5092 ParentRegion == OMPD_master_taskloop ||
5093 ParentRegion == OMPD_masked_taskloop ||
5094 ParentRegion == OMPD_parallel_masked_taskloop ||
5095 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5096 (CancelRegion == OMPD_sections &&
5097 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5098 ParentRegion == OMPD_parallel_sections)));
5099 OrphanSeen = ParentRegion == OMPD_unknown;
5100 }
else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5107 }
else if (CurrentRegion == OMPD_critical && CurrentName.
getName()) {
5113 bool DeadLock = Stack->hasDirective(
5117 if (K == OMPD_critical && DNI.
getName() == CurrentName.
getName()) {
5118 PreviousCriticalLoc = Loc;
5125 SemaRef.
Diag(StartLoc,
5126 diag::err_omp_prohibited_region_critical_same_name)
5128 if (PreviousCriticalLoc.
isValid())
5129 SemaRef.
Diag(PreviousCriticalLoc,
5130 diag::note_omp_previous_critical_region);
5133 }
else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5144 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5145 ParentRegion == OMPD_parallel_master ||
5146 ParentRegion == OMPD_parallel_masked ||
5147 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5159 ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5160 ParentRegion == OMPD_parallel_master ||
5161 ParentRegion == OMPD_parallel_masked ||
5162 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5163 Recommend = ShouldBeInParallelRegion;
5164 }
else if (CurrentRegion == OMPD_ordered) {
5173 NestingProhibited = ParentRegion == OMPD_critical ||
5176 Stack->isParentOrderedRegion());
5177 Recommend = ShouldBeInOrderedRegion;
5183 (SemaRef.
LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5184 (SemaRef.
LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5185 ParentRegion != OMPD_target);
5186 OrphanSeen = ParentRegion == OMPD_unknown;
5187 Recommend = ShouldBeInTargetRegion;
5188 }
else if (CurrentRegion == OMPD_scan) {
5194 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5195 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5196 ParentRegion != OMPD_parallel_for_simd);
5197 OrphanSeen = ParentRegion == OMPD_unknown;
5198 Recommend = ShouldBeInLoopSimdRegion;
5200 if (!NestingProhibited &&
5203 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5215 CurrentRegion != OMPD_loop &&
5217 CurrentRegion == OMPD_atomic);
5218 Recommend = ShouldBeInParallelRegion;
5220 if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5225 NestingProhibited = BindKind == OMPC_BIND_teams &&
5226 ParentRegion != OMPD_teams &&
5227 ParentRegion != OMPD_target_teams;
5228 Recommend = ShouldBeInTeamsRegion;
5230 if (!NestingProhibited &&
5236 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5237 Recommend = ShouldBeInTeamsRegion;
5239 if (!NestingProhibited &&
5246 NestingProhibited = Stack->hasDirective(
5250 OffendingRegion = K;
5256 CloseNesting =
false;
5258 if (NestingProhibited) {
5260 SemaRef.
Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5261 << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5263 SemaRef.
Diag(StartLoc, diag::err_omp_prohibited_region)
5264 << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5265 << Recommend << getOpenMPDirectiveName(CurrentRegion);